Novedades en video: transiciones, capítulos, CMAF y más
Durante los últimos meses, añadimos varias funciones de video, algunas a petición de nuestros clientes. Nunca las habíamos documentado, así que aquí las reunimos, cada una con Assembly Instructions que ejecutamos en producción antes de publicar.
Fundido cruzado entre clips
🤖 /video/concat une videos uno tras otro. Establece transition en
crossfade o fade_to_black, y los clips se fundirán entre sí en lugar de pasar de uno a otro con un corte brusco:
{
"steps": {
"first": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/big-buck-bunny-10s.mp4"
},
"second": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/waves10.mp4"
},
"concatenated": {
"robot": "/video/concat",
"use": {
"steps": [
{ "name": "first", "as": "video_1" },
{ "name": "second", "as": "video_2" }
]
},
"transition": "crossfade",
"transition_duration": 1,
"ffmpeg_stack": "v7"
}
}
}
El audio también se funde junto con la imagen. Estos son los fotogramas de justo antes, durante y justo después de la transición:

Algunos detalles que debes conocer:
transition_durationse expresa en segundos y su valor predeterminado es1. Su límite es la mitad de la duración del clip más corto de cada par.- Los clips se superponen durante la transición, por lo que el resultado es más corto: nuestros
clips de 10 y 13 segundos produjeron un video de 22 segundos. Esto también se aplica a
fade_to_black. - Una transición requiere que volvamos a codificar el video, por lo que el procesamiento tarda más que una unión simple, que puede copiar los flujos tal como están.
- 🤖 /video/merge acepta los mismos dos parámetros, pero
/video/concates más adecuado para unir clips. Procesa clips de distintos tamaños y tasas de fotogramas convirtiéndolos primero a especificaciones coincidentes, y conserva la salida en MP4.
Marcadores de capítulos para videos unidos
Cuando unas una introducción, el contenido principal y un cierre, establece chapter_markers: true, y los reproductores
que admitan capítulos podrán saltar directamente a cada parte:
{
"steps": {
"intro": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/big-buck-bunny-10s.mp4"
},
"main": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/waves10.mp4"
},
"outro": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/fake-ad.mp4"
},
"concatenated": {
"robot": "/video/concat",
"use": {
"steps": [
{ "name": "intro", "as": "video_1" },
{ "name": "main", "as": "video_2" },
{ "name": "outro", "as": "video_3" }
]
},
"chapter_markers": true,
"transition": "crossfade",
"transition_duration": 1,
"ffmpeg_stack": "v7"
}
}
}
Cada capítulo toma el nombre de su archivo de entrada, sin la extensión. ffprobe los muestra en el
resultado:
$ ffprobe -v error -show_entries chapter=start_time,end_time:chapter_tags=title -of compact big-buck-bunny-10s_waves10_fake-ad.mp4
chapter|start_time=0.000000|end_time=9.000000|tag:title=big-buck-bunny-10s
chapter|start_time=9.000000|end_time=21.000000|tag:title=waves10
chapter|start_time=21.000000|end_time=26.000000|tag:title=fake-ad
Para dar títulos legibles a los capítulos, nombra los archivos de entrada según corresponda. Los tiempos de los capítulos tienen en cuenta la superposición cuando añades una transición, por lo que cada marcador sigue coincidiendo con su clip.
Subtítulos en negrita, cursiva y con contorno
🤖 /video/subtitle añade subtítulos incrustados en la imagen, y ahora puedes
aplicarles estilos con bold, italic y outline_width (de 0 a 10 píxeles). Esta Assembly recibe un
archivo .srt subido y un video importado:
{
"steps": {
":original": {
"robot": "/upload/handle"
},
"video": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/fake-ad.mp4"
},
"subtitled": {
"robot": "/video/subtitle",
"use": {
"steps": [
{ "name": "video", "as": "video" },
{ "name": ":original", "as": "subtitles" }
]
},
"subtitles_type": "burned",
"preset": "empty",
"font_size": 22,
"bold": true,
"outline_width": 4,
"ffmpeg_stack": "v7"
}
}
}
La mitad superior muestra el estilo predeterminado; la inferior muestra bold: true con outline_width: 4,
que sigue siendo legible sobre un fondo claro:

Los estilos solo se aplican a los subtítulos incrustados, no a las pistas de subtítulos. "preset": "empty" conserva
el formato MP4 de la entrada. Sin un ajuste preestablecido, el Robot recurre a uno antiguo de FLV.
Audio multilingüe en HLS
Para ofrecer un video en varios idiomas, ya no necesitas una escala de variantes de video por idioma.
🤖 /video/adaptive con audio_group: true empaqueta archivos
que solo contienen audio como pistas de audio alternativas, y cada variante de video hace referencia
a ellas. Así, los espectadores pueden cambiar de idioma en el reproductor sin volver a cargar el video:
{
"steps": {
"video": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/big-buck-bunny-10s.mp4"
},
"audio_en": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/joakim_karud-rock_angel.mp3"
},
"audio_de": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/german-anthem.mp3"
},
"video_480p": {
"use": "video",
"robot": "/video/encode",
"preset": "hls/480p",
"ffmpeg_stack": "v7"
},
"video_720p": {
"use": "video",
"robot": "/video/encode",
"preset": "hls/720p",
"ffmpeg_stack": "v7"
},
"aac_en": {
"use": "audio_en",
"robot": "/audio/encode",
"preset": "aac",
"ffmpeg_stack": "v7",
"ffmpeg": {
"t": 10,
"metadata:s:a:0": "language=eng"
}
},
"aac_de": {
"use": "audio_de",
"robot": "/audio/encode",
"preset": "aac",
"ffmpeg_stack": "v7",
"ffmpeg": {
"t": 10,
"metadata:s:a:0": "language=deu"
}
},
"hls": {
"use": {
"steps": ["aac_en", "aac_de", "video_480p", "video_720p"],
"bundle_steps": true
},
"robot": "/video/adaptive",
"technique": "hls",
"audio_group": true
}
}
}
Nuestros archivos de demostración son música, así que imagínalos como pistas de sonido en inglés y
alemán. t: 10 los recorta a la duración del video. El idioma de cada pista procede de su etiqueta
language, que se establece con la opción metadata:s:a:0. Los archivos que ya tienen una etiqueta de idioma
no necesitan esa opción. La lista de reproducción maestra resultante asigna nombres legibles a las
pistas, y el primer archivo de audio en use se convierte en el predeterminado. Si una pista tiene
una etiqueta de título, ese título se convierte en su nombre; de lo contrario, el Robot usa el nombre
del idioma. AUTOSELECT=YES permite que los reproductores seleccionen una pista para el idioma del espectador,
y el BANDWIDTH de cada variante incluye su audio:
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_audio",NAME="English",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="eng",CHANNELS="2",URI="128515_44100/128515_44100.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="group_audio",NAME="German",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="deu",CHANNELS="2",URI="128539_44100/128539_44100.m3u8"
#EXT-X-STREAM-INF:BANDWIDTH=797670,AVERAGE-BANDWIDTH=797670,RESOLUTION=852x480,CODECS="avc1.4d401f,mp4a.40.2",AUDIO="group_audio",FRAME-RATE=25
852x480_616860_25/852x480_616860_25.m3u8
Con audio_group, las variantes de video no contienen audio propio, así que proporciona cada idioma como
un archivo de audio independiente. Almacena los resultados con ${file.meta.relative_path} en la ruta, como se describe
en la documentación del Robot, para que las listas de reproducción encuentren sus segmentos.
CMAF: un conjunto de segmentos para HLS y DASH
Los dispositivos Apple reproducen HLS, y muchos otros reproductores prefieren MPEG-DASH. Con technique: "cmaf",
/video/adaptive escribe los segmentos MP4 fragmentados una sola vez, junto con una lista de reproducción HLS y un manifiesto DASH
que apuntan a esos mismos segmentos. Almacenas y guardas en caché una copia de tu video en lugar de dos:
{
"steps": {
"imported": {
"robot": "/http/import",
"url": "https://demos.transloadit.com/inputs/big-buck-bunny-10s.mp4"
},
"encoded_480p": {
"use": "imported",
"robot": "/video/encode",
"preset": "hls/480p",
"ffmpeg_stack": "v7"
},
"encoded_720p": {
"use": "imported",
"robot": "/video/encode",
"preset": "hls/720p",
"ffmpeg_stack": "v7"
},
"cmaf": {
"use": {
"steps": ["encoded_480p", "encoded_720p"],
"bundle_steps": true
},
"robot": "/video/adaptive",
"technique": "cmaf"
}
}
}
El resultado contiene playlist.m3u8 para HLS, playlist.mpd para DASH y los segmentos .m4s que
comparten. FFmpeg decodificó ambos manifiestos sin errores en nuestras pruebas. hls_playlist_name y
playlist_name cambian los nombres de los dos manifiestos.
Los ajustes preestablecidos incluidos hls/480p y hls/720p funcionan juntos en una escala de variantes CMAF,
incluso con la pequeña diferencia de relación de aspecto causada por redondear el ancho de 480p a
un número par.
Aprovechamos también para que /video/adaptive aplique ahora las opciones ffmpeg que le pases al empaquetar
HLS y CMAF, como hls_flags o start_number. Antes, las ignoraba sin avisar.
Videos de iPhone con audio espacial
Los videos grabados con audio espacial en los iPhone recientes contienen dos pistas de audio:
una pista AAC estéreo normal y una pista Apple Positional Audio que nuestro stack de codificación no
puede decodificar. Hasta hace poco, esa segunda pista hacía fallar toda la codificación.
/video/encode, 🤖 /audio/encode y
🤖 /speech/transcribe ahora omiten las pistas de audio que no pueden decodificar y
usan la pista estéreo. Puedes codificar el video, extraer su audio y transcribir una
grabación de iPhone que hayas subido en una sola Assembly:
{
"steps": {
":original": {
"robot": "/upload/handle"
},
"video": {
"robot": "/video/encode",
"use": ":original",
"preset": "web/mp4/240p",
"ffmpeg_stack": "v7"
},
"audio": {
"robot": "/audio/encode",
"use": ":original",
"preset": "aac",
"ffmpeg_stack": "v7"
},
"transcript": {
"robot": "/speech/transcribe",
"use": ":original",
"provider": "aws",
"format": "text",
"source_language": "en-US"
}
}
}
El audio espacial en sí no se conserva: el resultado de la codificación tiene la mezcla estéreo. Si la única pista de audio de un archivo es audio espacial, la codificación de audio y la transcripción siguen fallando, porque no hay nada que podamos decodificar.
Primeros pasos
Todo esto funciona con cualquier plan de suscripción. En el plan de suscripción gratuito Community, los resultados de audio y video se recortan, por lo que una transición o un capítulo posterior puede quedar fuera del resultado de una prueba. La documentación de los Robots 🤖 /video/concat, 🤖 /video/subtitle y 🤖 /video/adaptive detalla todos los parámetros, y puedes crear una cuenta gratuita para probarlos.
