您可以使用供應商擴充功能擴充媒體擷取器和媒體編解碼元件。您無法自訂 MediaSession2 和 MediaParser API (但可以將變更內容上傳至舊版 MediaPlayer
和 MediaSession
API)。
如要在 Android 媒體架構中支援其他媒體類型,您需要建立自訂的extractor 和decoder。舉例來說,如要在 AVI 檔案中新增 Windows Media 影片支援功能,您需要建立 AVI Extractor 和 Windows Media 影片 Decoder。
關於擴充功能
如果預設的媒體擷取器不符合您的需求,您可以將自訂擷取器外掛程式放入 /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。Extractor 應實作由 frameworks/av/include/media/MediaExtractorPluginApi.h
定義的 API,並可使用 frameworks/av/include/media/MediaExtractorPluginHelper.h
中的 C++ 方便包裝函式。由於 Android 10 以上版本只支援最高版本的 extractor API,請務必在具有最高 API 版本號碼的 extractor 之後建構 extractor。
將自訂擷取器放在 /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 Extractor,但不需要 MP3 解碼器,因為已經有一個。
如要為含有 Windows Media 的 AVI 檔案新增媒體架構支援,您需要同時具備 AVI Extractor 和 Windows Media 解碼器。
新增解碼器的做法類似於為 AVC 或 HEVC 新增自己的硬體解碼器。
雖然擷取器會發布所含媒體音軌的 MIME 類型,但檔案必須提供支援這些 MIME 類型的編解碼器,才能獲得完整支援。實際使用的 MIME 類型字串,嚴格來說是萃取器和編解碼之間的協議 (字串不必加入 MediaDefs.h
檔案)。
整合媒體掃描器
媒體掃描器會尋找新的檔案類型,並將這些檔案類型新增至媒體資料庫。如要讓媒體掃描器處理自訂檔案類型,掃描器必須瞭解該類型。在 Android 10 以上版本中,MimeUtils
(位於 libcore
中) 會維護 MIME 到副檔名的對應關係。先前,這個對應項目是在 MediaFile.java
檔案中處理,該檔案會繼續包含從 MIME 類型到 MTP 格式常數的對應項目。
擷取器可匯出支援的副檔名清單 (例如 MP3 或 MP4)。不過,只有 LegacyMediaScanner
會使用該值,對預設使用的 ModernMediaScanner
沒有任何影響。