Na Androidzie 12 (API na poziomie 31) i nowszych system może automatycznie konwertować filmy nagrane w formatach takich jak HEVC (H.265) na AVC (H.264), gdy są one otwierane przez aplikację, która nie obsługuje HEVC. Ta funkcja umożliwia aplikacjom do nagrywania filmów korzystanie z nowocześniejszego, bardziej wydajnego kodowania filmów nagrywanych na urządzeniu bez utraty zgodności z innymi aplikacjami.
W przypadku treści utworzonych na urządzeniu można automatycznie transkodować te formaty:
| Format multimediów | Atrybut XML | Typ MIME MediaFormat |
|---|---|---|
| HEVC (H.265) | HEVC | MediaFormat.MIMETYPE_VIDEO_HEVC |
| HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |
| HDR10+ | HDR10Plus | MediaFeature.HdrType.HDR10_PLUS |
Android zakłada, że aplikacje mogą obsługiwać odtwarzanie wszystkich formatów multimediów, dlatego transkodowanie zgodnych multimediów jest domyślnie wyłączone.
Kiedy używać transkodowania
Transkodowanie jest operacją wymagającą dużej mocy obliczeniowej i powoduje znaczne opóźnienie podczas otwierania pliku wideo. Na przykład transkodowanie jednominutowego pliku wideo HEVC na format AVC na telefonie Pixel 3 zajmuje około 20 sekund. Z tego powodu transkodowanie pliku wideo powinno odbywać się tylko wtedy, gdy wysyłasz go z urządzenia. Na przykład podczas udostępniania pliku wideo innym użytkownikom tej samej aplikacji lub serwerowi w chmurze, który nie obsługuje nowoczesnych formatów wideo.
Nie transkoduj podczas otwierania plików wideo do odtwarzania na urządzeniu lub tworzenia miniatur.
Konfigurowanie transkodowania
Aplikacje mogą kontrolować transkodowanie, deklarując swoje możliwości multimedialne. Możesz zadeklarować te funkcje na 2 sposoby: w kodzie lub w zasobie.
Deklarowanie funkcji w kodzie
Możesz zadeklarować możliwości multimedialne w kodzie, tworząc instancję obiektu ApplicationMediaCapabilities za pomocą kreatora:
Kotlin
val mediaCapabilities = ApplicationMediaCapabilities.Builder() .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS) .build()
Java
ApplicationMediaCapabilities mediaCapabilities = new ApplicationMediaCapabilities.Builder() .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10) .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS) .build();
Używaj tego obiektu, gdy uzyskujesz dostęp do treści multimedialnych za pomocą metod takich jak ContentResolver#openTypedAssetFileDescriptor():
Kotlin
val providerOptions = Bundle().apply { putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities) } contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions) .use { fileDescriptor -> // Content will be transcoded based on values defined in the // ApplicationMediaCapabilities provided. }
Java
Bundle providerOptions = new Bundle(); providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES, mediaCapabilities); try (AssetFileDescriptor fileDescriptor = contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) { // Content will be transcoded based on values defined in the // ApplicationMediaCapabilities provided. }
Ta metoda umożliwia szczegółową kontrolę nad konkretnymi ścieżkami kodu, np. wywoływanie transkodowania tylko podczas przesyłania pliku wideo z urządzenia. Ma ona pierwszeństwo przed metodą opisaną poniżej.
Deklarowanie możliwości w zasobie
Zadeklarowanie możliwości w zasobie umożliwia ogólną kontrolę nad transkodowaniem. Tej metody należy używać tylko w bardzo konkretnych przypadkach. Na przykład jeśli aplikacja tylko odbiera pliki wideo z innych aplikacji (zamiast otwierać je bezpośrednio) i przesyła je na serwer, który nie obsługuje nowoczesnych kodeków wideo (patrz przykładowy scenariusz 1 poniżej).
Użycie tej metody, gdy nie jest to absolutnie konieczne, może wywołać transkodowanie w niezamierzonych sytuacjach, np. podczas tworzenia miniatur filmów, co może pogorszyć wrażenia użytkownika.
Aby użyć tej metody, utwórz plik zasobów media_capabilities.xml:
<?xml version="1.0" encoding="utf-8"?>
<media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
<format android:name="HEVC" supported="true"/>
<format android:name="HDR10" supported="false"/>
<format android:name="HDR10Plus" supported="false"/>
</media-capabilities>
W tym przykładzie filmy HDR nagrane na urządzeniu są płynnie transkodowane do formatu AVC SDR (standardowy zakres dynamiki), ale filmy HEVC nie są transkodowane.
Użyj tagu property w tagu application, aby dodać odwołanie do pliku z możliwościami multimedialnymi. Dodaj do pliku AndroidManifest.xml te właściwości:
<property
android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
android:resource="@xml/media_capabilities" />
otwieranie pliku wideo za pomocą funkcji multimedialnych innej aplikacji;
Jeśli Twoja aplikacja udostępnia plik wideo innej aplikacji, może być konieczne jego transkodowanie, zanim aplikacja odbierająca będzie mogła go otworzyć.
Możesz obsłużyć ten przypadek, otwierając plik wideo za pomocą openTypedAssetFileDescriptor i określając identyfikator UID aplikacji odbierającej, który można uzyskać za pomocą Binder.getCallingUid.
Następnie platforma używa funkcji multimedialnych aplikacji odbierającej, aby określić, czy plik wideo powinien zostać transkodowany.
Kotlin
val providerOptions = Bundle().apply { putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid()) } contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions) .use { fileDescriptor -> // Content will be transcoded based on the media capabilities of the // calling app. }
Java
Bundle providerOptions = new Bundle(); providerOptions.putParcelable(MediaStore.EXTRA_MEDIA_CAPABILITIES_UID, Binder.getCallingUid()); try (AssetFileDescriptor fileDescriptor = contentResolver.openTypedAssetFileDescriptor(mediaUri, mediaMimeType, providerOptions)) { // Content will be transcoded based on the media capabilities of the // calling app. }
Przykładowe scenariusze
Na diagramach poniżej przedstawiono 2 typowe przypadki użycia. W obu przypadkach oryginalny film jest zapisywany w formacie HEVC, a aplikacja do udostępniania filmów nie obsługuje tego formatu.
Przykład 1. Transkodowanie jest inicjowane przez aplikację do nagrywania filmów.
Aplikacja do udostępniania filmów deklaruje w pliku zasobów funkcji multimedialnych, że nie obsługuje formatu HEVC. Następnie żąda filmu z aplikacji do nagrywania filmów. Aplikacja do nagrywania filmów obsługuje żądanie i otwiera plik za pomocą
openTypedAssetFileDescriptor, podając identyfikator UID aplikacji udostępniającej. Spowoduje to rozpoczęcie procesu transkodowania.
Po otrzymaniu transkodowanego filmu jest on przekazywany do aplikacji do udostępniania, która przesyła go na serwer w chmurze.
Przykład 2. Transkodowanie jest inicjowane przez aplikację do udostępniania filmów.
Aplikacja do nagrywania filmów udostępnia film aplikacji do udostępniania filmów za pomocą identyfikatora URI
MediaStore. Aplikacja do udostępniania filmów otwiera plik wideo za pomocą openTypedAssetFileDescriptor, określając, że nie obsługuje HEVC w swoich funkcjach multimedialnych. Spowoduje to rozpoczęcie procesu transkodowania, a po jego zakończeniu plik zostanie przesłany na serwer w chmurze.
Niezadeklarowane formaty
Transkodowanie zgodnych multimediów jest włączone w przypadku wszystkich formatów, które są zadeklarowane jako nieobsługiwane, i wyłączone w przypadku wszystkich formatów, które są zadeklarowane jako obsługiwane. W przypadku innych formatów, które nie zostały zadeklarowane, platforma decyduje, czy transkodować, czy nie. W Androidzie 12 transkodowanie jest wyłączone w przypadku wszystkich niezadeklarowanych formatów. W przyszłości może się to zmienić w przypadku nowych formatów.
Opcje programisty
Aby zastąpić domyślne zachowanie transkodowania Androida, możesz użyć tych opcji programisty:
Zastąp domyślne ustawienia transkodowania To ustawienie określa, czy platforma kontroluje automatyczne transkodowanie. Gdy zastępowanie jest włączone, domyślne ustawienia platformy są ignorowane, a automatycznym transkodowaniem steruje ustawienie Włącz transkodowanie. Ta opcja jest domyślnie wyłączona.
Włącz transkodowanie To ustawienie określa, czy niezadeklarowane formaty są automatycznie transkodowane. Jest ona domyślnie włączona, ale działa tylko wtedy, gdy włączona jest też opcja Zastąp domyślne ustawienia transkodowania.
Zakładaj, że aplikacje obsługują nowoczesne formaty – to ustawienie określa, co się stanie, gdy aplikacja spróbuje odtworzyć niezadeklarowany format. Dzieje się tak, gdy plik manifestu nie deklaruje, czy aplikacja obsługuje dany format, lub gdy Google nie dodało aplikacji do listy wymuszonego transkodowania po stronie serwera. Gdy ustawienie jest włączone, aplikacja nie transkoduje, a gdy jest wyłączone, aplikacja transkoduje. Ta opcja jest domyślnie włączona.
Pokaż powiadomienia o transkodowaniu – gdy ta opcja jest włączona, aplikacja wyświetla powiadomienie o postępie transkodowania, gdy transkodowanie jest uruchamiane przez odczyt nieobsługiwanego pliku multimedialnego. Ta opcja jest domyślnie włączona.
Wyłącz pamięć podręczną transkodowania Jeśli ta opcja jest włączona, aplikacje wymagające transkodowania nie korzystają z pamięci podręcznej transkodowania. Może to być przydatne podczas programowania, aby łatwo uruchomić transkodowanie nieobsługiwanego pliku multimedialnego, ale może spowodować spadek wydajności urządzenia. Ta opcja jest domyślnie wyłączona.