Novidades em vídeo: transições, capítulos, CMAF e mais
Nos últimos meses, adicionamos alguns recursos de vídeo, vários deles a pedido de clientes. Ainda não havíamos escrito sobre eles, então reunimos todos aqui, cada um com Assembly Instructions que executamos em produção antes de publicar.
Transição cruzada entre clipes
🤖 /video/concat une vídeos em sequência. Defina transition como
crossfade ou fade_to_black, e os clipes se misturam em vez de passar por um corte seco:
{
"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"
}
}
}
O áudio acompanha a transição cruzada da imagem. Veja quadros imediatamente antes, durante e logo após a transição:

Alguns pontos importantes:
transition_durationé medido em segundos e tem o valor padrão1. Seu limite é metade da duração do clipe mais curto de cada par.- Os clipes se sobrepõem durante a transição, então o resultado fica mais curto: nossos clipes de
10 e 13 segundos geraram um vídeo de 22 segundos. Isso também vale para
fade_to_black. - Uma transição exige que recodifiquemos o vídeo, então o processamento demora mais do que uma simples junção, que pode copiar os fluxos sem alterações.
- 🤖 /video/merge aceita os mesmos dois parâmetros, mas
/video/concaté mais adequado para unir clipes. Ele lida com clipes de tamanhos e taxas de quadros diferentes, convertendo-os primeiro para especificações compatíveis, e mantém o formato MP4 da saída.
Marcadores de capítulo para vídeos unidos
Ao unir uma introdução, o conteúdo principal e um encerramento, defina chapter_markers: true, e os players
que oferecem suporte a capítulos poderão ir diretamente 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 recebe o nome do arquivo de entrada, sem a extensão. ffprobe mostra os capítulos no
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 legíveis aos capítulos, nomeie seus arquivos de entrada de acordo com esses títulos. Os tempos dos capítulos consideram a sobreposição quando você adiciona uma transição, de modo que cada marcador continue alinhado ao seu clipe.
Legendas em negrito, itálico e com contorno
🤖 /video/subtitle grava as legendas na imagem, e agora você pode
estilizá-las com bold, italic e outline_width (0 a 10 pixels). Esta Assembly recebe um
arquivo .srt enviado por upload e um vídeo 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"
}
}
}
A metade superior mostra o estilo padrão; a metade inferior mostra bold: true com outline_width: 4,
que mantém o texto legível sobre um fundo claro:

O estilo só se aplica às legendas gravadas na imagem, não às faixas de legenda. "preset": "empty" mantém
o formato MP4 da entrada. Sem uma predefinição, o Robot usa uma predefinição antiga de FLV.
Áudio em vários idiomas no HLS
Para oferecer um vídeo em vários idiomas, você não precisa mais de um conjunto separado de variantes
de vídeo para cada idioma. 🤖 /video/adaptive com audio_group: true empacota arquivos que contêm apenas áudio
como faixas de áudio alternativas, e cada variante de vídeo faz referência a elas. Assim, o público
pode trocar de idioma no player sem recarregar o vídeo:
{
"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
}
}
}
Nossos arquivos de demonstração contêm música, então imagine que sejam uma faixa de áudio em inglês
e outra em alemão. t: 10 corta essas faixas para que tenham a mesma duração do vídeo. O idioma de cada faixa vem da
sua tag language, definida pela opção metadata:s:a:0. Arquivos que já têm uma tag de idioma não precisam dessa opção.
A playlist mestre resultante atribui nomes legíveis às faixas, e o primeiro arquivo de áudio em
use se torna o padrão. Se uma faixa tiver uma tag de título, esse título será seu nome; caso contrário,
o Robot usará o nome do idioma. AUTOSELECT=YES permite que os players selecionem uma faixa no idioma de quem assiste, e o
BANDWIDTH de cada variante de vídeo inclui seu áudio:
#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
Com audio_group, as variantes de vídeo não contêm áudio próprio, então forneça cada idioma em um
arquivo de áudio separado. Armazene os resultados com ${file.meta.relative_path} no caminho, conforme descrito
na documentação do Robot, para que as playlists encontrem seus segmentos.
CMAF: um conjunto de segmentos para HLS e DASH
Dispositivos Apple reproduzem HLS, e muitos outros players preferem MPEG-DASH. Com technique: "cmaf",
/video/adaptive grava os segmentos de MP4 fragmentado uma única vez, além de uma playlist HLS e um manifesto DASH
que apontam para esses mesmos segmentos. Você armazena e mantém em cache uma cópia do vídeo em vez de duas:
{
"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"
}
}
}
O resultado contém playlist.m3u8 para HLS, playlist.mpd para DASH e os segmentos .m4s que ambos
compartilham. O FFmpeg decodificou os dois manifestos sem erros nos nossos testes. hls_playlist_name e
playlist_name renomeiam os dois manifestos.
As predefinições padrão hls/480p e hls/720p funcionam juntas em um conjunto de variantes de vídeo CMAF, mesmo com a pequena
diferença na proporção causada pelo arredondamento da largura de 480p para um número par.
Aproveitamos também para fazer com que /video/adaptive aplique as opções ffmpeg que você fornece ao empacotar
HLS e CMAF, como hls_flags ou start_number. Antes, essas opções eram ignoradas sem aviso.
Vídeos de iPhone com áudio espacial
Vídeos gravados com áudio espacial em iPhones recentes contêm duas faixas de áudio: uma faixa AAC
estéreo comum e uma faixa Apple Positional Audio que nosso stack de codificação não consegue
decodificar. Até recentemente, essa segunda faixa fazia toda a codificação falhar.
/video/encode, 🤖 /audio/encode e
🤖 /speech/transcribe agora ignoram as faixas de áudio que não conseguem decodificar e
usam a faixa estéreo. Você pode codificar o vídeo, extrair seu áudio e transcrever uma gravação de
iPhone enviada por upload em uma única 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"
}
}
}
O áudio espacial em si não é mantido: o resultado codificado contém a mixagem estéreo. Se a única faixa de áudio de um arquivo for áudio espacial, a codificação de áudio e a transcrição ainda falham, porque não há nada que possamos decodificar.
Primeiros passos
Tudo isso funciona em qualquer plano. No plano gratuito Community, os resultados de áudio e vídeo são cortados, então uma transição ou um capítulo posterior pode ficar de fora do resultado de um teste. A documentação dos Robots 🤖 /video/concat, 🤖 /video/subtitle e 🤖 /video/adaptive lista todos os parâmetros, e você pode criar uma conta gratuita para experimentar esses recursos.
