Transformationen

Zwischen Formaten transcodieren

Beim Erstellen von Transformer können Sie die gewünschten Audio- und Videoausgabeformate angeben. Der folgende Code zeigt beispielsweise, wie Transformer für die Ausgabe von H.264/AVC-Video- und AAC-Audio konfiguriert wird:

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 den Konfigurationen für Audio oder Video entspricht, wechselt Transformer automatisch zu Transmuxing, d. h., die komprimierten Beispiele werden unverändert aus dem Eingabecontainer in den Ausgabecontainer kopiert. Dadurch werden Rechenkosten und potenzielle Qualitätsverluste durch die Decodierung und Neucodierung im selben Format vermieden.

Audio oder Video entfernen

Entfernen Sie Audio- oder Videoinhalte mit EditedMediaItem.Builder. Beispiele:

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

Schnitte optimieren

Wenn du die Latenz beim Kürzen des Anfangs eines Videos verringern möchtest, aktiviere die Zuschneideoptimierung.

Kotlin

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

Java

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

Dies beschleunigt den Export, indem so wenig Video wie möglich decodiert und neu codiert werden. Anschließend werden die neu codierten Daten mit dem Rest des Originalvideos zusammengefügt. Die Optimierung setzt voraus, dass ein Teil der Eingabedatei mit einer neu codierten Ausgabe zusammengefügt werden kann. Das bedeutet, dass das Ausgabeformat des Encoders und das Eingabeformat kompatibel sein müssen. Wenn die Datei also ursprünglich auf einem Gerät mit einer anderen Encoderimplementierung erstellt wurde, ist es wahrscheinlich nicht möglich, die Optimierung anzuwenden. Für eine erfolgreiche Optimierung muss der an Transformer über EncoderFactory bereitgestellte Encoder eine Ebene und ein Profil haben, die mit dem Eingabeformat kompatibel sind.

Diese Optimierung funktioniert nur mit MP4-Eingaben aus einem Asset ohne Effekte, außer Videoeffekte und Rotationen, die um 90 Grad 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 überprüfen diese Funktionalität und gehen davon aus, dass sie in einer späteren Version nicht experimentell ist.

Videobearbeitungen

In EditedMediaItems finden Sie eine Liste mit Audioprozessoren und Videoeffekten, die in der richtigen Reihenfolge angewendet werden können. Die Bibliothek enthält Implementierungen für Videoeffekte für gängige Anwendungsfälle. Du kannst aber auch benutzerdefinierte Effekte schreiben und diese beim Erstellen bearbeiteter Medienelemente übergeben.

Sie können Medien neu skalieren. Dies kann nützlich sein, um Verarbeitungsressourcen oder Bandbreite zu sparen, wenn Sie mit einer Eingabe mit sehr hoher Auflösung wie 4K- oder 8K-Videos arbeiten. 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 um einen 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 Rotation auf die gleiche 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 Effects-Konstruktor 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-Shaderprogrammen, die der Reihe nach angewendet werden. In einigen Fällen kann das Effecten-Framework mehrere Effekte mit einem Shader-Programm anwenden. Beispielsweise kann ein Shader-Programm mehrere aufeinanderfolgende Matrixtransformationen anwenden, was die Effizienz und Qualität verbessert.

Videoeffekte werden auch für die Vorschau in ExoPlayer mit ExoPlayer.setVideoEffects unterstützt.

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

Audiobearbeitungen

Audioeffekte werden durch die Anwendung einer Sequenz von AudioProcessor-Instanzen auf Rohaudio (PCM) implementiert. ExoPlayer unterstützt die Übergabe von Audioprozessoren an DefaultAudioSink.Builder, wodurch eine Vorschau von Audiobearbeitungen angezeigt werden kann.