Transformationen

Zwischen Formaten transcodieren

Beim Erstellen von Transformer können Sie die Audio- und Videoausgabeformate angeben, die Sie erstellen möchten. Der folgende Code zeigt beispielsweise, wie Sie Transformer so konfigurieren, dass H.264/AVC-Video und AAC-Audio ausgegeben werden:

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

Wenn das Eingabemedienformat bereits mit den Konfigurationen für Audio oder Video übereinstimmt, wechselt Transformer automatisch zu Transmuxing. Das bedeutet, dass die komprimierten Samples ohne Änderungen vom Eingabe- in den Ausgabecontainer kopiert werden. So werden die Rechenkosten und der potenzielle Qualitätsverlust durch das Decodieren und erneute Codieren im selben Format vermieden.

Audio oder Video entfernen

Sie können Audio oder Video mit EditedMediaItem.Builder entfernen, z. B. so:

Kotlin

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

Java

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

Clip kürzen

Sie können alle Medien außerhalb der angegebenen Start- und Endzeitstempel entfernen, indem Sie die Clipping-Konfiguration für das Eingabemedienelement festlegen. So erstellen Sie beispielsweise einen Clip, der nur die Medien zwischen 10 und 20 Sekunden enthält:

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

MP4-Bearbeitungslisten

Für ein schnelleres Kürzen unterstützt Transformer MP4-Bearbeitungslisten, die effizientere Bearbeitungen ermöglichen, bei denen nur gekürzt wird, ohne dass das Video vollständig neu transcodiert werden muss. Bei dieser Methode werden vorhandene codierte Samples und ein „Pre-Roll“ in der Bearbeitungsliste verwendet, mit dem der Player angewiesen wird, die Wiedergabe an einem bestimmten Punkt zu starten. So wird das unerwünschte Anfangssegment übersprungen.

Wenn Sie Bearbeitungen, bei denen nur gekürzt wird, deutlich schneller durchführen möchten, rufen Sie experimentalSetMp4EditListTrimEnabled(true) auf.

Kotlin

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

Java

new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
Nicht alle Mediaplayer unterstützen eine „Pre-Roll“-Position. Wenn ein solcher Player verwendet wird, beginnt die Wiedergabe der Datei immer am Anfang des codierten Samples, unabhängig von Informationen in der Bearbeitungsliste, die einen anderen Startpunkt angeben.

Kürzen optimieren

Wenn Sie die Latenz beim Kürzen des Anfangs eines Videos reduzieren möchten, aktivieren Sie die Kürzung optimieren.

Kotlin

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

Java

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

Dadurch wird der Export beschleunigt, da nur so wenig wie möglich vom Video decodiert und neu codiert wird. Die neu codierten Daten werden dann mit dem Rest des Originalvideos zusammengefügt. Die Optimierung setzt voraus, dass ein Teil der Eingabedatei mit der neu codierten Ausgabe zusammengefügt werden kann. Das bedeutet, dass das Ausgabeformat des Encoders und das Eingabeformat kompatibel sein müssen. Wenn die Datei beispielsweise ursprünglich auf einem Gerät mit einer anderen Encoder-Implementierung erstellt wurde, ist es wahrscheinlich nicht möglich, die Optimierung anzuwenden. Damit die Optimierung funktioniert, muss der Encoder, der Transformer über die EncoderFactory zur Verfügung gestellt wird, ein Level und ein Profil haben, die mit dem Eingabeformat kompatibel sind.

Diese Optimierung funktioniert nur mit MP4-Eingaben mit einem einzelnen Asset ohne Effekte, mit Ausnahme von Videoeffekten ohne Operation und Drehungen, die durch 90 teilbar sind. Wenn die Optimierung fehlschlägt, greift Transformer automatisch auf den normalen Export zurück und meldet das Ergebnis der Optimierung in ExportResult.OptimizationResult.

Wir prüfen diese Funktion und gehen davon aus, dass sie in einer späteren Version nicht mehr als experimentell gekennzeichnet wird.

Videobearbeitungen

EditedMediaItems enthalten Listen von Audioprozessoren und Videoeffekten, die in der angegebenen Reihenfolge angewendet werden. Die Bibliothek enthält Implementierungen von Videoeffekten für häufige Anwendungsfälle. Sie können aber auch benutzerdefinierte Effekte erstellen und sie beim Erstellen bearbeiteter Medienelemente übergeben.

Sie können die Größe von Medien ändern. Das kann nützlich sein, um Verarbeitungsressourcen oder Bandbreite zu sparen, wenn Sie mit Eingaben mit sehr hoher Auflösung arbeiten, z. B. 4K- oder 8K-Videos. So skalieren Sie beispielsweise proportional auf eine Höhe von 480 Pixeln:

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

Alternativ können Sie die Größe um einen bestimmten Faktor ändern, z. B. um sie zu halbieren:

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

Die Drehung können Sie auf dieselbe Weise konfigurieren:

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

Benutzerdefinierte Videoeffekte

Der Konstruktor Effects akzeptiert eine Liste von Audio- und Videoeffekten, die angewendet werden sollen. Intern wandelt das Effekte-Framework von Transformer die Liste der Videoeffekte in eine Sequenz von GL-Shaderprogrammen um, die in der angegebenen Reihenfolge angewendet werden. In einigen Fällen kann das Effekte-Framework mehrere Effekte mit einem Shaderprogramm anwenden. So kann ein Shaderprogramm beispielsweise mehrere aufeinanderfolgende Matrixtransformationen anwenden, was die Effizienz und Qualität verbessert.

Videoeffekte werden auch für die Vorschau in ExoPlayer unterstützt. Verwenden Sie dazu ExoPlayer.setVideoEffects. Ein Beispiel für die Verwendung dieser API finden Sie in der Demo-App für Effekte.

Die Demo-App enthält Beispiele für benutzerdefinierte Videoeffekte.

Bildeingabe

Transformer unterstützt Bildeingaben, indem sie als statische Videoclips behandelt werden. So konfigurieren Sie ein Bild als Eingabequelle:

  • Erstellen Sie ein MediaItem mit MediaItem.Builder. Geben Sie die Anzeigedauer des Bildes im Ausgabevideo an, indem Sie setImageDurationMs aufrufen.

  • Erstellen Sie ein EditedMediaItem, das das MediaItem umschließt. Geben Sie die Zielbildrate für den generierten Videostream mit EditedMediaItem.Builder#setFrameRate an.

Das folgende Beispiel zeigt, wie Sie eine Bildeingabe so konfigurieren, dass ein 5-Sekunden-Video mit 30 Bildern pro Sekunde generiert wird:

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

Audiobearbeitungen

Audioeffekte werden implementiert, indem eine Sequenz von AudioProcessor-Instanzen auf Rohaudio (PCM) angewendet wird. ExoPlayer unterstützt das Übergeben von Audioprozessoren an DefaultAudioSink.Builder, wodurch eine Vorschau von Audiobearbeitungen möglich ist.