Unter Android 12 (API‑Level 31) und höher kann das System automatisch Videos, die in Formaten wie HEVC (H.265) aufgenommen wurden, in AVC (H.264) konvertieren, wenn die Videos von einer App geöffnet werden, die HEVC nicht unterstützt. Mit dieser Funktion können Videoaufzeichnungs-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 |
HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |
HDR10+ | HDR10Plus | MediaFeature.HdrType.HDR10_PLUS |
Unter Android wird davon ausgegangen, dass Apps die Wiedergabe aller Mediaformate unterstützen. Daher ist die kompatible Media-Transcodierung standardmäßig deaktiviert.
Wann sollte transkodiert werden?
Die Transcodierung ist ein rechenintensiver Vorgang und führt zu einer erheblichen Verzögerung beim Öffnen einer Videodatei. Beispiel: Auf einem Pixel 3 dauert die Transcodierung einer einminütigen HEVC-Videodatei in AVC etwa 20 Sekunden. Aus diesem Grund sollten Sie eine Videodatei nur transkodieren, wenn Sie sie vom Gerät senden. Das kann beispielsweise der Fall sein, wenn Sie eine Videodatei für andere Nutzer derselben App oder für einen Cloudserver freigeben, der keine modernen Videoformate unterstützt.
Beim Öffnen von Videodateien für die Wiedergabe auf dem Gerät oder zum Erstellen von Miniaturansichten wird keine Transcodierung durchgeführt.
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 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 für bestimmte Codepfade, z. B. das Aufrufen des Transcodierens nur beim Übertragen einer Videodatei auf 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 kann die Transcodierung pauschal gesteuert werden. Diese Methode sollte nur in ganz bestimmten Fällen verwendet werden. Das ist beispielsweise der Fall, 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 Videocodecs unterstützt (siehe Beispiel 1 unten).
Wenn Sie diese Methode verwenden, obwohl es nicht unbedingt erforderlich ist, kann es zu einer Transcodierung in unerwarteten Szenarien kommen, z. B. beim Erstellen von Thumbnails für Videos. Dies kann die Nutzerfreundlichkeit beeinträchtigen.
Erstellen Sie zum Verwenden 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 aufgenommene HDR-Videos nahtlos in AVC-SDR-Videos (Standard Dynamic Range) transcodiert, HEVC-Videos jedoch nicht.
Verwenden Sie ein property
-Tag innerhalb des application
-Tags, 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" />
Videodatei mit den Media-Funktionen einer anderen App öffnen
Wenn Ihre App eine Videodatei mit einer anderen App teilt, muss die Videodatei möglicherweise transcodiert werden, bevor die empfangende App sie öffnen kann.
Sie können diesen Fall bearbeiten, indem Sie eine Videodatei mit openTypedAssetFileDescriptor
öffnen und die UID der empfangenden App angeben, die mit Binder.getCallingUid
abgerufen 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 veranschaulichen die beiden gängigen 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 Videoaufzeichnungs-App initiiert.
Die App zum Teilen von Videos deklariert, dass sie HEVC in ihrer Media-Capabilities-Ressourcendatei nicht unterstützt. Anschließend wird ein Video von der Videoaufzeichnungs-App angefordert. Die Videoaufzeichnungs-App verarbeitet die Anfrage und öffnet die Datei mit
openTypedAssetFileDescriptor
und gibt die UID der Freigabe-App an. 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 zum Teilen von Videos initiiert.
Die App zur Videoaufnahme 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 an, dass HEVC in den Media-Funktionen nicht unterstützt wird. Dadurch wird die Transcodierung gestartet. Nach Abschluss des Vorgangs wird die Datei auf einen Server in der Cloud hochgeladen.
Nicht deklarierte Formate
Die kompatible Medien-Transcodierung ist für alle Formate aktiviert, die als nicht unterstützt deklariert sind, und für alle Formate deaktiviert, die als unterstützt deklariert sind. Bei anderen Formaten, die nicht deklariert sind, entscheidet die Plattform, ob eine Transcodierung erfolgt. In 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 standardmäßige Transcodierungsverhalten von Android überschreiben:
Standardeinstellungen für Transcodierung überschreiben: Mit dieser Einstellung legen Sie fest, ob die Plattform die automatische Transcodierung steuert. Wenn die Überschreibung aktiviert ist, werden die Plattformstandardeinstellungen 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 die 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. Das passiert, wenn im Manifest nicht deklariert wird, ob die App ein bestimmtes Format unterstützt, oder wenn Google die App nicht der serverseitigen Liste für das Erzwingen der 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.
Benachrichtigungen zur Transcodierung 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, wird der Cache für die Transcodierung nicht für Apps verwendet, die eine Transcodierung erfordern. Das kann während der Entwicklung hilfreich sein, um die Transcodierung einer nicht unterstützten Mediendatei einfach auszulösen. Es kann jedoch zu einer schlechten Geräteleistung führen. Diese Option ist standardmäßig deaktiviert.