在 Java 中将音频流转换为 WAV 字节数组,无需临时文件

发布于 2024-07-07 18:07:16 字数 902 浏览 10 评论 0原文

给定一个名为 inInputStream ,其中包含压缩格式(例如 MP3 或 OGG)的音频数据,我希望创建一个包含以下内容的 byte 数组:输入数据的 WAV 转换。 不幸的是,如果您尝试这样做,JavaSound 会给您带来以下错误:

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;

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

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:

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:

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一人独醉 2024-07-14 18:07:16

问题是大多数 AudioFileWriter 在写入 OutputStream 时需要提前知道文件大小。 因为你无法提供这个,所以它总是失败。 不幸的是,默认的 Java 声音 API 实现没有任何替代方案。

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

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.

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

话少心凉 2024-07-14 18:07:16

我注意到这个问题很久以前就被问过。 如果任何新人(使用 Java 7 及更高版本)发现此线程,请注意有一种更好的新方法通过 Files.readAllBytes API 来执行此操作。 看:
如何将 .wav 文件转换为字节数组?

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?

暮年慕年 2024-07-14 18:07:16

我知道为时已晚,但我需要这个,所以这是我对这个主题的两分钱。

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();
}

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();
}
停顿的约定 2024-07-14 18:07:16

如果您准备将为您创建正确的标头的类,那么这个问题很容易解决。 在我的示例中 示例如何读取 wav 缓冲区中的音频输入 数据进入某个缓冲区,之后我创建标头并在缓冲区中有 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。

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 buffer data 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.

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.

深居我梦 2024-07-14 18:07:16

这很简单...

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 文件。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文