Les API Transformer de Jetpack Media3 sont conçues pour le montage multimédia performante et fiable. Transformer accepte un certain nombre d'opérations, y compris:
- Modifier une vidéo avec le découpage, la mise à l'échelle et la rotation
- Ajouter des effets tels que des superpositions et des filtres
- Traitement de formats spéciaux tels que la technologie HDR et le ralenti
- Exporter un élément multimédia après application des modifications
Cette page décrit certains des principaux cas d'utilisation couverts par "Transformateur". Pour en savoir plus, vous pouvez consulter nos guides complets Media3 Transformer
Premiers pas
Pour commencer, ajoutez une dépendance aux modules Transformer, Effect et Common de Jetpack Media3:
implementation "androidx.media3:media3-transformer:1.4.1" implementation "androidx.media3:media3-effect:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
Veillez à remplacer 1.4.1
par la version de votre choix
bibliothèque. Vous pouvez consulter
Notes de version
pour afficher la dernière version.
Classes importantes
Classe | Objectif |
---|---|
Transformer |
Démarrez et arrêtez des transformations, et vérifiez l'état d'avancement d'une transformation en cours d'exécution. |
EditedMediaItem |
Représente un élément multimédia à traiter et les modifications à y appliquer. |
Effects |
Ensemble d'effets audio et vidéo. |
Configurer le résultat
Avec Transformer.Builder
, vous pouvez maintenant spécifier videoMimeType
et
audioMimetype
en définissant la fonction sans avoir à créer de
TransformationRequest
.
Transcodage d'un format à un autre
Le code suivant montre comment configurer un objet Transformer
pour
sortie vidéo H.265/AVC et audio AAC:
Kotlin
val transformer = Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build()
Java
Transformer transformer = new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
Si le format du média d'entrée correspond déjà à la requête de transformation pour l'audio ou vidéo, Transformer passe automatiquement au transmuxing, c'est-à-dire copier les échantillons compressés du conteneur d'entrée vers le conteneur de sortie sans modification. Cela permet d'éviter les coûts de calcul et la perte potentielle de qualité décodage et réencodage dans le même format.
Définir le mode HDR
Si le fichier multimédia d'entrée est au format HDR, vous avez le choix entre plusieurs
différents modes de traitement des informations HDR. Vous avez probablement
souhaitez utiliser HDR_MODE_KEEP_HDR
ou
HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL
HDR_MODE_KEEP_HDR |
HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL |
|
---|---|---|
Description | Conservez les données HDR, c'est-à-dire que le format de sortie HDR est identique au format d'entrée HDR. | Entrée de carte de tonalité HDR en SDR à l'aide d'un tone-mapper OpenGL, ce qui signifie que le format de sortie est au format SDR. |
Assistance | Compatible avec les niveaux d'API 31 et supérieurs pour les appareils qui incluent un encodeur avec la capacité FEATURE_HdrEditing . |
Compatible avec les niveaux d'API 29 et supérieurs. |
Erreurs | Si elle n'est pas compatible, essayez d'utiliser HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL à la place. |
S'il n'est pas compatible, une exception ExportException est générée. |
Appareils compatibles avec les fonctionnalités d'encodage requises et exécutant Android 13
(niveau d'API 33) ou version ultérieure, les objets Transformer
vous permettent de modifier des vidéos HDR.
HDR_MODE_KEEP_HDR
est le mode par défaut lors de la création de l'objet Composition
.
comme indiqué dans le code suivant:
Kotlin
val composition = Composition.Builder( ImmutableList.of(videoSequence)) .setHdrMode(HDR_MODE_KEEP_HDR) .build()
Java
Composition composition = new Composition.Builder( ImmutableList.of(videoSequence)) .setHdrMode(Composition.HDR_MODE_KEEP_HDR) .build();
Préparer un élément multimédia
Un MediaItem
représente un élément audio
ou vidéo dans votre application. Un EditedMediaItem
collecte un MediaItem
avec les transformations à lui appliquer.
Couper une vidéo
Pour supprimer les parties non désirées d'une vidéo, vous pouvez personnaliser le début et la fin
en ajoutant un ClippingConfiguration
à MediaItem
.
Kotlin
val clippingConfiguration = MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) // start at 10 seconds .setEndPositionMs(20_000) // end at 20 seconds .build() val mediaItem = MediaItem.Builder() .setUri(videoUri) .setClippingConfiguration(clippingConfiguration) .build()
Java
ClippingConfiguration clippingConfiguration = new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) // start at 10 seconds .setEndPositionMs(20_000) // end at 20 seconds .build(); MediaItem mediaItem = new MediaItem.Builder() .setUri(videoUri) .setClippingConfiguration(clippingConfiguration) .build();
Utiliser des effets intégrés
Media3 inclut un certain nombre d'effets vidéo intégrés pour les transformations courantes, Par exemple:
Classe | Effet |
---|---|
Presentation |
Ajuster l'élément multimédia en fonction de la résolution ou du format |
ScaleAndRotateTransformation |
Mettre à l'échelle l'élément multimédia selon un multiplicateur et/ou le faire pivoter |
Crop |
Recadrer l'élément multimédia dans un cadre plus petit ou plus grand |
OverlayEffect |
Ajoutez du texte ou une image en superposition sur l'élément multimédia. |
Pour les effets audio, vous pouvez ajouter une séquence
AudioProcessor
qui transformeront les données audio brutes (PCM). Par exemple, vous pouvez utiliser
un ChannelMixingAudioProcessor
pour combiner et adapter les canaux audio.
Pour utiliser ces effets, créez une instance de l'effet ou du processeur audio,
Une instance de Effects
avec les effets audio et vidéo auxquels vous souhaitez appliquer
l'élément multimédia, puis ajoutez l'objet Effects
à une EditedMediaItem
.
Kotlin
val channelMixingProcessor = ChannelMixingAudioProcessor() val rotateEffect = ScaleAndRotateTransformation.Builder().setRotationDegrees(60f).build() val cropEffect = Crop(-0.5f, 0.5f, -0.5f, 0.5f) val effects = Effects(listOf(channelMixingProcessor), listOf(rotateEffect, cropEffect)) val editedMediaItem = EditedMediaItem.Builder(mediaItem) .setEffects(effects) .build()
Java
ChannelMixingAudioProcessor channelMixingProcessor = new ChannelMixingAudioProcessor(); ScaleAndRotateTransformation rotateEffect = new ScaleAndRotateTransformation.Builder() .setRotationDegrees(60f) .build(); Crop cropEffect = new Crop(-0.5f, 0.5f, -0.5f, 0.5f); Effects effects = new Effects( ImmutableList.of(channelMixingProcessor), ImmutableList.of(rotateEffect, cropEffect) ); EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem) .setEffects(effects) .build();
Créer des effets personnalisés
Créez des effets personnalisés en développant les effets inclus dans Media3
spécifiques à vos cas d'utilisation. Dans l'exemple suivant, utilisez sous-classe
MatrixTransformation
pour zoomer sur la vidéo afin de remplir l'image à partir de la première image
seconde de lecture:
Kotlin
val zoomEffect = MatrixTransformation { presentationTimeUs -> val transformationMatrix = Matrix() // Set the scaling factor based on the playback position val scale = min(1f, presentationTimeUs / 1_000f) transformationMatrix.postScale(/* x */ scale, /* y */ scale) transformationMatrix } val editedMediaItem = EditedMediaItem.Builder(inputMediaItem) .setEffects(Effects(listOf(), listOf(zoomEffect)) .build()
Java
MatrixTransformation zoomEffect = presentationTimeUs -> { Matrix transformationMatrix = new Matrix(); // Set the scaling factor based on the playback position float scale = min(1f, presentationTimeUs / 1_000f); transformationMatrix.postScale(/* x */ scale, /* y */ scale); return transformationMatrix; }; EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(inputMediaItem) .setEffects(new Effects(ImmutableList.of(), ImmutableList.of(zoomEffect))) .build();
Pour personnaliser davantage le comportement d'un effet, implémentez une
GlShaderProgram
La
La méthode queueInputFrame()
permet de traiter les frames d'entrée. Par exemple, pour
les fonctionnalités de machine learning
MediaPipe, vous pouvez utiliser un
MediaPipe FrameProcessor
pour envoyer chaque image
via un graphique MediaPipe. Vous trouverez un exemple dans la
Application de démonstration Transformer
Prévisualiser les effets
Avec ExoPlayer, vous pouvez prévisualiser les effets
à un élément multimédia
avant de lancer le processus d'exportation. En utilisant la même
Effects
comme pour EditedMediaItem
, appelez setVideoEffects()
sur votre
Instance ExoPlayer.
Kotlin
val player = ExoPlayer.builder(context) .build() .also { exoPlayer -> exoPlayer.setMediaItem(inputMediaItem) exoPlayer.setVideoEffects(effects) exoPlayer.prepare() }
Java
ExoPlayer player = new ExoPlayer.builder(context).build(); player.setMediaItem(inputMediaItem); player.setVideoEffects(effects); exoPlayer.prepare();
Vous pouvez également prévisualiser des effets audio avec ExoPlayer. Lorsque vous créez votre
ExoPlayer
, transmettez un RenderersFactory
personnalisé qui configure le
les moteurs de rendu audio du lecteur pour diffuser le contenu audio vers un AudioSink
qui utilise votre
Séquence AudioProcessor
. Pour ce faire, dans l'exemple ci-dessous, la valeur
Méthode buildAudioSink()
d'un DefaultRenderersFactory
.
Kotlin
val player = ExoPlayer.Builder(context, object : DefaultRenderersFactory(context) { override fun buildAudioSink( context: Context, enableFloatOutput: Boolean, enableAudioTrackPlaybackParams: Boolean, enableOffload: Boolean ): AudioSink? { return DefaultAudioSink.Builder(context) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams) .setOffloadMode(if (enableOffload) { DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED } else { DefaultAudioSink.OFFLOAD_MODE_DISABLED }) .setAudioProcessors(arrayOf(channelMixingProcessor)) .build() } }).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context, new DefaultRenderersFactory(context) { @Nullable @Override protected AudioSink buildAudioSink( Context context, boolean enableFloatOutput, boolean enableAudioTrackPlaybackParams, boolean enableOffload ) { return new DefaultAudioSink.Builder(context) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams) .setOffloadMode( enableOffload ? DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED : DefaultAudioSink.OFFLOAD_MODE_DISABLED) .setAudioProcessors(new AudioProcessor[]{channelMixingProcessor}) .build(); } }).build();
Lancer une transformation
Enfin, créez un Transformer
pour appliquer vos modifications et commencer à exporter les
l'élément multimédia généré.
Kotlin
val transformer = Transformer.Builder(context) .addListener(listener) .build() transformer.start(editedMediaItem, outputPath)
Java
Transformer transformer = new Transformer.Builder(context) .addListener(listener) .build(); transformer.start(editedMediaItem, outputPath);
Vous pouvez aussi annuler
le processus d'exportation si nécessaire avec
Transformer.cancel()
Vérifier la progression
Transformer.start
renvoie immédiatement un résultat et s'exécute de manière asynchrone. Pour interroger la
la progression actuelle d'une transformation, appelez
Transformer.getProgress()
Cette méthode utilise un ProgressHolder
et, si l'état de progression est disponible,
Autrement dit, si la méthode renvoie PROGRESS_STATE_AVAILABLE
, les valeurs
ProgressHolder
sera mis à jour avec le pourcentage de progression actuel.
Vous pouvez également joindre un
écouteur
à votre Transformer
pour être averti des événements d'achèvement ou d'erreur.