Использование BufferedInputStream для чтения аудио с сервера
Я получаю AudioInputStream
из URLConnection
с помощью javax.sound.sampled.AudioSystem.getAudioInputStream()
, При прохождении URL
для функции getAudioInputStream() все работает отлично. Однако, чтобы предотвратить блокировку, я использую URLConnection
чтобы получить входной поток, чтобы я мог установить 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
будет вызывать это противоречивое поведение? В конце концов, BufferedInputStream
расширяет InputStream
и должен вести себя так же снаружи.
Я проверил это без настройки 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...
}
* Если вам интересно, я по какой-то причине настроил цикл чтения таким образом (с оператором if внутри цикла while).
Исходный код библиотеки, в которой находится read_allocation(): https://github.com/libgdx/jlayer-gdx/blob/master/src/javazoom/jl/decoder/LayerIDecoder.java
1 ответ
BufferedInputStream позволяет только пометить / сбросить до размера буфера. Попробуйте увеличить его до размера файла.