如何在Java中将字节数组转换为AudioInputStream

3

我想将一个字节数组转换为AudioInputStream。该字节数组之前是从*.wav文件中填充的。我有以下代码:

    public static AudioInputStream writeBytesBackToStream(byte[] bytes) {
    ByteArrayInputStream baiut = new ByteArrayInputStream(bytes);
    AudioInputStream stream = null;
    try {
        stream = AudioSystem.getAudioInputStream(baiut);
    } catch (UnsupportedAudioFileException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

    if(stream.equals(null) || stream == null) {
        System.out.println("WARNING: Stream read by byte array is null!");
    }
    return stream;
}

现在我只想将这个字节数组转换成一个AudioInputStream,但是会抛出UnsupportedAudioFileException异常:

javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from    input stream

有人有想法吗?


使用 此链接 来确认它是否支持 wav 文件,并尝试将 wav 文件传递给 getAudioInputStream 函数进行测试... 这样你就可以检查问题是出在字节数组还是文件本身上。 - fmodos
你能够发布WAV文件加载代码以验证你的字节数组是否正确吗? - gma
我相信Durandel的答案是正确的,但阅读这篇入门文章可能会有所帮助:http://blog.bjornroche.com/2013/05/the-abcs-of-pcm-uncompressed-digital.html - Bjorn Roche
2个回答

7

如果数据实际上是PCM格式,另一种处理方式是手动设置AudioFormat参数。以下是创建A小调的示例:

    byte[] b = new byte[64000];
    //lets make a 440hz tone for 1s at 32kbps, and 523.25hz.
    for(int i = 0; i<b.length/2; i++){

        b[i*2+1] = (byte)(127*Math.sin(4*Math.PI*440.0/b.length*i));
        b[i*2]  = (byte)(127*Math.sin(4*Math.PI*523.25/b.length*i));
    }

    AudioInputStream stream = new AudioInputStream(
        new ByteArrayInputStream(b), 
        new AudioFormat(16000, 8, 2, true, false), 
        64000
    );

如果你将字节转化为声音并戴着耳机,请小心。


1
如果您正确读取WAV文件,则字节数组将只包含原始PCM数据。因此,AudioSystem无法识别流的格式并抛出异常。
这是设计上不可行的。您需要在流中提供完整的音频格式图像,以使AudioSystem识别流的格式,而不仅仅是原始数据。

谢谢,编写 .wav 头文件是解决方案。我以为每次都可以获得 AudioInputStream,即使没有头文件。 - Thomas Kosch
@Kosch 如果你仔细想一下,就会发现这是不可能实现的。getAudioInputStream() 怎么能仅凭原始数据就确定它是单声道/立体声、每个样本的字节数、字节顺序和采样率呢? - Durandal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接