将音频流转换为Java格式的WAV字节数组,无临时文件

问题描述:

给定一个名为inInputStream,其中包含压缩格式(如MP3或OGG)的音频数据,我希望创建一个包含输入的WAV转换的byte数组数据。不幸的是,如果你尝试这样做,JavaSound给了你以下错误:将音频流转换为Java格式的WAV字节数组,无临时文件

java.io.IOException: stream length not specified 

我设法得到它通过写WAV到一个临时文件,然后在回读,工作,如下图所示:

AudioInputStream source = AudioSystem.getAudioInputStream(new BufferedInputStream(in, 1024)); 
AudioInputStream pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source); 
AudioInputStream ulaw = AudioSystem.getAudioInputStream(AudioFormat.Encoding.ULAW, pcm); 
File tempFile = File.createTempFile("wav", "tmp"); 
AudioSystem.write(ulaw, AudioFileFormat.Type.WAVE, tempFile); 
// The fileToByteArray() method reads the file 
// into a byte array; omitted for brevity 
byte[] bytes = fileToByteArray(tempFile); 
tempFile.delete(); 
return bytes; 

这显然不太理想。有没有更好的办法?

问题是,如果写入OutputStream,大多数AudioFileWriters需要提前知道文件大小。因为你不能提供这个,它总是失败。不幸的是,默认的Java声音API实现没有任何选择。

但是你可以尝试使用AudioOutputStream架构从Tritonus插件(Tritonus是一个开源实现的Java API声音的):http://tritonus.org/plugins.html

+1

我得试试看。在我尝试之前可能会有一点点,所以目前我无法接受答案。不过,我会鼓励它。 – 2008-10-21 22:43:00

这是非常简单的...

File f = new File(exportFileName+".tmp"); 
File f2 = new File(exportFileName); 
long l = f.length(); 
FileInputStream fi = new FileInputStream(f); 
AudioInputStream ai = new AudioInputStream(fi,mainFormat,l/4); 
AudioSystem.write(ai, Type.WAVE, f2); 
fi.close(); 
f.delete(); 

的.tmp文件是一个RAW音频文件,结果是带有标题的WAV文件。

+1

问题问是否可以完成*没有临时文件。 – 2012-07-02 15:21:16

我注意到这是很久以前问过的。如果有任何新人(使用Java 7及以上版本)发现此线程,请注意,通过Files.readAllBytes API执行此操作有更好的新方法。请参阅: How to convert .wav file into byte array?

太迟了,我知道,但我需要这个,所以这是我的两分钱的话题。

public void UploadFiles(String fileName, byte[] bFile) 
{ 
    String uploadedFileLocation = "c:\\"; 

    AudioInputStream source; 
    AudioInputStream pcm; 
    InputStream b_in = new ByteArrayInputStream(bFile); 
    source = AudioSystem.getAudioInputStream(new BufferedInputStream(b_in)); 
    pcm = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED, source); 
    File newFile = new File(uploadedFileLocation + fileName); 
    AudioSystem.write(pcm, Type.WAVE, newFile); 

    source.close(); 
    pcm.close(); 
} 

这个问题很容易解决,如果你准备的类会为你创建正确的标题。在我的示例Example how to read audio input in wav buffer数据进入一些缓冲区,之后我创建标题并在缓冲区中有wav文件。无需额外的库。只需复制示例中的代码即可。

示例如何使用类缓存阵列中创建正确的标题:

public void run() {  
    try {  
     writer = new NewWaveWriter(44100); 

     byte[]buffer = new byte[256]; 
     int res = 0; 
     while((res = m_audioInputStream.read(buffer)) > 0) { 
      writer.write(buffer, 0, res); 
     } 
    } catch (IOException e) { 
     System.out.println("Error: " + e.getMessage()); 
    }  
}  

public byte[]getResult() throws IOException { 
    return writer.getByteBuffer(); 
} 

和类NewWaveWriter你可以在我的链接找到。