在没有临时文件的 Java 中将音频流转换为 WAV 字节数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/198679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert audio stream to WAV byte array in Java without temp file
提问by Robert J. Walker
Given an InputStream
called in
which contains audio data in a compressed format (such as MP3 or OGG), I wish to create a byte
array containing a WAV conversion of the input data. Unfortunately, if you try to do this, JavaSound hands you the following error:
给定一个包含压缩格式(如 MP3 或 OGG)音频数据的InputStream
调用in
,我希望创建一个byte
包含输入数据的 WAV 转换的数组。不幸的是,如果您尝试这样做,JavaSound 会给您以下错误:
java.io.IOException: stream length not specified
I managed to get it to work by writing the wav to a temporary file, then reading it back in, as shown below:
我设法通过将 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;
This is obviously less desirable. Is there a better way?
这显然不太理想。有没有更好的办法?
采纳答案by Simon Lehmann
The problem is that the most AudioFileWriters need to know the file size in advance if writing to an OutputStream. Because you can't provide this, it always fails. Unfortunatly, the default Java sound API implementation doesn't have any alternatives.
问题是,如果写入 OutputStream,大多数 AudioFileWriter 需要提前知道文件大小。因为你不能提供这个,它总是失败。不幸的是,默认的 Java 声音 API 实现没有任何替代方案。
But you can try using the AudioOutputStream architecture from the Tritonus plugins (Tritonus is an open source implementation of the Java sound API): http://tritonus.org/plugins.html
但是您可以尝试使用 Tritonus 插件中的 AudioOutputStream 架构(Tritonus 是 Java 声音 API 的开源实现):http://tritonus.org/plugins.html
回答by Gábor Dikán
This is very simple...
这非常简单...
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();
The .tmp file is a RAW audio file, the result is a WAV file with header.
.tmp 文件是一个 RAW 音频文件,结果是一个带标题的 WAV 文件。
回答by Superziyi
I notice this one was asked very long time ago. In case any new person (using Java 7 and above) found this thread, note there is a better new way doing it via Files.readAllBytes API. See: How to convert .wav file into byte array?
我注意到很久以前就有人问过这个问题。如果任何新人(使用 Java 7 及更高版本)发现此线程,请注意通过 Files.readAllBytes API 有一种更好的新方法。请参阅: 如何将 .wav 文件转换为字节数组?
回答by HolloW
Too late, I know, but I was needed this, so this is my two cents on the topic.
太晚了,我知道,但我需要这个,所以这是我在这个主题上的两分钱。
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();
}
回答by Kanaris007
The issue is easy to solve if you prepare class which will create correct header for you. In my example Example how to read audio input in wav bufferdata goes in some buffer, after that I create header and have wav file in the buffer. No need in additional libraries. Just copy the code from my example.
如果您准备为您创建正确标题的类,这个问题很容易解决。在我的示例中,示例如何读取 wav 缓冲区中的音频输入数据进入某个缓冲区,之后我创建标题并在缓冲区中有 wav 文件。不需要额外的库。只需从我的示例中复制代码。
Example how to use class which creates correct header in the buffer array:
示例如何使用在缓冲区数组中创建正确标头的类:
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();
}
And class NewWaveWriter you can find under my link.
你可以在我的链接下找到 NewWaveWriter 类。