Intereting Posts
Не удалось решить com.google.firebase: firebase-core: 10.0.1 Как показать свое текущее местоположение в Google Map? Начните вторую операцию внутри TestCase (которая не является тестируемой активностью) Строки списка Android ListView в ScrollView не отображаются полностью – обрезаны Android WebView открывается в WebView, а не в браузере по умолчанию. Проблемы с отображением исключений android.graphics.drawable Не удалось найти цель с хеш-строкой 'android-22' Как открыть окно терминала эмулятора Android? Как изменить фон названия Android Alert Dialog Пользовательский интерфейс перемещается вверх при открытии клавиатуры Метод getSupportFragmentManager () не определен Хороший учебник по использованию AccountManager в Android? Android-веб-просмотр, файловый файл filechooser не отображается Начальная активность в образе просмотра изображения в адаптере пользовательского массива Тест UI для Android Espresso – Не удалось выполнить проверку: сбой инструментария из-за «java.lang.IllegalAccessError»

Декодирование аудиофайлов и повторное кодирование в желаемый формат PCM: 44,100 кГц, 2 канала, 16 бит

Я хочу декодировать аудиофайлы для сырых данных PCM, чтобы передать их на устройство воспроизведения в локальной сети. Для этого я использую новые классы MediaExtractor и MediaCodec , представленные с уровнем API 16. Устройство требует, чтобы данные PCM находились в 44 100 кГц, имеют 2 канала и 16-разрядный размер выборки . Это работает нормально, пока входной файл примерно соответствует этим требованиям. Однако всякий раз, когда я декодирую MP3-файл, который использует, например, частоту дискретизации 32 000 кГц и, возможно, имеет только один канал, я не получаю требуемый вывод из класса MediaCodec.

Похоже, я не могу указать выходной формат класса MediaCodec . Поэтому я решил создать экземпляр другого объекта MediaCodec для повторного кодирования необработанных данных в желаемый формат. Согласно списку поддерживаемых медиаформатов, Android поддерживает кодирование в PCM / Wave с Android 4.1. Однако я не могу создать объект MediaCodec, который кодируется в PCM / Wave . Я попытался передать все типы MIME-типов в MediaCodec.createEncoderByType (type); Но я всегда с ошибкой IOException:

java.io.IOException: Failed to allocate component instance at android.media.MediaCodec.native_setup(Native Method) at android.media.MediaCodec.<init>(MediaCodec.java:210) at android.media.MediaCodec.createEncoderByType(MediaCodec.java:194) [..] 

Кто-нибудь из вас смог успешно создать экземпляр MediaCodec, который кодирует в PCM / Wave и может предоставить мне рабочий пример?

Solutions Collecting From Web of "Декодирование аудиофайлов и повторное кодирование в желаемый формат PCM: 44,100 кГц, 2 канала, 16 бит"

Согласно нашему разговору в комментариях, этот ответ относится к декодированию аудиоданных в PCM с использованием OpenSL. К сожалению, я не могу предоставить аналогичный ответ, используя класс MediaCodec .

Чтобы начать, настройте проект Android NDK (с помощью Eclipse: щелкните правой кнопкой мыши проект, Android Tools -> Add Native support …). Затем в созданном файле Android.mk, по крайней мере, вам нужно будет связать его с библиотекой OpenSL:

 LOCAL_LDLIBS += -lOpenSLES 

Если вам еще не нравится проект NDK, в старом интерфейсе есть много учебников, например, здесь и здесь .

После того, как вы работаете над проектом NDK, общая цель будет заключаться в том, чтобы настроить аудиоплеер, который действует как декодер для PCM. В примерах NDK есть пример, который делает именно это. Это немного сложнее, чем если бы вы использовали минимально функциональный инструмент, но он должен вас поймать. Существует довольно легкое для понимания описание того, что происходит на этой ссылке (поиск «Декодирование звука в PCM»). Я предоставил вам ссылку на соответствующую спецификацию OpenSL в комментариях, но там она снова. Структура SLDataFormat_PCM вы должны использовать при указании приемника данных, будет выглядеть примерно так:

 SLDataFormat_PCM pcm = { SL_DATAFORMAT_PCM, 2, // numChannels SL_SAMPLINGRATE_44_1, // samplesPerSec SL_PCMSAMPLEFORMAT_FIXED_16, // bitsPerSample SL_PCMSAMPLEFORMAT_FIXED_16, // containerSize SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT, // channelMask SL_BYTEORDER_LITTLEENDIAN // endianness }; 

Следуя примеру и описательному руководству, вы должны определить SLDataSink с локальным локатором данных очереди буфера Android и указанным выше форматом данных. Затем плеер должен предоставить вам ряд буферов, содержащих данные в правильном формате. Затем вы можете передать эти данные на Java или (лучше) передать данные из собственного кода.