Transcodierung kompatibler Medien

Unter Android 12 (API-Level 31) und höher können Videos, die in Formaten wie HEVC (H.265) aufgenommen wurden, automatisch in AVC (H.264) konvertiert werden, wenn die Videos von einer App geöffnet werden, die HEVC nicht unterstützt. Mit dieser Funktion können Apps zur Videoaufnahme eine modernere, speichereffiziente Codierung für Videos verwenden, die auf dem Gerät aufgenommen wurden, ohne dass die Kompatibilität mit anderen Apps beeinträchtigt wird.

Die folgenden Formate können für Inhalte, die auf dem Gerät erstellt werden, automatisch transkodiert werden:

Medienformat XML-Attribut MediaFormat-MIME-Typ
HEVC (H.265) Logo: HEVC MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 MediaFeature.HdrType.HDR10
HDR10+ HDR10Plus MediaFeature.HdrType.HDR10_PLUS

Android geht davon aus, dass Apps die Wiedergabe aller Medienformate unterstützen. Daher ist die kompatible Medientranscodierung standardmäßig deaktiviert.

Wann sollte die Transcodierung verwendet werden?

Das Transcodieren ist ein rechenintensiver Vorgang und führt beim Öffnen einer Videodatei zu erheblichen Verzögerungen. Beispielsweise dauert die Transcodierung einer einminütigen HEVC-Videodatei auf einem Pixel 3 etwa 20 Sekunden in AVC. Aus diesem Grund solltest du eine Videodatei nur transcodieren, wenn du sie vom Gerät sendest. Dies ist beispielsweise der Fall, wenn Sie eine Videodatei für andere Nutzer derselben Anwendung freigeben oder einen Cloud-Server verwenden, der keine modernen Videoformate unterstützt.

Nicht transcodieren, wenn Videodateien für die Wiedergabe auf dem Gerät oder zum Erstellen von Miniaturansichten geöffnet werden

Transcodierung konfigurieren

Anwendungen können ihr Transcodierungsverhalten durch Deklarieren ihrer Medienfunktionen steuern. Es gibt zwei Möglichkeiten, diese Funktionen zu deklarieren: im Code oder in einer Ressource.

Funktionen im Code deklarieren

Sie können Medienfunktionen im Code deklarieren, indem Sie mit einem Builder eine Instanz eines ApplicationMediaCapabilities-Objekts erstellen:

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();

Verwenden Sie dieses Objekt, wenn Sie über Methoden wie ContentResolver#openTypedAssetFileDescriptor() auf Medieninhalte zugreifen:

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.
}

Diese Methode ermöglicht eine detaillierte Steuerung bestimmter Codepfade, z. B. das Aufrufen der Transcodierung nur dann, wenn eine Videodatei vom Gerät übertragen wird. Sie hat Vorrang vor der unten beschriebenen Methode.

Funktionen in einer Ressource deklarieren

Die Deklaration von Funktionen in einer Ressource ermöglicht die pauschale Kontrolle über die Transcodierung. Diese Methode sollte nur in sehr speziellen Fällen verwendet werden. Beispiel: Ihre App empfängt Videodateien von anderen Apps (statt sie nicht direkt öffnen) und lädt sie auf einen Server hoch, der keine modernen Video-Codecs unterstützt (siehe Beispielszenario 1 unten).

Wenn diese Methode nicht unbedingt erforderlich ist, kann dies in unbeabsichtigten Szenarien, z. B. beim Thumbnail von Videos, dazu führen, dass die Nutzerfreundlichkeit beeinträchtigt wird.

Erstellen Sie zur Verwendung dieser Methode eine media_capabilities.xml-Ressourcendatei:

<?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>

In diesem Beispiel werden auf dem Gerät aufgezeichnete HDR-Videos nahtlos in ACC-SDR-Videos (Standard Dynamic Range) umgewandelt, HEVC-Videos jedoch nicht.

Verwenden Sie ein property-Tag innerhalb des application-Tags, um einen Verweis auf die Datei mit Medienfunktionen hinzuzufügen. Fügen Sie der Datei AndroidManifest.xml diese Attribute hinzu:

<property
    android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
    android:resource="@xml/media_capabilities" />

Öffnen einer Videodatei mithilfe der Medienfunktionen einer anderen App

Wenn Ihre App eine Videodatei für eine andere App freigibt, muss die Videodatei möglicherweise transkodiert werden, bevor die empfangende App sie öffnen kann.

Sie können in diesem Fall eine Videodatei mit openTypedAssetFileDescriptor öffnen und die UID der empfangenden Anwendung angeben, die Sie mit Binder.getCallingUid abrufen können. Die Plattform bestimmt dann anhand der Medienfunktionen der empfangenden App, ob die Videodatei transkodiert werden soll.

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.
}

Beispielszenarien

In den folgenden Diagrammen werden die beiden häufigsten Anwendungsfälle veranschaulicht. In beiden Fällen wird das Originalvideo im HEVC-Format gespeichert und die App zum Teilen von Videos unterstützt HEVC nicht.

Beispiel 1: Die Transcodierung wird von der Videoaufnahme-App initiiert. Beispiel 1 Die App zur Videofreigabe gibt in ihrer Ressourcendatei für Medienfunktionen an, dass sie HEVC nicht unterstützt. Anschließend fordert sie ein Video von der Anwendung zur Videoaufnahme an. Diese verarbeitet die Anfrage und öffnet die Datei mit openTypedAssetFileDescriptor unter Angabe der UID der Freigabe-App. Dadurch wird der Transcodierungsprozess gestartet. Wenn das transcodierte Video empfangen wird, wird es an die Freigabe-App gesendet, die es auf einen Server in der Cloud hochlädt.

Beispiel 2: Die Transcodierung wird von der App zur Videofreigabe initiiert. Beispiel 2 Die App zur Videoaufnahme gibt über den URI MediaStore ein Video an die App zum Teilen von Videos weiter. Die App zur Freigabe von Videos öffnet die Videodatei über openTypedAssetFileDescriptor. Dabei wird angegeben, dass HEVC für die Medienfunktionen nicht unterstützt wird. Dadurch wird der Transcodierungsprozess initiiert. Wenn der Vorgang abgeschlossen ist, wird die Datei auf einen Server in der Cloud hochgeladen.

Nicht deklarierte Formate

Die Transcodierung von kompatiblen Medien ist für alle Formate aktiviert, die als nicht unterstützt deklariert werden, und deaktiviert für alle Formate, die als unterstützt deklariert werden. Bei anderen nicht deklarierten Formaten entscheidet die Plattform, ob eine Transcodierung stattfindet oder nicht. In Android 12 ist die Transcodierung für alle nicht deklarierten Formate deaktiviert. Dieses Verhalten kann sich in Zukunft bei neuen Formaten ändern.

Entwickleroptionen

Mit den folgenden Entwickleroptionen können Sie das Standardverhalten für die Transcodierung von Android überschreiben:

  • Standardeinstellungen für die Transcodierung überschreiben: Mit dieser Einstellung wird festgelegt, ob die Plattform die automatische Transcodierung steuert. Wenn die Überschreibung aktiviert ist, werden die Standardeinstellungen der Plattform ignoriert und die Einstellung Transcodierung aktivieren steuert die automatische Transcodierung. Diese Option ist standardmäßig deaktiviert.

  • Transcodierung aktivieren Mit dieser Einstellung können Sie festlegen, ob nicht deklarierte Formate automatisch transkodiert werden. Sie ist standardmäßig aktiviert, wirkt sich aber nur aus, wenn auch Standardeinstellungen für Transcodierung überschreiben aktiviert ist.

  • Angenommen, Apps unterstützen moderne Formate Mit dieser Einstellung wird festgelegt, was passiert, wenn die App versucht, ein nicht deklariertes Format wiederzugeben. Dies geschieht, wenn im Manifest nicht angegeben ist, ob die App ein bestimmtes Format unterstützt, oder wenn Google die App nicht zur serverseitigen Liste der erzwungenen Transcodierungen hinzugefügt hat. Wenn diese Einstellung aktiviert ist, führt die App keine Transcodierung durch. Ist sie deaktiviert, erfolgt die Transcodierung in der App. Diese Option ist standardmäßig aktiviert.

  • Benachrichtigungen zur Transcodierung anzeigen: Wenn diese Option aktiviert ist, zeigt die Anwendung eine Benachrichtigung über den Fortschritt der Transcodierung an, wenn die Transcodierung durch Lesen einer nicht unterstützten Mediendatei ausgelöst wird. Diese Option ist standardmäßig aktiviert.

  • Transcodierungs-Cache deaktivieren: Wenn diese Option aktiviert ist, verwenden Anwendungen, die eine Transcodierung erfordern, den Transcodierungs-Cache nicht. Das kann während der Entwicklung hilfreich sein, um die Transcodierung für eine nicht unterstützte Mediendatei auszulösen, gleichzeitig aber zu einer schlechten Geräteleistung führen. Diese Option ist standardmäßig deaktiviert.