Вы можете расширить компоненты средства извлечения мультимедиа и кодека мультимедиа, используя расширения поставщиков. API-интерфейсы MediaSession2 и MediaParser нельзя настроить (но вы можете воспроизвести изменения для устаревших API-интерфейсов MediaPlayer
и MediaSession
).
Для поддержки дополнительных типов мультимедиа в медиа-фреймворке Android необходимо создать собственный экстрактор и декодер . Например, чтобы добавить поддержку видео Windows Media в файлы AVI, необходимо создать AVI Extractor и декодер видео Windows Media.
О расширениях
Если стандартные экстракторы мультимедиа не соответствуют вашим требованиям, вы можете поместить собственные подключаемые модули экстракторов в /system/lib[64]/extractors/
. Процесс экстрактора автоматически загружает подключаемые модули экстрактора из предоставленного Google пакета APEX и из /system/lib[64]/extractors/
.
Точно так же вы можете настроить пользовательские службы медиакодеков, которые используют интерфейс Codec 2.0, определенный в frameworks/av/media/codec2/core/
. Для базовой реализации обратитесь к frameworks/av/media/codec2/hidl/services/
. Точкой входа в библиотеку является интерфейс C2ComponentStore
. В качестве примера обратитесь к реализации хранилища программных кодеков по умолчанию в frameworks/av/media/codec2/vndk/C2Store.cpp
.
При использовании собственного APEX структурируйте службу кодека и загрузите файл APEX, используя те же процессы, что и служба mediaswcodec
. Для этого определите общую библиотеку верхнего уровня, отвечающую за регистрацию всех компонентов C2, а затем создайте пакет APEX (с транзитивными зависимостями), который находится в разделе поставщика. Когда процесс службы кодеков поставщика запускается, он может загрузить эту точку входа верхнего уровня.
Создание экстрактора
При добавлении экстрактора для нового формата убедитесь, что экстрактор зависит только от стабильных API-интерфейсов NDK и не зависит ни от каких частных API-интерфейсов. Экстракторы должны реализовывать API, определенный frameworks/av/include/media/MediaExtractorPluginApi.h
и могут использовать удобные оболочки C++ в frameworks/av/include/media/MediaExtractorPluginHelper.h
. Поскольку Android 10 или более поздняя версия поддерживает только самую последнюю версию API-интерфейса экстрактора, убедитесь, что ваш экстрактор смоделирован по образцу экстрактора с самым высоким номером версии API.
Поместите пользовательские экстракторы в /system/lib/64/extractors
или APEX поставщика, который открывается вместе с Google APEX, содержащим экстракторы Google. Чтобы убедиться, что фреймворк загрузил ваш экстрактор, выполните следующую команду.
adb shell dumpsys media.extractor
Вы должны получить список доступных экстракторов, похожий на следующий.
Available extractors:
AAC Extractor: plugin\_version(2), uuid(4fd80eae03d24d729eb948fa6bb54613), version(1), path(/system/lib64/extractors/libaacextractor.so)
AMR Extractor: plugin\_version(2), uuid(c86639c92f3140aca715fa01b4493aaf), version(1), path(/system/lib64/extractors/libamrextractor.so)
FLAC Extractor: plugin\_version(2), uuid(1364b048cc454fda9934327d0ebf9829), version(1), path(/system/lib64/extractors/libflacextractor.so)
MIDI Extractor: plugin\_version(2), uuid(ef6cca0af8a243e6ba5fdfcd7c9a7ef2), version(1), path(/system/lib64/extractors/libmidiextractor.so)
MP3 Extractor: plugin\_version(2), uuid(812a3f6cc8cf46deb5293774b14103d4), version(1), path(/system/lib64/extractors/libmp3extractor.so)
MP4 Extractor: plugin\_version(2), uuid(27575c6744174c548d3d8e626985a164), version(2), path(/system/lib64/extractors/libmp4extractor.so)
MPEG2-PS/TS Extractor: plugin\_version(1), uuid(3d1dcfebe40a436da574c2438a555e5f), version(1), path(/system/lib64/extractors/libmpeg2extractor.so)
Matroska Extractor: plugin\_version(2), uuid(abbedd9238c44904a4c1b3f45f899980), version(1), path(/system/lib64/extractors/libmkvextractor.so)
Ogg Extractor: plugin\_version(2), uuid(8cc5cd06f772495e8a62cba9649374e9), version(1), path(/system/lib64/extractors/liboggextractor.so)
WAV Extractor: plugin\_version(3), uuid(7d61385858374a3884c5332d1cddee27), version(1), path(/system/lib64/extractors/libwavextractor.so)
Если ваш пользовательский экстрактор поддерживает формат, который уже поддерживается экстрактором, предоставленным Google, вы можете заставить фреймворк использовать ваш экстрактор, используя функцию Sniff()
, чтобы вернуть более высокий уровень достоверности, чем предоставленный Google.
Когда медиа-фреймворк загружает ваш экстрактор (из /system/lib/64/extractors
или от поставщика APEX), он распознает файл и получает информацию о его содержимом. Следующим шагом является добавление декодера для формата, чтобы платформа могла понять, как анализировать содержимое файла.
Создание собственного декодера
Вам нужен собственный декодер для любого формата, который еще не поддерживается декодером, предоставленным Google. Например:
Чтобы добавить поддержку медиа-фреймворка для файлов AVI, содержащих MP3, вам нужен экстрактор AVI, но не нужен декодер MP3, поскольку он уже существует.
Чтобы добавить поддержку медиа-фреймворка для файлов AVI, содержащих Windows Media, вам потребуется как экстратор AVI, так и декодер Windows Media.
Добавление нового декодера аналогично добавлению собственных аппаратных декодеров для AVC или HEVC.
Хотя экстрактор публикует MIME-тип содержащихся в нем медиа-треков, для полной поддержки файла должны присутствовать кодеки, поддерживающие эти MIME-типы. Фактическая используемая строка типа MIME является строго соглашением между экстрактором и кодеком (строку не нужно добавлять в файл MediaDefs.h
).
Интеграция с медиа сканером
Сканер мультимедиа ищет новые типы файлов и добавляет их в базу данных мультимедиа. Чтобы сканер мультимедиа обрабатывал ваш пользовательский тип файла, сканер должен знать об этом. В Android 10 или более MimeUtils
(в libcore
) поддерживает сопоставление MIME с расширением. Ранее это сопоставление обрабатывалось в файле MediaFile.java
, который по-прежнему содержит сопоставление типа MIME с константами формата MTP.
Экстрактор может экспортировать список поддерживаемых расширений файлов (например, MP3 или MP4). Однако его использует только LegacyMediaScanner
; это не влияет на ModernMediaScanner
, который используется по умолчанию.