Как избежать пропуска аудиотрека в аудиобуфере в Android?

#android #mp3 #audio-streaming #aac

#Android #mp3 #потоковое аудио #aac

Вопрос:

Я хочу реализовать потоковое воспроизведение аудио в реальном времени для своего приложения для Android.Итак, я использовал OpenCORE aacdec библиотеку и завернул ее.Потому что я должен воспроизводить как MP3, так и AAC.

Сохраненный поток в виде файлов (размером 50 * 1024), считывает и декодирует каждый файл с помощью библиотеки BufferReader и Decoder .

Для чтения каждого файла изменен next() метод BufferReader .Внутри next() считываемого файла в виде буфера, размер которого совпадает с размером файла (т.е. 50 * 1024). Запись этих декодов AudioTrack в буфер в потоке и воспроизведение.

 public void run() {
           short[] samplesBuffered = getDecodedSample(filePath);

        if (samplesBuffered != null) {
            // samples written to AudioTrack in this round:
            int writtenNow = 0;
            int ln = samplesBuffered.length;
            do {
                if (writtenNow != 0) {
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                    }
                }
                int written = track.write(samplesBuffered, writtenNow, ln);
                if (written < 0) {
                    stopped = true;
                    break;
                }
                writtenTotal  = written;
                int buffered = writtenTotal - track.getPlaybackHeadPosition()
                        * configuration.getChannels();
                if (!stopped amp;amp; !isPlaying) {
                    if (buffered * 2 >= configuration.getBufferSizeInBytes()) {
                        track.play();
                        isPlaying = true;
                    }
                }

                writtenNow  = written;
                ln -= written;
            } while (ln > 0 amp;amp; !stopped);
        }
    }


private  synchronized short[] getDecodedSample(String filePath) {
        InputStream iStream = null;
        BufferReader reader = null;
        try {
            if (decoder != null) {
                decoder.stop();
            }
            iStream = new FileInputStream(filePath.trim());
            reader = new BufferReader(PlayerUtils.computeInputBufferSize(declaredBitRate, decodeBufferCapacityMs), iStream);
            //new Thread(reader).start();

            Decoder.Info info = decoder.start(reader);
            short[] decodeBuffer = new short[PCMFeed.msToSamples( decodeBufferCapacityMs, info.getSampleRate(), info.getChannels())];

            info = decoder.decode(decodeBuffer, decodeBuffer.length);

            int nsamp = info.getRoundSamples();
            if (nsamp == 0 || reader.isStopped()){
                return null;
            }

            return decodeBuffer;
        } catch (FileNotFoundException e) {
        } catch (Exception e) {
        } finally {
            try {
                iStream.close();
            } catch (Exception e) {
            }
        }
        return null;
    }
  

Объем буфера декодирования: 5000
Объем аудиобуфера: 1000
Размер буфера аудиотрека: 88200
частота дискретизации: 22050

Моя проблема в том, что AudioTrack пропускает последнюю часть каждого буфера.Как я могу решить эту проблему?

Ответ №1:

Я знаю, что это было год назад, но на случай, если вы все еще ищете решение или оно нужно другим — вам нужно воспроизвести весь буфер, который вам нужен, чтобы записать в «дорожку» все, что осталось в вашем буфере PCMFeed, а не сразу завершить do-while (ln > 0 amp;amp; !stopped); цикл.

Пожалуйста, проверьте более подробную информацию здесь: https://github.com/vbartacek/aacdecoder-android/blob/master/decoder/src/com/spoledge/aacdecoder/PCMFeed.java

И обратите внимание на waitForLastTone метод и логику вокруг него.