#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
метод и логику вокруг него.