Java 将PCM原始字节转换为WAV字节

Java 将PCM原始字节转换为WAV字节,java,html5-audio,wav,pcm,transcoding,Java,Html5 Audio,Wav,Pcm,Transcoding,我正在收听现场电话,能够获取原始PCM字节。 我还能够通过java的音频api收听这些字节。 这些都可以在applet上运行 现在,我希望能够将电话呼叫的原始PCM字节转换为WAV字节,以便直接将其写入ServletOutputStream。这将允许浏览器实际监听电话 有人知道我如何能够将一些原始PCM字节[]转换为WAV字节[]吗 我所看到的示例都与将一个文件转换为另一个文件有关 谢谢。我也陷入了同样的境地,以下是我如何解决问题的 public static boolean getWavF

我正在收听现场电话,能够获取原始PCM字节。 我还能够通过java的音频api收听这些字节。 这些都可以在applet上运行

现在,我希望能够将电话呼叫的原始PCM字节转换为WAV字节,以便直接将其写入ServletOutputStream。这将允许浏览器实际监听电话

有人知道我如何能够将一些原始PCM字节[]转换为WAV字节[]吗

我所看到的示例都与将一个文件转换为另一个文件有关


谢谢。

我也陷入了同样的境地,以下是我如何解决问题的

public static boolean getWavFile(String filePath, InputStream audioStream) throws IOException {

    boolean result = false;
    try {

        byte[] decodedData = IOUtils.toByteArray(audioStream);

        System.out.println(">>Decoded Data" + Arrays.toString(decodedData));
        File outFile = new File(filePath);
        AudioFormat format = new AudioFormat(8000, 16, 1, true, false);
        AudioSystem.write(new AudioInputStream(new ByteArrayInputStream(
                decodedData), format, decodedData.length), AudioFileFormat.Type.WAVE, outFile);
        result = true;
        return result;
    } catch (IOException ex) {
        System.out.println("<<getWavFile - impl" + ex);
        return result;

    }
}
public静态布尔getWavFile(字符串文件路径,InputStream音频流)引发IOException{
布尔结果=假;
试一试{
字节[]decodedData=IOUtils.toByteArray(音频流);
System.out.println(“>>解码数据”+Arrays.toString(decodedData));
文件输出文件=新文件(文件路径);
AudioFormat格式=新的AudioFormat(8000、16、1、真、假);
AudioSystem.write(新的AudioInputStream(新的ByteArrayInputStream(
decodedata),format,decodedata.length),AudioFileFormat.Type.WAVE,outFile);
结果=真;
返回结果;
}捕获(IOEX异常){

System.out.println(“已经有一段时间了,但我认为这可能会对某些人有所帮助。这是我的解决方案-我正在将字节写回任意输出流(在我的例子中是servletoutputstream)。首先,我将WAV头(44字节)写入输出流,并写入pcm字节(您需要将pcm数据转换为字节数组).我在html中使用了音频标记,并将src标记指定为我的api url,它工作得非常好

public void streamCloudObject(OutputStream stream, InputStream pcmData) throws IOException {

    stream.write(WAVHeader.build(44100,5242880));
    //byte_chunk_size is stream buffer size, I have it as 1MB, so at a time you are streaming 1MB of bytes
    byte[] outBytes = new byte[BYTE_CHUNK_SIZE];

    while(true) {   
        int r = pcmData.read(outBytes);
        if(r == -1)
            break;      
        stream.write(outBytes,0,r); 

    }

}


public class WAVHeader {

private static final int CHUNK_SIZE = 36;
private static final int BIT_RATE_16 = 16;
private static final int MONO = 1;
private static final int HEADER_SIZE = 44;

//inputStreamLength - I send the pcm filesize here and I get it from s3.
public static byte[] build(int sampleRate,int inputStreamLength) {

    byte[] header = new byte[HEADER_SIZE];
    int srate = resp.getSampleRate();
    int channel = MONO;
    int format = BIT_RATE_16;
    long dataLength = inputStreamLength;

    long totalDataLen = dataLength + CHUNK_SIZE;
    long bitrate = srate * channel * format;

    header[0] = 'R'; 
    header[1] = 'I';
    header[2] = 'F';
    header[3] = 'F';
    header[4] = (byte) (totalDataLen & 0xff);
    header[5] = (byte) ((totalDataLen >> 8) & 0xff);
    header[6] = (byte) ((totalDataLen >> 16) & 0xff);
    header[7] = (byte) ((totalDataLen >> 24) & 0xff);
    header[8] = 'W';
    header[9] = 'A';
    header[10] = 'V';
    header[11] = 'E';
    header[12] = 'f'; 
    header[13] = 'm';
    header[14] = 't';
    header[15] = ' ';
    header[16] = (byte) format; 
    header[17] = 0;
    header[18] = 0;
    header[19] = 0;
    header[20] = 1; 
    header[21] = 0;
    header[22] = (byte) channel; 
    header[23] = 0;
    header[24] = (byte) (srate & 0xff);
    header[25] = (byte) ((srate >> 8) & 0xff);
    header[26] = (byte) ((srate >> 16) & 0xff);
    header[27] = (byte) ((srate >> 24) & 0xff);
    header[28] = (byte) ((bitrate / 8) & 0xff);
    header[29] = (byte) (((bitrate / 8) >> 8) & 0xff);
    header[30] = (byte) (((bitrate / 8) >> 16) & 0xff);
    header[31] = (byte) (((bitrate / 8) >> 24) & 0xff);
    header[32] = (byte) ((channel * format) / 8); 
    header[33] = 0;
    header[34] = 16; 
    header[35] = 0;
    header[36] = 'd';
    header[37] = 'a';
    header[38] = 't';
    header[39] = 'a';
    header[40] = (byte) (dataLength  & 0xff);
    header[41] = (byte) ((dataLength >> 8) & 0xff);
    header[42] = (byte) ((dataLength >> 16) & 0xff);
    header[43] = (byte) ((dataLength >> 24) & 0xff);
    return header;
}
}

您提供的两个链接看起来像是有效的解决方案,因为它们创建了缺少原始数据的WAVE头。@maxime.bochon:是的。但问题是这些解决方案与“文件”相关,而不是原始“字节”[]’。在我的情况下,与这些解决方案相比,我没有wave标头所需的数据长度。同样,我只有一部实际电话的PCM字节,我不知道电话会持续多长时间。有没有办法将无限的wave文件流式传输到浏览器?谢谢。这实际上就是我们需要的当我读到“能够转换,在飞行中”时,我被激怒了"…我从来没有读过WAVE头中的流模式。而且,如果我记得清楚的话,WAVE文件的长度是有限制的。你的问题更多的是在应用层而不是在格式化层。这是一个与你相关的主题。PCM和WAV基本上是一样的,唯一的区别是WAV文件有一个头。现在,头需要au要正确创建dio长度。因此,我认为“动态”创建wav的可能性不大。@lCapp:这是真的,这就是我放弃此功能的原因。我必须找到另一种解决方案使此功能正常工作。可能需要使用WebRTC trancoders来完成此操作。谢谢!)