Transcodierung kompatibler Medien

Unter Android 12 (API-Level 31) und höher kann das System Videos, die in Formaten wie HEVC (H.265) aufgezeichnet wurden, automatisch in AVC (H.264) konvertieren, wenn die Videos von einer App geöffnet werden, die HEVC nicht unterstützt. Mit dieser Funktion können Videoaufnahme-Apps eine moderne, speichereffiziente Codierung von Videos verwenden, die mit dem Gerät aufgenommen wurden, ohne die Kompatibilität mit anderen Apps zu beeinträchtigen.

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

Medienformat XML-Attribut MediaFormat-MIME-Typ
HEVC (H.265) 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 können. Daher ist die Transcodierung kompatibler Medien standardmäßig deaktiviert.

Wann die Transcodierung verwendet werden sollte

Das Transcodieren ist ein rechenintensiver Vorgang und führt zu einer erheblichen Verzögerung beim Öffnen einer Videodatei. Beispielsweise dauert die Transcodierung einer einminütigen HEVC-Videodatei in AVC auf einem Pixel 3 etwa 20 Sekunden. Daher solltest du eine Videodatei nur dann 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, der keine modernen Videoformate unterstützt.

Transcodieren Sie keine Dateien, wenn Sie Videodateien zur Wiedergabe auf dem Gerät oder zum Erstellen von Miniaturansichten öffnen.

Transcodierung konfigurieren

Apps können ihr Transcodierungsverhalten steuern, indem sie ihre Medienfunktionen deklarieren. 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 mit 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 beim Übertragen einer Videodatei an ein anderes Gerät. Sie hat Vorrang vor der unten beschriebenen Methode.

Funktionen in einer Ressource deklarieren

Durch das Deklarieren von Funktionen in einer Ressource haben Sie die volle Kontrolle über die Transcodierung. Diese Methode sollte nur in sehr spezifischen Fällen verwendet werden. Beispiel: Ihre App empfängt Videodateien von anderen Anwendungen, anstatt sie direkt zu ö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 es passieren, dass die Transcodierung in unbeabsichtigten Szenarien ausgelöst wird, z. B. beim Thumbnail-Bilden von Videos, was die Nutzererfahrung beeinträchtigt.

Erstellen Sie eine media_capabilities.xml-Ressourcendatei, um diese Methode zu verwenden:

<?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 aufgenommene HDR-Videos nahtlos in AVC-SDR-Videos (Standard Dynamic Range) transcodiert, HEVC-Videos jedoch nicht.

Verwende ein property-Tag innerhalb des application-Tags, um der Datei mit den Medienfunktionen einen Verweis 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" />

Verwenden der Medienfunktionen einer anderen App zum Öffnen einer Videodatei

Wenn Ihre App eine Videodatei für eine andere App freigibt, muss die Videodatei möglicherweise erst transcodiert werden, bevor sie von der empfangenden App geöffnet werden kann.

In diesem Fall können Sie eine Videodatei mit openTypedAssetFileDescriptor öffnen und die UID der empfangenden App angeben. Diese erhalten Sie mit Binder.getCallingUid. Die Plattform ermittelt dann anhand der Medienfunktionen der empfangenden App, ob die Videodatei transcodiert 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

Die folgenden Diagramme zeigen die beiden häufigsten Anwendungsfälle. 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 eingeleitet. Beispiel 1 Die App zum Teilen von Videos gibt in der Ressourcendatei für Medienfunktionen an, dass sie HEVC nicht unterstützt. Anschließend wird ein Video von der Videoaufnahme-App angefordert. Die Videoaufnahme-App verarbeitet die Anfrage und öffnet die Datei mit openTypedAssetFileDescriptor, wobei die UID der Freigabe-App angegeben wird. Dadurch wird der Transcodierungsprozess gestartet. Wenn das transcodierte Video empfangen wird, wird es der Freigabe-App bereitgestellt, die es auf einen Server in der Cloud hochlädt.

Beispiel 2: Die Transcodierung wird von einer App zum Teilen von Videos initiiert. Beispiel 2 Die App zur Videoaufnahme teilt ein Video über einen MediaStore-URI mit der App zum Teilen von Videos. Die App zum Teilen von Videos öffnet die Videodatei mit openTypedAssetFileDescriptor und gibt an, dass HEVC in den Medienfunktionen nicht unterstützt wird. Dadurch wird der Transcodierungsprozess gestartet. Sobald die Datei abgeschlossen ist, wird sie auf einen Server in der Cloud hochgeladen.

Nicht deklarierte Formate

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

Entwickleroptionen

Mit den folgenden Entwickleroptionen kannst du das Standard-Transcodierungsverhalten 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 wird angegeben, ob nicht deklarierte Formate automatisch transcodiert werden. Es ist standardmäßig aktiviert, hat aber nur dann eine Auswirkung, wenn Standardeinstellungen für Transcodierung überschreiben ebenfalls aktiviert ist.

  • Angenommen, Anwendungen unterstützen moderne Formate Mit dieser Einstellung wird festgelegt, was passiert, wenn die Anwendung versucht, ein nicht deklariertes Format wiederzugeben. Dies ist der Fall, wenn im Manifest nicht angegeben ist, ob die App ein bestimmtes Format unterstützt oder nicht, oder Google die App nicht der serverseitigen Liste mit erzwungenen Transcodierungen hinzugefügt hat. Ist die Einstellung aktiviert, transcodiert die App nicht, ist sie deaktiviert, wird sie transcodiert. Diese Option ist standardmäßig aktiviert.

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

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