Komponenty Media Extractor i Media Codec można rozszerzyć za pomocą rozszerzeń dostawcy. Interfejsów API MediaSession2 i MediaParser nie można dostosowywać (ale można wprowadzić zmiany w starszych interfejsach API MediaPlayer
i MediaSession
).
Aby obsługiwać dodatkowe typy multimediów w środowisku multimedialnym Androida, musisz utworzyć niestandardowy ekstraktor i dekoder . Na przykład, aby dodać obsługę wideo Windows Media w plikach AVI, musisz utworzyć ekstraktor AVI i dekoder wideo Windows Media .
O rozszerzeniach
Jeśli domyślne ekstraktory multimediów nie spełniają Twoich wymagań, możesz umieścić niestandardowe wtyczki ekstraktorów w /system/lib[64]/extractors/
. Proces ekstraktora automatycznie ładuje wtyczki ekstraktora z dostarczonego przez Google pakietu APEX oraz z /system/lib[64]/extractors/
.
Podobnie można skonfigurować niestandardowe usługi kodeków multimedialnych, które korzystają z interfejsu Codec 2.0 zdefiniowanego w frameworks/av/media/codec2/core/
. Aby zapoznać się z podstawową implementacją, zapoznaj się z frameworks/av/media/codec2/hidl/services/
. Punktem wejścia biblioteki jest interfejs C2ComponentStore
. Aby zapoznać się z przykładem, zapoznaj się z domyślną implementacją sklepu z kodekami oprogramowania pod adresem frameworks/av/media/codec2/vndk/C2Store.cpp
.
Korzystając z własnego APEX, ustrukturyzuj usługę kodeka i załaduj plik APEX przy użyciu tych samych procesów, co usługa mediaswcodec
. Aby to zrobić, zdefiniuj bibliotekę współdzieloną najwyższego poziomu odpowiedzialną za rejestrację wszystkich komponentów C2, a następnie utwórz pakiet APEX (z zależnościami przechodnimi), który znajduje się na partycji dostawcy. Po rozpoczęciu procesu obsługi kodeka dostawcy może on załadować ten punkt wejścia najwyższego poziomu.
Tworzenie ekstraktora
Dodając ekstraktor dla nowego formatu, upewnij się, że ekstraktor zależy tylko od stabilnych interfejsów API NDK i nie jest zależny od żadnych prywatnych interfejsów API. Ekstraktory powinny implementować interfejs API zdefiniowany przez frameworks/av/include/media/MediaExtractorPluginApi.h
i mogą używać wygodnych otoczek języka C++ w frameworks/av/include/media/MediaExtractorPluginHelper.h
. Ponieważ system Android 10 lub nowszy obsługuje tylko najwyższą wersję interfejsu API ekstraktora, pamiętaj, aby modelować ekstraktor według ekstraktora o najwyższym numerze wersji interfejsu API.
Umieść niestandardowe ekstraktory w /system/lib/64/extractors
lub dostawcy APEX, który jest otwierany wraz z Google APEX zawierającym ekstraktory Google. Aby sprawdzić, czy framework załadował ekstraktor, uruchom następujące polecenie.
adb shell dumpsys media.extractor
Powinieneś otrzymać listę dostępnych ekstraktorów podobną do poniższej.
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)
Jeśli Twój niestandardowy ekstraktor obsługuje format, który jest już obsługiwany przez ekstraktor dostarczony przez Google, możesz zmusić framework do korzystania z ekstraktora, używając funkcji Sniff()
w celu zwrócenia wyższego poziomu ufności niż ten dostarczony przez Google.
Kiedy media framework ładuje twój ekstraktor (z /system/lib/64/extractors
lub od dostawcy APEX), rozpoznaje plik i otrzymuje informacje o jego zawartości. Następnym krokiem jest dodanie dekodera dla formatu, aby platforma mogła zrozumieć, jak analizować zawartość pliku.
Tworzenie własnego dekodera
Potrzebujesz niestandardowego dekodera dla dowolnego formatu, który nie jest jeszcze obsługiwany przez dekoder dostarczony przez Google. Na przykład:
Aby dodać obsługę media framework dla plików AVI zawierających MP3, potrzebujesz ekstraktora AVI, ale nie potrzebujesz dekodera MP3, ponieważ taki już istnieje.
Aby dodać obsługę struktury mediów dla plików AVI zawierających Windows Media, potrzebujesz zarówno ekstraktora AVI, jak i dekodera Windows Media.
Dodanie nowego dekodera jest podobne do dodawania własnych dekoderów sprzętowych dla AVC lub HEVC.
Chociaż ekstraktor publikuje typ MIME zawartych w nim ścieżek multimedialnych, kodeki obsługujące te typy MIME muszą być obecne, aby plik był w pełni obsługiwany. Użyty ciąg znaków typu MIME jest ściśle porozumieniem między ekstraktorem a kodekiem (ciąg nie musi być dodawany do pliku MediaDefs.h
).
Integracja ze skanerem mediów
Skaner multimediów wyszukuje nowe typy plików i dodaje je do bazy danych multimediów. Aby skaner multimediów obsługiwał niestandardowy typ pliku, skaner musi o tym wiedzieć. W systemie Android 10 lub nowszym MimeUtils
(w libcore
) utrzymuje mapowanie MIME-do-rozszerzenia. Poprzednio to mapowanie było obsługiwane w pliku MediaFile.java
, który nadal zawiera mapowanie z typu MIME na stałe formatu MTP.
Ekstraktor może wyeksportować listę rozszerzeń plików, które obsługuje (takich jak MP3 lub MP4). Jednak tylko LegacyMediaScanner
używa tego; nie ma to wpływu na ModernMediaScanner
, który jest używany domyślnie.