Transcodage de contenus multimédias dans un format compatible

Sur Android 12 (niveau d'API 31) ou version ultérieure, le système peut convertir automatiquement des vidéos enregistrées dans des formats tels que HEVC (H.265) au format AVC (H.264) lorsque les vidéos sont ouvertes par une application non compatible avec HEVC. Cette fonctionnalité permet aux applications de capture vidéo d'utiliser un encodage plus moderne et plus économe en stockage pour les vidéos enregistrées sur l'appareil sans sacrifier la compatibilité avec d'autres applications.

Les formats suivants peuvent être transcodés automatiquement pour le contenu créé sur l'appareil:

Format du média Attribut XML Type MIME MediaFormat
HEVC (H.265) HEVC MediaFormat.MIMETYPE_VIDEO_HEVC
HDR10HDR10 MediaFeature.HdrType.HDR10
HDR10+ HDR10Plus MediaFeature.HdrType.HDR10_PLUS

Android suppose que les applications peuvent lire tous les formats multimédias. Le transcodage de contenus multimédias compatible est donc désactivé par défaut.

Quand utiliser le transcodage ?

Le transcodage est une opération coûteuse en calcul qui ajoute un délai important lors de l'ouverture d'un fichier vidéo. Par exemple, sur un téléphone Pixel 3, le transcodage d'un fichier vidéo HEVC d'une minute au format AVC prend environ 20 secondes. C'est pourquoi vous ne devez transcoder un fichier vidéo que lorsque vous l'envoyez depuis l'appareil. (par exemple, lorsque vous partagez un fichier vidéo avec d'autres utilisateurs de la même application ou avec un serveur cloud qui n'est pas compatible avec les formats vidéo modernes).

Ne procédez pas au transcodage lorsque vous ouvrez des fichiers vidéo pour les lire sur l'appareil ou pour créer des vignettes.

Configurer le transcodage

Les applications peuvent contrôler leur comportement de transcodage en déclarant leurs fonctionnalités multimédias. Il existe deux façons de déclarer ces capacités: dans le code ou dans une ressource.

Déclarer des fonctionnalités dans le code

Vous pouvez déclarer des fonctionnalités multimédias dans le code en construisant une instance d'un objet ApplicationMediaCapabilities à l'aide d'un compilateur:

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

Utilisez cet objet lorsque vous accédez au contenu multimédia via des méthodes telles que ContentResolver#openTypedAssetFileDescriptor():

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

Cette méthode permet un contrôle précis pour des chemins de code particuliers, par exemple en appelant le transcodage uniquement lors du transfert d'un fichier vidéo hors de l'appareil. Elle est prioritaire sur la méthode décrite ci-dessous.

Déclarer des fonctionnalités dans une ressource

La déclaration des capacités d'une ressource permet de contrôler totalement le transcodage. Cette méthode ne doit être utilisée que dans des cas très spécifiques. Par exemple, si votre application ne reçoit que des fichiers vidéo d'autres applications (au lieu de les ouvrir directement) et les importe sur un serveur qui n'est pas compatible avec les codecs vidéo modernes (voir le scénario 1 ci-dessous).

Si cette méthode n'est pas absolument nécessaire, elle peut déclencher le transcodage dans des situations inattendues (par exemple, lors de la création de vignettes de vidéos), ce qui peut altérer l'expérience utilisateur.

Pour utiliser cette méthode, créez un fichier de ressources media_capabilities.xml:

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

Dans cet exemple, les vidéos HDR enregistrées sur l'appareil sont facilement transcodées en vidéo AVC SDR (Standard Dynamic Range), contrairement aux vidéos HEVC.

Utilisez une balise property dans la balise application pour ajouter une référence au fichier de fonctionnalités multimédias. Ajoutez les propriétés suivantes à votre fichier AndroidManifest.xml:

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

Utiliser les fonctionnalités multimédias d'une autre application pour ouvrir un fichier vidéo

Si votre application partage un fichier vidéo avec une autre application, il peut être nécessaire de transcoder le fichier vidéo avant que l'application réceptrice puisse l'ouvrir.

Pour gérer ce cas de figure, ouvrez un fichier vidéo à l'aide de openTypedAssetFileDescriptor et spécifiez l'UID de l'application réceptrice, qui peut être obtenu en utilisant Binder.getCallingUid. La plate-forme utilise ensuite les fonctionnalités multimédias de l'application réceptrice pour déterminer si le fichier vidéo doit être transcodé.

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

Exemples de scénarios

Les schémas suivants illustrent les deux cas d'utilisation courants. Dans les deux cas, la vidéo d'origine est stockée au format HEVC, et l'application de partage vidéo n'est pas compatible avec ce format.

Exemple 1. Le transcodage est lancé par l'application de capture vidéo. Exemple 1 L'application de partage de vidéos déclare ne pas prendre en charge HEVC dans son fichier de ressources de fonctionnalités multimédias. Elle demande ensuite une vidéo à l'application de capture vidéo. Celle-ci gère la requête et ouvre le fichier à l'aide de openTypedAssetFileDescriptor, en spécifiant l'UID de l'application de partage. Le processus de transcodage démarre. Lorsque la vidéo transcodée est reçue, elle est transmise à l'application de partage, qui l'importe sur un serveur dans le cloud.

Exemple 2. Le transcodage est lancé par l'application de partage de vidéos. Exemple 2 L'application de capture vidéo partage une vidéo avec l'application de partage de vidéos à l'aide d'un URI MediaStore. L'application de partage de vidéos ouvre le fichier vidéo à l'aide de openTypedAssetFileDescriptor, indiquant qu'elle n'est pas compatible avec le format HEVC dans ses fonctionnalités multimédias. Le processus de transcodage est lancé. Une fois l'opération terminée, le fichier est importé sur un serveur dans le cloud.

Formats non déclarés

Le transcodage de contenus multimédias compatible est activé pour tous les formats déclarés non compatibles et désactivé pour tous les formats déclarés compatibles. Pour les autres formats non déclarés, la plate-forme décide si elle doit être transcodée ou non. Dans Android 12, le transcodage est désactivé pour tous les formats non déclarés. Ce comportement est susceptible de changer pour de nouveaux formats à l'avenir.

Options pour les développeurs

Vous pouvez utiliser les options pour les développeurs suivantes pour ignorer le comportement de transcodage par défaut d'Android:

  • Remplacer les paramètres de transcodage par défaut : ce paramètre détermine si la plate-forme contrôle ou non le transcodage automatique. Lorsque le forçage est activé, les valeurs par défaut de la plate-forme sont ignorées, et le paramètre Activer le transcodage contrôle le transcodage automatique. Cette option est désactivée par défaut.

  • Activer le transcodage : ce paramètre indique si les formats non déclarés sont automatiquement transcodés. Elle est activée par défaut, mais elle n'a d'effet que si l'option Ignorer les paramètres de transcodage par défaut est également activée.

  • Supposer que les applications sont compatibles avec les formats modernes Ce paramètre contrôle ce qui se passe lorsque l'application tente de lire un format non déclaré. Cela se produit lorsque le fichier manifeste ne déclare pas si l'application est compatible ou non avec un format particulier, ou lorsque Google n'a pas ajouté l'application à la liste de transcodage forcé côté serveur. Lorsque ce paramètre est activé, l'application n'effectue pas de transcodage. Lorsqu'il est désactivé, l'application effectue le transcodage. Cette option est activée par défaut.

  • Afficher les notifications de transcodage : lorsque cette option est activée, l'application affiche une notification de progression du transcodage lorsque le transcodage est déclenché à la lecture d'un fichier multimédia non compatible. Cette option est activée par défaut.

  • Désactiver le cache de transcodage : si cette option est activée, les applications qui nécessitent le transcodage n'utilisent pas le cache de transcodage. Cela peut être utile pendant le développement pour déclencher facilement le transcodage sur un fichier multimédia non compatible, mais cela peut nuire aux performances de l'appareil. Cette option est désactivée par défaut.