我AudioInputStream
从URLConnection
via得到一个javax.sound.sampled.AudioSystem.getAudioInputStream()
。将 a 传递URL
给 getAudioInputStream() 函数时,一切正常。但是,为了防止阻塞,我使用 aURLConnection
来获取输入流,以便我可以设置 a timeout
。由于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
会导致这种不一致的行为?毕竟, aBufferedInputStream
扩展了 anInputStream
并且应该在外部表现相同。
我在没有设置URLConnection
超时的情况下对此进行了测试,并且错误仍然存在,但是当我切换回将其URL
直接传递给getAudioInputStream()
函数时,它就可以工作了。
*我正在使用Tritonus
和JLayer
。
编辑:我不能提供所有的代码,因为这个类非常大。这是相关的代码。
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