您可以使用供應商擴展來擴展媒體提取器和媒體編解碼器組件。 MediaSession2 和 MediaParser API 無法自定義(但您可以上游更改舊版MediaPlayer
和MediaSession
API)。
要在 Android 媒體框架中支持其他媒體類型,您需要創建自定義提取器和解碼器。例如,要在 AVI 文件中添加對 Windows Media 視頻的支持,您需要創建一個 AVI Extractor和一個 Windows Media 視頻解碼器。
關於擴展
如果默認媒體提取器不符合您的要求,您可以將自定義提取器插件放在/system/lib[64]/extractors/
中。提取器進程會自動從 Google 提供的 APEX 包和/system/lib[64]/extractors/
加載提取器插件。
同樣,您可以設置使用frameworks/av/media/codec2/core/
中定義的 Codec 2.0 接口的自定義媒體編解碼器服務。有關基本實現,請參閱frameworks/av/media/codec2/hidl/services/
。庫入口點是C2ComponentStore
接口。例如,請參閱frameworks/av/media/codec2/vndk/C2Store.cpp
中的默認軟件編解碼器存儲實現。
使用您自己的 APEX 時,構建編解碼器服務並使用與mediaswcodec
服務相同的進程加載 APEX 文件。為此,請定義一個負責註冊所有 C2 組件的頂級共享庫,然後創建一個駐留在供應商分區中的 APEX 包(具有傳遞依賴項)。當供應商編解碼器服務進程啟動時,它可以加載這個頂級入口點。
創建提取器
在為新格式添加提取器時,請確保提取器僅依賴於穩定的 NDK API,而不依賴於任何私有 API。提取器應該實現由frameworks/av/include/media/MediaExtractorPluginApi.h
定義的 API,並且可以使用frameworks/av/include/media/MediaExtractorPluginHelper.h
/av/include/media/MediaExtractorPluginHelper.h 中的 C++ 便利包裝器。由於 Android 10 或更高版本僅支持提取器 API 的最高版本,因此請務必在具有最高 API 版本號的提取器之後建模您的提取器。
將自定義提取器放置在/system/lib/64/extractors
或供應商 APEX 中,它與包含 Google 提取器的 Google APEX 一起打開。要驗證框架加載了您的提取器,請運行以下命令。
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 提供的解碼器尚不支持的任何格式,您都需要一個自定義解碼器。例如:
要為包含 MP3 的 AVI 文件添加媒體框架支持,您需要一個 AVI 提取器,但不需要 MP3 解碼器,因為它已經存在。
要為包含 Windows Media 的 AVI 文件添加媒體框架支持,您需要一個 AVI 提取器和一個 Windows Media 解碼器。
添加新解碼器類似於為 AVC 或 HEVC 添加您自己的硬件解碼器。
當提取器發布它包含的媒體軌道的 MIME 類型時,需要存在支持這些 MIME 類型的編解碼器才能完全支持文件。實際使用的 MIME 類型字符串是提取器和編解碼器之間的嚴格協議(該字符串不需要添加到MediaDefs.h
文件中)。
與媒體掃描儀集成
媒體掃描儀尋找新的文件類型並將它們添加到媒體數據庫中。要讓媒體掃描儀處理您的自定義文件類型,掃描儀需要了解它。在 Android 10 或更高版本中, MimeUtils
(在libcore
中)維護 MIME 到擴展名的映射。以前,此映射在MediaFile.java
文件中處理,該文件繼續包含從 MIME 類型到 MTP 格式常量的映射。
提取器可以導出它們支持的文件擴展名列表(例如 MP3 或 MP4)。但是,只有LegacyMediaScanner
使用它;它對默認使用的ModernMediaScanner
沒有影響。