Использование 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 позволяет только пометить / сбросить до размера буфера. Попробуйте увеличить его до размера файла.

Другие вопросы по тегам