Transformations

Transcoder des formats

Vous pouvez spécifier les formats audio et vidéo de sortie que vous souhaitez générer lors de la création de Transformer. Par exemple, le code suivant montre comment configurer Transformer pour générer une vidéo H.264/AVC et un son AAC :

Kotlin

Transformer.Builder(context)
  .setVideoMimeType(MimeTypes.VIDEO_H264)
  .setAudioMimeType(MimeTypes.AUDIO_AAC)
  .build()

Java

new Transformer.Builder(context)
    .setVideoMimeType(MimeTypes.VIDEO_H264)
    .setAudioMimeType(MimeTypes.AUDIO_AAC)
    .build();

Si le format multimédia d'entrée correspond déjà aux configurations audio ou vidéo, Transformer passe automatiquement au transmuxage, c'est-à-dire qu'il copie les échantillons compressés du conteneur d'entrée vers le conteneur de sortie sans modification. Cela évite le coût de calcul et la perte de qualité potentielle du décodage et du réencodage dans le même format.

Supprimer l'audio ou la vidéo

Supprimez l'audio ou la vidéo à l'aide de EditedMediaItem.Builder, par exemple :

Kotlin

EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()

Java

new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();

Découper un extrait

Vous pouvez supprimer tout contenu multimédia en dehors des codes temporels de début et de fin spécifiés en définissant la configuration de découpage sur l'élément multimédia d'entrée. Par exemple, pour produire un extrait contenant uniquement le contenu multimédia entre 10 et 20 secondes :

Kotlin

val inputMediaItem =
  MediaItem.Builder()
    .setUri(uri)
    .setClippingConfiguration(
      MediaItem.ClippingConfiguration.Builder()
        .setStartPositionMs(10_000)
        .setEndPositionMs(20_000)
        .build()
    )
    .build()

Java

MediaItem inputMediaItem =
    new MediaItem.Builder()
        .setUri(uri)
        .setClippingConfiguration(
            new MediaItem.ClippingConfiguration.Builder()
                .setStartPositionMs(10_000)
                .setEndPositionMs(20_000)
                .build())
        .build();

Listes de modification MP4

Pour un découpage plus rapide, Transformer est compatible avec les listes de modification MP4, ce qui permet des modifications plus efficaces de type "découpage uniquement" sans réencodage complet de la vidéo. Cette méthode utilise des exemples encodés existants et un "pré-roll" dans la liste de modification, qui indique au lecteur de commencer la lecture à un point spécifique, en ignorant efficacement le segment initial indésirable.

Pour accélérer considérablement les modifications de type "découpage uniquement", appelez experimentalSetMp4EditListTrimEnabled(true).

Kotlin

Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build()

Java

new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
Il est important de noter que tous les lecteurs multimédias ne sont pas compatibles avec une position de "pré-roll". Cela signifie que lorsqu'un tel lecteur est utilisé, la lecture du fichier commence au tout début de l'exemple encodé, quelles que soient les informations de la liste de modification qui pourraient spécifier un point de départ différent.

Optimiser les découpages

Pour réduire la latence du découpage au début d'une vidéo, activez l'optimisation du découpage.

Kotlin

Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build()

Java

new Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build();

Cela accélère l'exportation en décodant et en réencodant le moins possible de la vidéo, puis en assemblant les données réencodées avec le reste de la vidéo d'origine. L'optimisation repose sur la possibilité d'assembler une partie du fichier d'entrée avec une sortie nouvellement encodée, ce qui signifie que le format de sortie de l'encodeur et le format d'entrée doivent être compatibles. Par exemple, si le fichier a été produit à l'origine sur un appareil avec une implémentation d'encodeur différente, il est probable qu'il ne soit pas possible d'appliquer l'optimisation. Pour que l'optimisation réussisse, l'encodeur fourni à Transformer via EncoderFactory doit avoir un niveau et un profil compatibles avec le format d'entrée.

Cette optimisation ne fonctionne qu'avec une entrée MP4 à un seul élément sans effets, à l'exception des effets vidéo sans opération et des rotations divisibles par 90 degrés. Si l'optimisation échoue, Transformer revient automatiquement à l'exportation normale et signale le résultat de l'optimisation dans ExportResult.OptimizationResult.

Nous validons cette fonctionnalité et prévoyons qu'elle ne sera plus expérimentale dans une version ultérieure.

Retouches vidéo

Les EditedMediaItems comportent des listes de processeurs audio et d'effets vidéo à appliquer dans l'ordre. La bibliothèque inclut des implémentations d'effets vidéo pour les cas d'utilisation courants, mais vous pouvez également écrire des effets personnalisés et les transmettre lors de la création d'éléments multimédias modifiés.

Vous pouvez redimensionner le contenu multimédia, ce qui peut être utile pour économiser des ressources de traitement ou de la bande passante lorsque vous traitez des entrées à très haute résolution, comme des vidéos 4K ou 8K. Par exemple, pour mettre à l'échelle proportionnellement à 480 pixels de hauteur :

Kotlin

EditedMediaItem.Builder(MediaItem.fromUri(uri))
  .setEffects(
    Effects(
      /* audioProcessors= */ listOf(),
      /* videoEffects= */ listOf(Presentation.createForHeight(480)),
    )
  )
  .build()

Java

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480))))
    .build();

Vous pouvez également mettre à l'échelle selon un facteur donné, par exemple pour réduire la taille de moitié :

Kotlin

val editedMediaItem =
  EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
      Effects(
        /* audioProcessors= */ listOf(),
        /* videoEffects= */ listOf(
          ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()
        ),
      )
    )
    .build()

Java

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(
                new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build())))
    .build();

Vous pouvez configurer la rotation de la même manière :

Kotlin

EditedMediaItem.Builder(MediaItem.fromUri(uri))
  .setEffects(
    Effects(
      /* audioProcessors= */ listOf(),
      /* videoEffects= */ listOf(
        ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build()
      ),
    )
  )
  .build()

Java

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(
                new ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build())))
    .build();

Effets vidéo personnalisés

Le constructeur Effects accepte une liste d'effets audio et vidéo à appliquer. En interne, le framework d'effets de Transformer convertit la liste des effets vidéo en une séquence de programmes de shader GL qui sont appliqués dans l'ordre. Dans certains cas, le framework d'effets est en mesure d'appliquer plusieurs effets avec un seul programme de shader. Par exemple, un programme de shader peut appliquer plusieurs transformations de matrice consécutives, ce qui améliore l'efficacité et la qualité.

Les effets vidéo sont également compatibles avec la prévisualisation dans ExoPlayer, à l'aide de ExoPlayer.setVideoEffects. Pour obtenir un exemple d'utilisation de cette API, consultez l'application de démonstration d'effets.

L'application de démonstration inclut des exemples d'effets vidéo personnalisés.

Image d'entrée

Transformer est compatible avec les entrées d'image en les traitant comme des extraits vidéo statiques. Pour configurer une image comme source d'entrée, procédez comme suit :

  • Créez un MediaItem à l'aide de MediaItem.Builder. Spécifiez la durée d'affichage de l'image dans la vidéo de sortie en appelant setImageDurationMs.

  • Créez un EditedMediaItem encapsulant le MediaItem. Spécifiez la fréquence d'images cible pour le flux vidéo généré à l'aide de EditedMediaItem.Builder#setFrameRate.

L'exemple suivant montre comment configurer une entrée d'image pour générer une vidéo de cinq secondes à 30 images par seconde :

Kotlin

val imageMediaItem =
  MediaItem.Builder()
    .setUri(imageUri)
    .setImageDurationMs(5000) // 5 seconds
    .build()

val editedImageItem =
  EditedMediaItem.Builder(imageMediaItem)
    .setFrameRate(30) // 30 frames per second
    .build()

Java

MediaItem imageMediaItem =
    new MediaItem.Builder()
        .setUri(imageUri)
        .setImageDurationMs(5000) // 5 seconds
        .build();
new EditedMediaItem.Builder(imageMediaItem)
    .setFrameRate(30) // 30 frames per second
    .build();

Retouches audio

Les effets audio sont implémentés en appliquant une séquence d'instances AudioProcessor à l'audio brut (PCM). ExoPlayer est compatible avec la transmission de processeurs audio à DefaultAudioSink.Builder, ce qui permet de prévisualiser les retouches audio.