Потоковое аудио в формате MP3 через сокет с использованием OpenSL ES на Android

Я пытаюсь передать MP3-файл с телефона Android на другой телефон Android с помощью Wi-Fi через точку доступа. Проблема в том, что OpenSL ES, похоже, поддерживает только аудио буферы PCM в качестве источника (если не используется URI). Вместо того, чтобы декодировать потенциально огромный файл на стороне «мастера» перед отправкой, я бы предпочел позволить «клиенту» декодировать MP3 в PCM. Имейте в виду, что это должно происходить как поток файлов, а не просто отправлять весь файл и затем декодировать. Есть ли способ сделать это с помощью OpenSL ES? Аудио трек? Похоже, это будет довольно частый запрос.


person honeal    schedule 30.01.2013    source источник


Ответы (3)


Вы правы, что opensl, похоже, не принимает простую буферную очередь с источником mp3. При этом вместо этого вы сможете использовать SLDataLocator_URI. Теперь я понимаю, что у вас нет полного файла, доступного при запуске (поскольку вы ведете потоковую передачу), но есть способ обойти это. Если вы создаете пустой файл и используете его в качестве источника для проигрывателя URI opensl, все должно работать. Когда вы получите данные (биты mp3-файла), просто добавьте эти данные в пустой файл, который вы создали. Вы можете заставить OpenSL начать воспроизведение из этого файла до того, как вы закончите добавлять в него данные.

Создайте пустой файл с помощью:

RandomAccessFile raf = new RandomAccessFile(new File(mFileUri), "rw");
raf.setLength(audioFileSize);

Создайте свой источник звука как:

SLDataLocator_URI loc_uri = {SL_DATALOCATOR_URI, (SLchar *) fileLoc};
SLDataFormat_MIME format_mime = {SL_DATAFORMAT_MIME, NULL, SL_CONTAINERTYPE_UNSPECIFIED};
SLDataSource audioSrc = {&loc_uri, &format_mime};

Загрузите буферы с:

for (int i = 0; i < BUFFER_COUNT; i++) {
    // get byte[] data from stream
    raf.seek(i*Constants.BUFFER_SIZE);
    raf.write(data);
}

Начните воспроизведение аудио в любое время с помощью OpenSL, а затем продолжайте загрузку буферов. Пока вы опережаете процесс потоковой передачи, все будет в порядке.

person tboling1    schedule 07.02.2013

Вам нужно использовать opensl. MediaCodec (доступен в Android 4.2) может декодировать mp3 в фрагменты PCM, которые можно передать в AudioTrack.

person Ratna Beresford    schedule 14.02.2014

Вы пробовали этот пример программирования звука Виктора Лаззарини с OpenSL ES http://audioprograming.wordpress.com/2012/10/29/lock-free-audio-io-with-opensl-es-on-android?/

он обеспечивает хорошую реализацию потоковой передачи на основе http://mobilepearls.com/labs/native-android-api/ndk/docs/opensles/

person UdayaLakmal    schedule 06.02.2013
comment
По первой ссылке источник звука уже находится в формате PCM, когда он его воспроизводит. Я считаю, что исходный плакат искал способ использовать фрагменты MP3 в качестве источника. - person tboling1; 06.02.2013
comment
Верный. Как и предполагал tboling1, проблема не в потоковой передаче. Проблема заключается в потоковой передаче MP3 в звуковые буферы или декодировании этих фрагментов MP3 в PCM перед их вставкой в ​​звуковые буферы. - person honeal; 06.02.2013