首页 > 解决方案 > 试图将原始 PCM 写入 WAV 并且只获取标题

问题描述

我目前正在使用此代码:

File wavFile=new File("tmp"+File.separator+"recordings"+File.separator+uuid.toString()+".wav");
try{
    FileInputStream pcmInputStream=new FileInputStream(file);
    FileOutputStream wavOutputStream=new FileOutputStream(wavFile);
    AudioSystem.write(new AudioInputStream(new ByteArrayInputStream(IOUtils.toByteArray(pcmInputStream)),
    new AudioFormat(48000,16,2,true,
    true),IOUtils.toByteArray(pcmInputStream).length/4),
    AudioFileFormat.Type.WAVE,wavOutputStream);
    wavOutputStream.flush();
    wavOutputStream.close();
    pcmInputStream.close();
    fileOutputStream.close();
}catch(IOException e){
    e.printStackTrace();
}

检查后,我可以确认 PCM 有 30 秒的数据,大约是 4.7MB。这会写入 .wav 文件,但它只有 44 个字节且不可播放,我认为这 44 个字节是 RIFF 标头,但不确定如何解决它。我尝试过使用不同长度和不同组合的 File/ByteArray OutputStreams。

标签: javaaudioencodingwavpcm

解决方案


创建时AudioInputStream,您调用IOUtils.toByteArray(pcmInputStream)了两次,在第二次调用时,输入流已经前进到最后,因此toByteArray返回一个空数组。这导致 0 作为参数传递给AudioInputStream构造函数的长度。

new AudioInputStream(
    new ByteArrayInputStream( IOUtils.toByteArray(pcmInputStream) ),
    new AudioFormat(48000,16,2,true,true),
    ( IOUtils.toByteArray(pcmInputStream) ).length/4
)

您应该将字节数组保存到临时变量中,而不是尝试toByteArray在同一输入流上调用两次。


推荐阅读