W 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 kodowania, które pozwala zaoszczędzić miejsce na urządzeniu, bez utraty zgodności z innymi aplikacjami.
W przypadku treści utworzonych na urządzeniu można automatycznie przekodować 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, więc domyślnie transkodowanie zgodnych multimediów jest wyłączone.
Kiedy używać transkodowania
Transkodowanie to operacja wymagająca dużych zasobów obliczeniowych, która znacznie wydłuża czas otwierania pliku wideo. Na przykład konwersja minutowego pliku wideo HEVC na AVC na telefonie Pixel 3 trwa około 20 sekund. Dlatego plik wideo powinieneś przekonwertować 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 plików wideo, które mają być odtwarzane na urządzeniu lub służyć do tworzenia miniatur.
Konfigurowanie transkodowania
Aplikacje mogą kontrolować sposób transkodowania, deklarując swoje możliwości multimedialne. Te możliwości można zadeklarować na 2 sposoby: w kodzie lub w zasobach.
Deklarowanie możliwości w kodzie
Aby zadeklarować możliwości mediów w kodzie, utwórz 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ą takich metod 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 określonymi ścieżkami kodu, np. wywoływanie transkodowania tylko podczas przenoszenia pliku wideo poza urządzenie. Ma ona pierwszeństwo przed metodą opisaną poniżej.
Deklarowanie możliwości w zasobach
Zadeklarowanie możliwości w zasobach umożliwia ogólną kontrolę nad transkodowaniem. Tej metody należy używać tylko w bardzo szczególnych przypadkach. Jeśli na przykład Twoja aplikacja: otrzymuje tylko 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).
Korzystanie z tej metody, gdy nie jest to absolutnie konieczne, może spowodować przekodowanie w nieprzewidzianych sytuacjach, takich jak tworzenie miniatur filmów, co może pogorszyć wrażenia użytkownika.
Aby użyć tej metody, utwórz plik zasobu 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ą bezproblemowo konwertowane na filmy AVC SDR (standardowy zakres dynamiki), ale nie HEVC.
Aby dodać odwołanie do pliku z możliwościami multimediów, użyj tagu property
w tagu application
. 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 przekodowanie pliku wideo, zanim aplikacja odbiorcza będzie mogła go otworzyć.
Aby rozwiązać ten problem, otwórz plik wideo za pomocą openTypedAssetFileDescriptor
i wskaż identyfikator UID aplikacji odbiorczej, który możesz uzyskać za pomocą Binder.getCallingUid
.
Następnie platforma korzysta z funkcji multimedialnych aplikacji odbiorcy, aby określić, czy plik wideo powinien zostać przekodowany.
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 HEVC.
Przykład 1. Transkodowanie jest inicjowane przez aplikację do przechwytywania wideo.
Aplikacja do udostępniania filmów deklaruje w pliku z zasobami multimedialnymi, że nie obsługuje 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 do udostępniania. Spowoduje to rozpoczęcie procesu transkodowania.
Gdy otrzymamy transkodowany film, przekazujemy go 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 formatu HEVC. Spowoduje to zainicjowanie procesu transkodowania, a po jego zakończeniu plik zostanie przesłany na serwer w chmurze.
Niedeklarowane formaty
Transkodowanie kompatybilnych 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 niedeklarowanych formatów platforma sama decyduje, czy dokonać transkodowania. 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 w Androidzie, możesz użyć tych opcji dla programistów:
Zastąp domyślne ustawienia transkodowania – to ustawienie określa, czy platforma ma kontrolować automatyczne transkodowanie. Gdy zastąpienie jest włączone, ustawienia domyślne platformy są ignorowane, a ustawienie włącz transkodowanie kontroluje automatyczne transkodowanie. Ta opcja jest domyślnie wyłączona.
Włącz transkodowanie – to ustawienie określa, czy niedeklarowane formaty mają być automatycznie transkodowane. Jest ona domyślnie włączona, ale ma zastosowanie tylko wtedy, gdy włączona jest też opcja zastępowania domyślnych ustawień transkodowania.
Zakładaj, że aplikacje obsługują nowoczesne formaty – to ustawienie określa, co się dzieje, gdy aplikacja próbuje odtworzyć niedeklarowany format. Dzieje się tak, gdy manifest nie określa, czy aplikacja obsługuje dany format, lub gdy Google nie dodała aplikacji do listy wymuszania transkodowania po stronie serwera. Gdy to ustawienie jest włączone, aplikacja nie transkoduje, a gdy jest wyłączone, transkoduje. Ta opcja jest domyślnie włączona.
Pokaż powiadomienia o transkodowaniu – gdy ta opcja jest włączona, aplikacja wyświetla powiadomienie o postępach transkodowania, gdy transkodowanie jest wywoływane przez odczytanie 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 tworzenia, aby łatwo wywołać transkodowanie nieobsługiwanego pliku multimedialnego, ale może to spowodować pogorszenie wydajności urządzenia. Domyślnie ta opcja jest wyłączona.