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 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 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 transcodiert werden:
| Medienformat | XML-Attribut | MediaFormat-MIME-Typ |
|---|---|---|
| HEVC (H.265) | HEVC | MediaFormat.MIMETYPE_VIDEO_HEVC |
| HDR10 | HDR10 | MediaFeature.HdrType.HDR10 |
| HDR10+ | HDR10Plus | MediaFeature.HdrType.HDR10_PLUS |
Android geht davon aus, dass Apps die Wiedergabe aller Medienformate unterstützen. Daher ist die Transcodierung in kompatible Medienformate 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 die Transcodierung einer einminütigen HEVC-Videodatei in AVC auf einem Pixel 3 etwa 20 Sekunden. Daher sollten Sie eine Videodatei nur dann transcodieren, wenn Sie sie vom Gerät senden. Beispielsweise, wenn eine Videodatei für andere Nutzer derselben App oder für einen Cloud-Server freigegeben wird, der moderne Videoformate nicht unterstützt.
Transcodieren Sie nicht, wenn Sie Videodateien für die Wiedergabe auf dem Gerät oder zum Erstellen von Miniaturansichten öffnen.
Transcodierung konfigurieren
Apps können das 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
Du kannst Medienfunktionen im Code deklarieren, indem du mit einem Builder eine Instanz eines ApplicationMediaCapabilities-Objekts erstellst:
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 der Transcodierung nur beim Übertragen einer Videodatei vom Gerät. Sie hat Vorrang vor der unten beschriebenen Methode.
Funktionen in einer Ressource deklarieren
Durch das Deklarieren von Funktionen in einer Ressource ist eine umfassende Kontrolle über die Transcodierung möglich. Diese Methode sollte nur in ganz bestimmten Fällen verwendet werden. Wenn Ihre App beispielsweise 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 Beispielszenario 1 unten).
Wenn Sie diese Methode verwenden, obwohl es nicht unbedingt erforderlich ist, kann es in unbeabsichtigten Szenarien zu einer Transcodierung kommen, z. B. beim Erstellen von Thumbnails für Videos. Dies kann die Nutzerfreundlichkeit beeinträchtigen.
Wenn Sie diese Methode verwenden möchten, erstellen Sie 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 Medienfunktionen hinzuzufügen. Fügen Sie Ihrer AndroidManifest.xml-Datei die folgenden Attribute hinzu:
<property
android:name="android.media.PROPERTY_MEDIA_CAPABILITIES"
android:resource="@xml/media_capabilities" />
Verwendung der Medienfunktionen einer anderen App zum Öffnen einer Videodatei
Wenn Ihre App eine Videodatei mit einer anderen App teilt, muss die Videodatei möglicherweise transcodiert werden, bevor die empfangende App sie öffnen kann.
In diesem Fall können Sie eine Videodatei mit openTypedAssetFileDescriptor öffnen und die UID der empfangenden App angeben, die Sie mit Binder.getCallingUid abrufen können.
Die Plattform verwendet dann die Medienfunktionen 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 in ihrer Ressourcendatei für Medienfunktionen, dass sie HEVC 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, wobei die UID der App angegeben wird, die die Datei freigibt. Dadurch wird der Transcodierungsprozess gestartet.
Wenn das transcodierte Video empfangen wird, wird es an die App zum Teilen weitergeleitet, 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 in ihren Medienfunktionen 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 Transcodierung in kompatible Medienformate 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 sie transcodiert werden sollen oder nicht. 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 Standard-Transcodierungsverhalten von Android überschreiben:
Standardeinstellungen für die Transcodierung überschreiben: Mit dieser Einstellung wird festgelegt, ob die automatische Transcodierung von der Plattform gesteuert wird. Wenn das Überschreiben aktiviert ist, werden die Plattformstandards 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 dann Auswirkungen, wenn auch Transcodierungs-Standardeinstellungen überschreiben aktiviert ist.
Annehmen, 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 angegeben ist, ob die App ein bestimmtes Format unterstützt, oder wenn Google die App nicht zur serverseitigen Liste für die erzwungene Transcodierung hinzugefügt hat. Wenn die Einstellung aktiviert ist, transcodiert die App nicht. Wenn sie deaktiviert ist, transcodiert die App. 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.
Transcodierungs-Cache deaktivieren: Wenn diese Option aktiviert ist, verwenden Apps, die eine Transcodierung erfordern, nicht den Transcodierungs-Cache. Das kann während der Entwicklung hilfreich sein, um die Transcodierung einer nicht unterstützten Mediendatei einfach auszulösen, kann aber zu einer schlechten Geräteleistung führen. Diese Option ist standardmäßig deaktiviert.