Nouveautés concernant les produits

Media3 1.9.0 : nouveautés

Temps de lecture : 6 min
Kristina Simakova
Responsable ingénierie

Media3 1.9.0 est disponible. Outre les corrections de bugs et les améliorations des performances habituelles, la dernière version contient également quatre modules nouveaux ou largement réécrits :

  • media3-inspector : extrait les métadonnées et les images en dehors de la lecture
  • media3-ui-compose-material3 : crée une interface utilisateur multimédia Compose Material3 de base en quelques étapes seulement
  • media3-cast : gère automatiquement les transitions entre la lecture Cast et la lecture locale
  • media3-decoder-av1 : assure une lecture AV1 cohérente grâce au décodeur d'extension réécrit basé sur la bibliothèque dav1d

Nous avons également amélioré la mise en cache et la gestion de la mémoire dans PreloadManager, et simplifié ExoPlayerTransformer et MediaSession

Cette version vous offre également le premier accès expérimental à CompositionPlayer pour prévisualiser les modifications multimédias.  


Pour en savoir plus, lisez la suite. Comme toujours, veuillez consulter les notes de version complètes pour obtenir une vue d'ensemble des modifications apportées à cette version.

Extraire les métadonnées et les images en dehors de la lecture

Dans de nombreux cas, vous souhaiterez inspecter des contenus multimédias sans lancer la lecture. Par exemple, vous pouvez détecter les formats qu'ils contiennent, leur durée ou récupérer des miniatures.

Le nouveau module media3-inspector combine tous les utilitaires permettant d'inspecter des contenus multimédias sans lecture en un seul endroit :

  • MetadataRetriever : lit la durée, le format et les métadonnées statiques à partir d'un MediaItem.
  • FrameExtractor : obtient des images ou des miniatures à partir d'un élément.
  • MediaExtractorCompat : remplace directement la classe MediaExtractor de la plate-forme Android pour obtenir des informations détaillées sur les exemples du fichier.

MetadataRetriever et FrameExtractor suivent un modèle AutoCloseable simple. Pour en savoir plus, consultez nos nouvelles pages de guide.

suspend fun extractThumbnail(mediaItem: MediaItem) {

  FrameExtractor.Builder(context, mediaItem).build().use {

    val thumbnail = frameExtractor.getThumbnail().await()

  } 

}

Créer une interface utilisateur multimédia Compose Material3 de base en quelques étapes seulement

Dans les versions précédentes, nous avons commencé à fournir du code de connecteur entre les éléments d'interface utilisateur Compose et votre instance Player. Avec Media3 1.9.0, nous avons ajouté un nouveau module media3-ui-compose-material3 avec des boutons et des éléments de contenu Material3 entièrement stylisés. Ils vous permettent de créer une interface utilisateur multimédia en quelques étapes seulement, tout en vous offrant la possibilité de personnaliser le style. Si vous préférez créer votre propre style d'interface utilisateur, vous pouvez utiliser les blocs de construction qui gèrent toute la logique de mise à jour et de connexion. Vous n'avez donc qu'à vous concentrer sur la conception de l'élément d'interface utilisateur. Veuillez consulter nos pages de guide étendues pour les modules d'interface utilisateur Compose.

Nous travaillons également sur d'autres composants Compose, tels qu'une barre de recherche prédéfinie, un remplacement complet prêt à l'emploi pour PlayerView, ainsi que l'intégration de sous-titres et d'annonces.

@Composable
fun SimplePlayerUI(player: Player, modifier: Modifier = Modifier) {
  Column(modifier) {
    ContentFrame(player)  // Video surface and shutter logic
    Row (Modifier.align(Alignment.CenterHorizontally)) {                 
      SeekBackButton(player)   // Simple controls
      PlayPauseButton(player)
      SeekForwardButton(player)
    }
  }
}

 

image.png

Interface utilisateur simple du lecteur Compose avec des éléments prêts à l'emploi

Gérer automatiquement les transitions entre la lecture Cast et la lecture locale

Le CastPlayer du module media3-cast a été réécrit pour gérer automatiquement les transitions entre la lecture locale (par exemple, avec ExoPlayer) et la lecture Cast à distance.

Lorsque vous configurez votre MediaSession, créez simplement un CastPlayer autour de votre ExoPlayer et ajoutez un MediaRouteButton à votre interface utilisateur. C'est tout !

// MediaSession setup with CastPlayer 

val exoPlayer = ExoPlayer.Builder(context).build()

val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()

val session = MediaSession.Builder(context, castPlayer).build()

// MediaRouteButton in UI 

@Composable fun UIWithMediaRouteButton() {

  MediaRouteButton()

}
image.png

Nouvelle intégration de CastPlayer dans l'application de démonstration de session Media3

Assurer une lecture AV1 cohérente grâce à l'extension réécrite basée sur dav1d

La version 1.9.0 contient un module d'extension AV1 entièrement réécrit basé sur la bibliothèque populaire dav1d

Comme pour tous les modules de décodeur d'extension, veuillez noter qu'il est nécessaire de compiler à partir de la source  pour regrouper correctement le code natif pertinent. Le regroupement d'un décodeur assure la cohérence et la prise en charge des formats sur tous les appareils. Toutefois, comme il exécute le décodage dans votre processus, il est plus adapté aux contenus auxquels vous pouvez faire confiance.

Intégrer la mise en cache et la gestion de la mémoire dans PreloadManager

Nous avons également amélioré notre PreloadManager. Il vous permet déjà de précharger des contenus multimédias en mémoire en dehors de la lecture, puis de les transmettre de manière transparente à un lecteur si nécessaire. Bien qu'il soit assez performant, vous deviez toujours veiller à ne pas dépasser les limites de mémoire en préchargeant trop de contenus par erreur. Avec Media3 1.9.0, nous avons ajouté deux fonctionnalités qui facilitent et stabilisent considérablement cette opération :

  1. Prise en charge de la mise en cache : lorsque vous définissez la distance de préchargement, vous pouvez désormais choisir PreloadStatus.specifiedRangeCached(0, 5000) comme état cible pour les éléments préchargés. La plage spécifiée est alors ajoutée à votre cache sur le disque au lieu de charger les données en mémoire. Vous pouvez ainsi fournir une plage d'éléments beaucoup plus large pour le préchargement, car ceux qui sont plus éloignés de l'élément actuel n'ont plus besoin d'occuper de la mémoire. Notez que cela nécessite de définir un Cache dans DefaultPreloadManager.Builder.
  2. Gestion automatique de la mémoire : nous avons également mis à jour notre interface LoadControl pour mieux gérer le cas de préchargement. Vous pouvez désormais définir une limite supérieure explicite de mémoire pour tous les éléments préchargés en mémoire. Elle est de 144 Mo par défaut, et vous pouvez la configurer dans DefaultLoadControl.Builder. Le DefaultPreloadManager arrête automatiquement le préchargement une fois la limite atteinte et libère automatiquement la mémoire des éléments de priorité inférieure si nécessaire.

S'appuyer sur de nouveaux comportements par défaut simplifiés dans ExoPlayer

Comme toujours, nous avons également apporté de nombreuses améliorations progressives à ExoPlayer. En voici quelques exemples :

  • Couper et réactiver le son : nous disposions déjà d'une méthode setVolume, mais nous avons ajouté les méthodes pratiques mute et unmute pour restaurer facilement le volume précédent sans avoir à le suivre vous-même.
  • Détection des lecteurs bloqués : dans certains cas rares, le lecteur peut se bloquer dans un état de mise en mémoire tampon ou de lecture sans progresser, par exemple en raison de problèmes de codec ou de configurations incorrectes. Vos utilisateurs seront agacés, mais vous ne verrez jamais ces problèmes dans vos analyses. Pour rendre cela plus évident, le lecteur signale désormais une StuckPlayerException lorsqu'il détecte un état bloqué.
  • Wakelock par défaut : la gestion du verrouillage de l'activation était auparavant facultative, ce qui entraînait des cas extrêmes difficiles à trouver où la progression de la lecture pouvait être considérablement retardée lors de l'exécution en arrière-plan. Cette fonctionnalité est désormais désactivée par défaut. Vous n'avez donc pas à vous en soucier et vous pouvez également supprimer toute la gestion manuelle du wakelock autour de la lecture.
  • Paramètre simplifié pour la logique du bouton CC : il était étonnamment difficile de modifier TrackSelectionParameters pour indiquer "activer/désactiver les sous-titres". Nous avons donc ajouté une simple option booléenne selectTextByDefault pour ce cas d'utilisation.

Simplifier vos préférences de boutons multimédias dans MediaSession

Jusqu'à présent, pour définir vos préférences concernant les boutons à afficher dans le tiroir de notification multimédia sur Android Auto ou WearOS, vous deviez définir des commandes et des boutons personnalisés, même si vous souhaitiez simplement déclencher une méthode de lecteur standard.

Media3 1.9.0 offre une nouvelle fonctionnalité qui simplifie considérablement cette opération. Vous pouvez désormais définir vos préférences de boutons multimédias avec une commande de lecteur standard, sans avoir à gérer de commandes personnalisées.

session.setMediaButtonPreferences(listOf(
    CommandButton.Builder(CommandButton.ICON_FAST_FORWARD) // choose an icon
      .setDisplayName(R.string.skip_forward)
      .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) // choose an action 
      .build()
))
image.png

Préférences de boutons multimédias avec le bouton d'avance rapide

CompositionPlayer pour la prévisualisation en temps réel

La version 1.9.0 introduit CompositionPlayer sous une nouvelle annotation @ExperimentalApi. L'annotation indique qu'elle est disponible pour l'expérimentation, mais qu'elle est toujours en cours de développement. 

CompositionPlayer est un nouveau composant des API d'édition Media3 conçu pour la prévisualisation en temps réel des modifications multimédias. Basé sur l'interface Media3 familière PlayerCompositionPlayer permet aux utilisateurs de voir leurs modifications en action avant de s'engager dans le processus d'exportation. Il utilise le même objet Composition que celui que vous transmettez à Transformer pour l'exportation, ce qui simplifie le workflow d'édition en unifiant le modèle de données pour la prévisualisation et l'exportation.

Nous vous encourageons à commencer à utiliser CompositionPlayer et à nous faire part de vos commentaires. Consultez les prochains articles et mises à jour de la documentation pour en savoir plus.

InAppMuxer comme muxer par défaut dans Transformer

Transformer utilise désormais InAppMp4Muxer comme muxer par défaut pour écrire des fichiers de conteneur multimédia. En interne, InAppMp4Muxer dépend du module Muxer Media3, ce qui assure un comportement cohérent sur toutes les versions de l'API. 

Notez que, bien que Transformer n'utilise plus MediaMuxer de la plate-forme Android par défaut, vous pouvez toujours fournir FrameworkMuxer.Factory via setMuxerFactory si votre cas d'utilisation l'exige.

Nouvelles API d'ajustement de la vitesse

La version 1.9.0 simplifie les API d'ajustement de la vitesse pour l'édition multimédia. Nous avons introduit de nouvelles méthodes directement sur EditedMediaItem.Builder pour contrôler la vitesse, ce qui rend l'API plus intuitive. Vous pouvez désormais modifier la vitesse d'un clip en appelant setSpeed(SpeedProvider provider) sur EditedMediaItem.Builder :

val speedProvider = object : SpeedProvider {
    override fun getSpeed(presentationTimeUs: Long): Float {
        return speed
    }

    override fun getNextSpeedChangeTimeUs(timeUs: Long): Long {
        return C.TIME_UNSET
    }
}

EditedMediaItem speedEffectItem = EditedMediaItem.Builder(mediaItem)
    .setSpeed(speedProvider)
    .build()

Cette nouvelle approche remplace la méthode précédente qui utilisait Effects#createExperimentalSpeedChangingEffects(), que nous avons abandonnée et que nous supprimerons dans une prochaine version.

Présentation des types de pistes pour EditedMediaItemSequence

Dans la version 1.9.0, EditedMediaItemSequence nécessite de spécifier les types de pistes de sortie souhaités lors de la création de la séquence. Cette modification garantit une gestion des pistes plus explicite et robuste dans l'ensemble de la composition. 

Pour ce faire, nous avons ajouté un nouveau EditedMediaItemSequence.Builder constructeur qui accepte un ensemble de types de pistes (par exemple, C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO).

Pour simplifier la création, nous avons ajouté de nouvelles méthodes statiques pratiques :

  • EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

Nous vous encourageons à migrer vers le nouveau constructeur ou les méthodes pratiques pour des définitions de séquence plus claires et plus fiables.

Exemple de création d'une séquence vidéo uniquement :

EditedMediaItemSequence videoOnlySequence =
    EditedMediaItemSequence.Builder(setOf(C.TRACK_TYPE_VIDEO))
        .addItem(editedMediaItem)
        .build()

Veuillez nous contacter via l'outil de suivi des problèmes Media3 si vous rencontrez des bugs, si vous avez des questions ou si vous souhaitez demander une fonctionnalité. Nous attendons vos commentaires avec impatience !

Lire la suite