在没有临时文件的情况下将音频流转换为Java中的WAV字节数组

时间:2021-12-24 19:42:41

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:

给定一个调用的InputStream,其中包含压缩格式的音频数据(如MP3或OGG),我希望创建一个包含输入数据的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?

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

5 个解决方案

#1


6  

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,大多数AudioFileWriters需要事先知道文件大小。因为您无法提供此功能,所以始终会失败。不幸的是,默认的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

#2


1  

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文件转换为字节数组?

#3


1  

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

#4


-1  

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.

如果您准备将为您创建正确标题的类,则该问题很容易解决。在我的示例示例中,如何读取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类。

#5


-2  

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

#1


6  

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,大多数AudioFileWriters需要事先知道文件大小。因为您无法提供此功能,所以始终会失败。不幸的是,默认的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

#2


1  

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文件转换为字节数组?

#3


1  

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

#4


-1  

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.

如果您准备将为您创建正确标题的类,则该问题很容易解决。在我的示例示例中,如何读取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类。

#5


-2  

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