Transformaciones

Transcodifica entre formatos

Puedes especificar los formatos de salida de audio y video que deseas producir cuando compilas Transformer. Por ejemplo, en el siguiente código, se muestra cómo configurar Transformer para generar video H.264/AVC y audio 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 el formato de medios de entrada ya coincide con la configuración de audio o video, Transformer cambiará de forma automática a transmuxing, es decir, copiar las muestras comprimidas del contenedor de entrada al contenedor de salida sin realizar modificaciones. Esto evita el costo de procesamiento y la posible pérdida de calidad al decodificar y volver a codificar en el mismo formato.

Cómo quitar audio o video

Quita audio o video con EditedMediaItem.Builder, por ejemplo:

Kotlin

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

Java

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

Cómo cortar un clip

Puedes quitar cualquier contenido multimedia fuera de las marcas de tiempo de inicio y finalización especificadas si estableces la configuración de recorte en el elemento multimedia de entrada. Por ejemplo, para producir un clip que contenga solo el contenido multimedia de 10 a 20 segundos, haz lo siguiente:

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

Optimizando los recortes

Para reducir la latencia al cortar el inicio de un video, habilita la optimización de recorte.

Kotlin

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

Java

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

Esto acelera la exportación, ya que decodifica y vuelve a codificar lo menos posible del video y, luego, une los datos recodificados con el resto del video original. La optimización se basa en poder unir parte del archivo de entrada con la salida recién codificada, lo que significa que el formato de salida del codificador y el formato de entrada deben ser compatibles. Por ejemplo, si el archivo se produjo originalmente en un dispositivo con una implementación de codificador diferente, es probable que no se pueda aplicar la optimización. Para que la optimización tenga éxito, el codificador proporcionado a Transformer a través de EncoderFactory debe tener un nivel y un perfil compatibles con el formato de entrada.

Esta optimización solo funciona con entradas MP4 de un solo elemento, sin efectos, excepto con efectos de video operacionales y rotaciones divisibles en 90 grados. Si la optimización falla, Transformer recurre automáticamente a la exportación normal y, luego, informa el resultado de la optimización en ExportResult.OptimizationResult.

Estamos validando esta funcionalidad y esperamos que no sea experimental en una versión posterior.

Ediciones de videos

Los EditedMediaItems tienen listas de procesadores de audio y efectos de video para aplicar en orden. La biblioteca incluye implementaciones de efectos de video para casos de uso comunes, o bien puedes escribir efectos personalizados y pasarlos cuando compiles elementos multimedia editados.

Puedes reescalar el contenido multimedia, lo que puede ser útil para ahorrar en recursos de procesamiento o ancho de banda cuando se trata de entradas de muy alta resolución, como videos en 4K u 8K. Por ejemplo, para escalar de manera proporcional a 480 píxeles de alto:

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

Como alternativa, puedes escalar por un factor determinado, por ejemplo, para reducir a la mitad el tamaño:

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

Puedes configurar la rotación de la misma manera:

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

Efectos de video personalizados

El constructor Effects acepta una lista de efectos de audio y video para aplicar. De forma interna, el framework de efectos de Transformer convierte la lista de efectos de video en una secuencia de programas sombreadores de GL que se aplican en orden. En algunos casos, el framework de efectos puede aplicar varios efectos con un solo programa sombreador. Por ejemplo, un programa sombreador puede aplicar varias transformaciones de matrices consecutivas, lo que mejora la eficiencia y la calidad.

Los efectos de video también se admiten para la vista previa en ExoPlayer, mediante ExoPlayer.setVideoEffects.

La app de demostración incluye ejemplos de efectos de video personalizados.

Ediciones de audio

Los efectos de audio se implementan aplicando una secuencia de instancias de AudioProcessor al audio sin procesar (PCM). ExoPlayer admite el paso de procesadores de audio a DefaultAudioSink.Builder, lo que permite obtener una vista previa de las ediciones de audio.