Transcodierung in kompatibles Medienformat

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

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

Media-Format XML-Attribut MIME-Typ von MediaFormat
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 Media-Formate unterstützen. Daher ist die kompatible Media-Transcodierung standardmäßig deaktiviert.

Wann sollte die Transcodierung verwendet werden?

Die Transcodierung ist ein rechenintensiver Vorgang und führt zu einer erheblichen Verzögerung beim Öffnen einer Videodatei. Beispielsweise dauert es auf einem Pixel 3-Smartphone etwa 20 Sekunden, eine einminütige HEVC-Videodatei in AVC zu transcodieren. Aus diesem Grund sollten Sie eine Videodatei nur transcodieren, wenn Sie sie vom Gerät senden. Beispielsweise beim Teilen einer Videodatei mit anderen Nutzern derselben App oder mit einem Cloud-Server, der keine modernen Videoformate unterstützt.

Transcodieren Sie keine Videodateien, wenn Sie sie auf dem Gerät wiedergeben oder Miniaturansichten erstellen möchten.

Transcodierung konfigurieren

Apps können ihr Transcodierungsverhalten steuern, indem sie ihre Media-Funktionen deklarieren. Es gibt zwei Möglichkeiten, diese Funktionen zu deklarieren: im Code oder in einer Ressource.

Funktionen im Code deklarieren

Sie können Media-Funktionen 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 Media-Inhalte 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.
}

Mit dieser Methode können Sie die Transcodierung für bestimmte Codepfade detailliert steuern, z. B. nur dann aufrufen, wenn eine Videodatei vom Gerät übertragen wird. Sie hat Vorrang vor der unten beschriebenen Methode.

Funktionen in einer Ressource deklarieren

Wenn Sie Funktionen in einer Ressource deklarieren, können Sie die Transcodierung umfassend steuern. Diese Methode sollte nur in sehr spezifischen Fällen verwendet werden. Beispielsweise wenn Ihre App nur Videodateien von anderen Apps empfängt (anstatt sie direkt zu öffnen) und sie auf einen Server hochlädt, der keine modernen Video-Codecs unterstützt (siehe Beispielszenario 1 unten).

Wenn Sie diese Methode verwenden, obwohl sie nicht unbedingt erforderlich ist, kann die Transcodierung in unerwarteten Szenarien aufgerufen werden, z. B. beim Erstellen von Miniaturansichten von Videos. Dies kann die Nutzerfreundlichkeit beeinträchtigen.

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 HDR-Videos, die auf dem Gerät aufgenommen wurden, nahtlos in AVC-SDR-Videos (Standard Dynamic Range) transcodiert, HEVC-Videos jedoch nicht.

Verwenden Sie ein property-Tag im application-Tag, um einen Verweis auf die Datei mit den Media-Funktionen hinzuzufügen. Fügen Sie diese Attribute der Datei AndroidManifest.xml hinzu:

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

Media-Funktionen einer anderen App zum Öffnen einer Videodatei verwenden

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

Sie können diesen Fall verarbeiten, indem Sie eine Videodatei mit openTypedAssetFileDescriptor öffnen und die UID der empfangenden App angeben, die mit Binder.getCallingUidabgerufen werden kann. Die Plattform verwendet dann die Media-Funktionen der empfangenden App, um zu bestimmen, 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 initiiert. Beispiel 1 Die App zum Teilen von Videos deklariert in ihrer Ressourcendatei mit den Media Funktionen, dass sie HEVC nicht unterstützt. Anschließend fordert sie ein Video von der Videoaufnahme-App an. Die Videoaufnahme App verarbeitet die Anfrage und öffnet die Datei mit openTypedAssetFileDescriptor. Dabei wird die UID der App zum Teilen angegeben. Dadurch wird der Transcodierungsprozess gestartet. Wenn das transcodierte Video empfangen wird, wird es an die App zum Teilen gesendet, die es auf einen Server in der Cloud hochlädt.

Beispiel 2 Die Transcodierung wird von der App zum Teilen von Videos initiiert. Beispiel 2 Die Videoaufnahme-App teilt ein Video mit der App zum Teilen von Videos über einen MediaStore URI. Die App zum Teilen von Videos öffnet die Videodatei mit openTypedAssetFileDescriptor und gibt in ihren Media-Funktionen an, dass sie HEVC nicht unterstützt. Dadurch wird der Transcodierungsprozess gestartet. Nach Abschluss wird die Datei auf einen Server in der Cloud hochgeladen.

Nicht deklarierte Formate

Die kompatible Media-Transcodierung ist für alle Formate aktiviert, die als nicht unterstützt deklariert wurden, und für alle Formate deaktiviert, die als unterstützt deklariert wurden. Bei anderen Formaten, die nicht deklariert wurden, entscheidet die Plattform, ob sie transcodiert werden sollen. Unter Android 12 ist die Transcodierung für alle nicht deklarierten Formate deaktiviert. Dieses Verhalten kann sich in Zukunft für neue Formate ändern.

Entwickleroptionen

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

  • Standardeinstellungen für 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 festgelegt, ob nicht deklarierte Formate automatisch transcodiert werden. Sie ist standardmäßig aktiviert, hat aber nur Auswirkungen, wenn auch Standardeinstellungen für Transcodierung überschreiben aktiviert ist.

  • Voraussetzen, dass Apps moderne Formate unterstützen Mit dieser Einstellung wird festgelegt, was passiert, wenn die App versucht, ein nicht deklariertes Format abzuspielen. Dies geschieht, wenn im Manifest nicht deklariert ist, ob die App ein bestimmtes Format unterstützt, oder wenn Google die App nicht der serverseitigen Liste für die erzwungene Transcodierung hinzugefügt hat. Wenn die Einstellung aktiviert ist, wird die App nicht transcodiert. Wenn sie deaktiviert ist, wird die App transcodiert. Diese Option ist standardmäßig aktiviert.

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

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