Transkodowanie zgodnych multimediów

W Androidzie 12 (API na poziomie 31) lub nowszym 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 nagrywanie filmów Przechwytywać aplikacje, aby móc korzystać z nowoczesnego kodowania filmów, oszczędzającego pamięć nagrane na urządzeniu bez negatywnego wpływu na zgodność z innymi aplikacjami.

Poniższe formaty mogą być automatycznie transkodowane w przypadku treści utworzone na urządzeniu:

Format multimediów Atrybut XML Typ MIME MediaFormat
HEVC (H.265) HEVC MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 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 jednominutowy plik wideo HEVC około 20 sekund na transkodowanie na AVC na telefonie Pixel 3. Z tego powodu pliku wideo należy transkodować tylko wtedy, gdy przesyłasz go 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ć działanie transkodowania, deklarując multimedia funkcje zabezpieczeń. Są 2 sposoby zadeklarowania tych funkcji: w kodzie lub w zasobie.

Deklarowanie możliwości w kodzie

Możesz zadeklarować możliwości związane z multimediami w kodzie, tworząc instancję Obiekt ApplicationMediaCapabilities za pomocą konstruktora:

KotlinJava
val mediaCapabilities = ApplicationMediaCapabilities.Builder()
    .addSupportedVideoMimeType(MediaFormat.MIMETYPE_VIDEO_HEVC)
    .addUnsupportedHdrType(MediaFeature.HdrType.HDR10)
    .addUnsupportedHdrType(MediaFeature.HdrType.HDR10_PLUS)
    .build()
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():

KotlinJava
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.
    }
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ę określonych ścieżek kodu, takich jak jako wywoływania transkodowania tylko podczas przesyłania pliku wideo poza urządzenie. Ma ona pierwszeństwo przed metodą opisaną poniżej.

Deklarowanie możliwości zasobu

Zadeklarowanie możliwości w zasobie pozwala na ogólną kontrolę transkodowania. 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).

Używanie tej metody, gdy nie jest absolutnie konieczne, może spowodować transkodowanie w niezamierzonych sytuacjach, np. przy miniaturze filmów, co pogarsza wrażenia użytkowników.

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ą bezproblemowo konwertowane na filmy AVC SDR (standardowy zakres dynamiki), ale nie HEVC.

Aby dodać odwołanie do pliku z danymi o możliwościach obsługi 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ć.

W tej sytuacji możesz otworzyć plik wideo za pomocą narzędzia openTypedAssetFileDescriptor i określić identyfikator UID aplikacji odbierającej, który można uzyskać za pomocą Binder.getCallingUid. Następnie platforma korzysta z funkcji multimedialnych aplikacji odbiorcy, aby określić, czy plik wideo powinien zostać przekodowany.

KotlinJava
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.
    }
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 i obsługują HEVC.

Przykład 1. Transkodowanie jest inicjowane przez aplikację do przechwytywania wideo. Przykład 1 Aplikacja do udostępniania filmów deklaruje w pliku z zasobami multimedialnymi, że nie obsługuje HEVC. Następnie wysyła żądanie filmu do aplikacji do przechwytywania wideo. Aplikacja do przechwytywania wideo obsługuje żądanie i otwiera plik za pomocą openTypedAssetFileDescriptor, podając identyfikator UID aplikacji do udostępniania. Rozpocznie się proces transkodowania. Po transkodowaniu film jest dostarczany 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. Przykład 2 Aplikacja do nagrywania filmów udostępnia film aplikacji do udostępniania filmów za pomocą Identyfikator URI MediaStore. Aplikacja do udostępniania filmów otwiera plik wideo za pomocą openTypedAssetFileDescriptor, określając, że nie obsługuje formatu HEVC. Ten rozpoczyna proces transkodowania. Po jego zakończeniu plik jest przesyłany do z serwerem w chmurze.

Niezadeklarowane formaty

Transkodowanie kompatybilnych multimediów jest włączone w przypadku wszystkich formatów, które są zadeklarowane jako niedostępne, i wyłączone w przypadku wszystkich formatów, które są zadeklarowane jako dostępne. W przypadku innych niedeklarowanych formatów platforma sama decyduje, czy przekodować plik. 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 a platforma kontroluje automatyczne transkodowanie. Gdy zastąpienie jest włączone, domyślne ustawienia 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 nie zadeklarowano są automatycznie transkodowane. Jest ona domyślnie włączona, ale tylko działa, jeśli jest też włączone zastępowanie 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 ustawienie jest włączona, aplikacja nie transkoduje, a gdy jest wyłączona, po transkodowaniu. Ta opcja jest domyślnie włączona.

  • Pokaż powiadomienia transkodowania Po włączeniu tej opcji aplikacja wyświetla powiadomienie o postępie transkodowania po aktywowaniu transkodowania przez odczytanie nieobsługiwany plik multimedialny. 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.