java - 使用 BufferedInputStream 从服务器读取音频

标签 java inputstream urlconnection javax.sound.sampled

我通过 javax.sound.sampled.AudioSystem.getAudioInputStream()URLConnection 获取 AudioInputStream。当将 URL 传递给 getAudioInputStream() 函数时,一切正常。但是,为了防止阻塞,我使用 URLConnection 来获取输入流,以便我可以设置超时。由于 AudioInputStream 要求流被标记为支持且可重置,因此我将 URLConnection 输入流包装在 BufferedInputStream 中。

使用 BufferedInputStream 时,在流中的单首歌曲末尾(由 Icecast 提供),AudioInputStream.read() 方法会抛出 ArrayIndexOutOfBounds 异常。它并不是每首歌曲都一致发生,它的出现相当随机。

这是堆栈跟踪:

java.lang.ArrayIndexOutOfBoundsException: 15
    at javazoom.jl.decoder.LayerIDecoder$SubbandLayer1Stereo.read_allocation(Unknown Source)
    at javazoom.jl.decoder.LayerIDecoder.readAllocation(Unknown Source)
    at javazoom.jl.decoder.LayerIDecoder.decodeFrame(Unknown Source)
    at javazoom.jl.decoder.Decoder.decodeFrame(Unknown Source)
    at javazoom.spi.mpeg.sampled.convert.DecodedMpegAudioInputStream.execute(Unknown Source)
    at org.tritonus.share.TCircularBuffer.read(TCircularBuffer.java:138)
    at org.tritonus.share.sampled.convert.TAsynchronousFilteredAudioInputStream.read(TAsynchronousFilteredAudioInputStream.java:189)
    at [line where the AudioInputStream.read() is located]

我想知道,BufferedInputStream 的哪些底层属性会导致这种不一致的行为?毕竟,BufferedInputStream 扩展了 InputStream 并且在外部的行为应该相同。

我在没有设置 URLConnection 超时的情况下对此进行了测试,并且错误仍然存​​在,但是当我切换回将 URL 直接传递到 getAudioInputStream() 时,错误仍然存​​在 功能,它有效。

*我正在使用 TritonusJLayer

编辑:我无法提供所有代码,因为该类非常大。这是相关代码。

URLConnection uc = url.openConnection();
uc.setReadTimeout(30000);
uc.setConnectTimeout(20000);
uc.connect();

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new BufferedInputStream(uc.getInputStream()));

和读取(af 是存储音频信息并声明 AudioInputStream 的自定义类的实例)

//Performs a necessary conversion
AudioInputStream in = AudioSystem.getAudioInputStream(af.getAudioFormat(), af.getAudioStream());

while(play) {
    try {
        int n = 0;
        if ((n = in.read(buffer, 0, buffer.length)) == -1) {
            break;
        }
    } catch (ArrayIndexOutOfBoundsException e) {
        e.printStackTrace();
    }

    // SourceDataLine.write() here...
}

*如果您想知道,我设置这样的读取循环是有原因的(在 while 循环内使用 if 语句)。

read_allocation() 所在库的源代码:https://github.com/libgdx/jlayer-gdx/blob/master/src/javazoom/jl/decoder/LayerIDecoder.java

最佳答案

BufferedInputStream 只允许您标记/重置缓冲区的大小。尝试将其增加到超过文件大小。

关于java - 使用 BufferedInputStream 从服务器读取音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24620996/

相关文章:

java - 从mongoDB复制数据到hdfs时hadoop jar错误

java - 如果添加了名称模板,为什么 Eclipse 无法识别多模块 Maven 项目的 Java 性质?

Java - 如何使用输出流向子进程发送值?

java - 如何从网站获取非拉丁字符?

java - 如何使用java.net.URLConnection触发和处理HTTP请求?

java调用包程序无响应

java - 如何使IntelliJ IDEA理解我的null检查方法?

java - 如何在 Java 中读取 Zip 文件中的 XML

android - 捕获 BluetoothSocket InputStream.read() 超时的线程

android - Cloudant/CouchDB key /通行证权限不起作用