Transkodowanie zgodnych multimediów

W Androidzie 12 (poziom interfejsu API 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 w aplikacji, która nie obsługuje HEVC. Ta funkcja umożliwia aplikacjom do nagrywania filmów bardziej nowoczesne, oszczędzające miejsce na dane kodowania filmów nagranych na urządzeniu, bez negatywnego wpływu na zgodność z innymi aplikacjami.

W przypadku treści tworzonych na urządzeniu te formaty mogą być automatycznie transkodowane:

Format multimediów Atrybut XML Typ MIME MediaFormat
HEVC (H.265) protokół 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 transkodowanie zgodnych multimediów jest domyślnie wyłączone.

Kiedy stosować transkodowanie

Transkodowanie to kosztowny technicznie proces, który znacznie opóźnia otwieranie pliku wideo. Na przykład transkodowanie jednominutowego pliku wideo HEVC na telefonie Pixel 3 zajmuje około 20 sekund na format AVC. Dlatego musisz transkodować plik wideo tylko wtedy, gdy wysyłasz go poza urządzenie. np. gdy udostępniasz plik wideo innym użytkownikom tej samej aplikacji lub serwer w chmurze, który nie obsługuje nowoczesnych formatów wideo.

Nie transkoduj podczas otwierania plików wideo na potrzeby odtwarzania na urządzeniu lub do tworzenia miniatur.

Konfigurowanie transkodowania

Aplikacje mogą kontrolować działanie transkodowania, deklarując dostępne funkcje multimedialne. Te uprawnienia możesz zadeklarować na 2 sposoby: 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ę obiektu ApplicationMediaCapabilities za pomocą konstruktora:

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 chcesz uzyskiwać 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, na przykład wywoływanie transkodowania tylko w przypadku 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 ściśle określonych przypadkach. Dzieje się tak na przykład wtedy, gdy aplikacja otrzymuje pliki wideo tylko z innych aplikacji (a nie bezpośrednio) i przesyła je na serwer, który nie obsługuje nowoczesnych kodeków (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ą płynnie transkodowane na pliki AVC SDR (standardowy zakres dynamiki), a filmy HEVC nie.

Aby dodać odwołanie do pliku funkcji multimedialnych, umieść w tagu application tag property. 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 transkodowanie tego pliku, zanim aplikacja odbierająca będzie mogła go otworzyć.

W tym przypadku otwórz plik wideo za pomocą narzędzia openTypedAssetFileDescriptor i podaj identyfikator UID aplikacji odbierającej, który można uzyskać za pomocą Binder.getCallingUid. Następnie platforma korzysta z możliwości multimedialnych aplikacji odbierającej, aby określić, czy należy transkodować plik wideo.

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

Poniższe diagramy ilustrują 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 nagrywania wideo. Przykład 1 Aplikacja do udostępniania wideo deklaruje, że nie obsługuje HEVC w pliku zasobów funkcji multimediów. Następnie wysyła żądanie udostępnienia filmu do aplikacji do nagrywania filmów. Aplikacja do nagrywania filmów obsługuje to żądanie i otwiera plik za pomocą polecenia openTypedAssetFileDescriptor, który określa 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ą identyfikatora URI MediaStore. Aplikacja do udostępniania wideo otwiera plik wideo za pomocą narzędzia openTypedAssetFileDescriptor, wskazując, że nie obsługuje on HEVC w ramach funkcji multimediów. Rozpoczyna to proces transkodowania, a po jego zakończeniu plik jest przesyłany na serwer w chmurze.

Niezadeklarowane formaty

Zgodne transkodowanie multimediów jest włączone w przypadku wszystkich formatów, które zostały zadeklarowane jako nieobsługiwane, i wyłączone w przypadku wszystkich zadeklarowanych obsługiwanych formatów. W przypadku innych formatów, które nie są zadeklarowane, platforma decyduje, czy transkodować czy nie. Na Androidzie 12 transkodowanie jest wyłączone w przypadku wszystkich niezadeklarowanych formatów. W przyszłości może to się zmienić w przypadku nowych formatów.

Opcje programisty

Możesz użyć tych opcji dla programistów, aby zastąpić domyślne działanie transkodowania Androida:

  • 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 ustawienie włącz transkodowanie kontroluje automatyczne transkodowanie. Domyślnie ta opcja jest wyłączona.

  • Włącz transkodowanie to ustawienie określa, czy niezadeklarowane formaty są transkodowane automatycznie. Jest ona domyślnie włączona, ale działa 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ć niezadeklarowany format. Dzieje się tak, gdy plik manifestu nie określa, czy aplikacja obsługuje dany format, lub gdy Google nie dodał aplikacji do listy wymuszonych transkodowania po stronie serwera. Gdy to ustawienie jest włączone, aplikacja nie transkoduje treści, a gdy jest wyłączone, aplikacja transkoduje. Ta opcja jest domyślnie włączona.

  • Pokaż powiadomienia transkodowania, gdy ta opcja jest włączona, aplikacja wyświetla powiadomienie o postępie transkodowania po aktywowaniu transkodowania przez odczytanie nieobsługiwanego pliku multimedialnego. Ta opcja jest domyślnie włączona.

  • Wyłącz pamięć podręczną transkodowania Gdy ta opcja jest włączona, aplikacje wymagające transkodowania nie korzystają z pamięci podręcznej transkodowania. Może to być pomocne podczas programowania, gdy zechcesz łatwo aktywować transkodowanie w nieobsługiwanym pliku multimedialnym, ale może też obniżyć wydajność urządzenia. Domyślnie ta opcja jest wyłączona.