Mit Jetpack Media3 Transformer können Sie Medienassets auf Android-Geräten bearbeiten, konvertieren und exportieren. Auf dieser Seite wird erläutert, wie Sie die folgenden grundlegenden Transformationen konfigurieren:
- Transcodierung und Transmuxing: Sie können Audio- und Videoformate konvertieren oder die erneute Codierung durch Kopieren von Containerbeispielen (Transmuxing) umgehen.
- Entfernen von Tracks: Sie können Audio- oder Videotracks aus Medien entfernen.
- Zuschneiden und Optimieren: Sie können Medien anhand von Zeitstempeln zuschneiden und Optionen für schnellere Exporte mit MP4-Bearbeitungslisten und Zuschneideoptimierung verwenden.
- Videoeffekte: Sie können Videos skalieren, drehen oder benutzerdefinierte OpenGL-Shader-Effekte anwenden. Eine Vorschau ist in ExoPlayer möglich.
- Bildeingabe: Sie können statische Bilder in Videoclips mit benutzerdefinierten Dauern und Frameraten umwandeln.
- Audioverarbeitung: Sie können
AudioProcessorInstanzen verketten, um Rohaudio zu ändern.
Transcodierung zwischen Formaten
Sie können die Audio- und Videoausgabeformate angeben, die Sie beim Erstellen von Transformer verwenden möchten. Im folgenden Code wird beispielsweise gezeigt, 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 zum Transmuxing. Dabei werden die komprimierten Beispiele aus dem Eingabecontainer unverändert in den Ausgabecontainer kopiert. So werden die Rechenkosten und der potenzielle Qualitätsverlust durch Decodierung und erneute Codierung im selben Format vermieden.
Audio oder Video entfernen
Sie können Audio oder Video mit EditedMediaItem.Builder entfernen, z. B.:
Kotlin
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
Clip zuschneiden
Sie können alle Medien außerhalb der angegebenen Start- und Endzeitstempel entfernen, indem Sie die Zuschneidekonfiguration für das Eingabemedienitem festlegen. Wenn Sie beispielsweise einen Clip erstellen möchten, der nur die Medien zwischen 10 und 20 Sekunden enthält, gehen Sie so vor:
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 Zuschneiden unterstützt Transformer MP4-Bearbeitungslisten. So können Sie effizienter nur Zuschneidebearbeitungen vornehmen, ohne das gesamte Video neu zu transcodieren. Bei dieser Methode werden vorhandene codierte Beispiele 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 nur Zuschneidebearbeitungen deutlich schneller vornehmen möchten, rufen Sie experimentalSetMp4EditListTrimEnabled(true) auf.
Kotlin
Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build()
Java
new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
Zuschneiden optimieren
Wenn Sie die Latenz beim Zuschneiden des Anfangs eines Videos reduzieren möchten, aktivieren Sie die Zuschneideoptimierung.
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 bereitgestellt wird, ein Level und ein Profil haben, die mit dem Eingabeformat kompatibel sind.
Diese Optimierung funktioniert nur mit MP4-Eingaben mit einem einzelnen Asset und ohne Effekte, mit Ausnahme von No-Op-Videoeffekten 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 gängige Anwendungsfälle. Sie können aber auch benutzerdefinierte Effekte schreiben und sie beim Erstellen bearbeiteter Medienitems übergeben.
Sie können Medien neu skalieren. Das kann nützlich sein, um Verarbeitungsressourcen oder Bandbreite zu sparen, wenn Sie mit Eingaben mit sehr hoher Auflösung wie 4K- oder 8K-Videos arbeiten. Wenn Sie beispielsweise proportional auf 480 Pixel Höhe skalieren möchten, gehen Sie so vor:
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 nach einem bestimmten Faktor skalieren, z. B. um die Größe 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();
Sie können die Drehung 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 konvertiert das Effekte-Framework von Transformer die Liste der Videoeffekte in eine Sequenz von GL-Shader-Programmen, die in der angegebenen Reihenfolge angewendet werden. In einigen Fällen kann das Effekte-Framework mehrere Effekte mit einem Shader-Programm anwenden.
So kann ein Shader-Programm 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 mit
MediaItem.BuildereinMediaItem. Geben Sie die Anzeigedauer des Bildes im Ausgabevideo an, indem SiesetImageDurationMsaufrufen.Erstellen Sie ein
EditedMediaItem, das dasMediaItemumschließt. Geben Sie die Ziel-Framerate für den generierten Videostream mitEditedMediaItem.Builder#setFrameRatean.
Im folgenden Beispiel wird gezeigt, 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 die Übergabe von Audioprozessoren an DefaultAudioSink.Builder, sodass Sie sich eine Vorschau der Audiobearbeitungen ansehen können.