FFmpeg divide o vídeo e mescla de volta

8

Estou tentando usar o FFmpeg para dividir o vídeo com base em algumas entradas start_time e end_time e substituí-las por outros arquivos de vídeo. Por exemplo, para a entrada 10 15 , precisarei substituir os segundos EXATOS 10 to 15 por outro vídeo.

OK. O que me vem à mente é isto:

  1. Primeiro divida o vídeo (neste caso, 0-10, 10-15 e 15 final)
  2. Substitua o 10-15 pelo outro vídeo
  3. Mesclar todos os sub-vídeos de volta

Primeira pergunta: esta é a melhor e mais rápida solução? Temos um comando mais fácil ou outras ferramentas para substituir um período de tempo específico em vídeo por outro vídeo?

Segunda pergunta: Assumindo que o FFmpeg é a solução viável, quando eu simplesmente uso o comando ffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4 , meu código de processamento de vídeo não pode ler e processar o arquivo. Eu usei a ferramenta mediainfo para comparar os dois arquivos e notei diferenças nos tamanhos dos cabeçalhos, enquanto todas as coisas relacionadas ao codec de vídeo eram as mesmas. Eu notei que o TAMANHO DA PLATAFORMA é diferente, o que aparentemente está causando o problema. Existe alguma maneira de forçar o tamanho do cabeçalho também (além dos codecs) a ser o mesmo?

ATUALIZAÇÃO: Aqui está o arquivo .mp4 original que funciona bem no emulador.

    
por Ariana 14.07.2017 / 18:27

1 resposta

6

Usando trim e concat - arquivos de origem com codecs diferentes

Para isso, certifique-se de que seus arquivos individuais tenham a mesma resolução e, idealmente, a mesma subamostragem de framerate e chroma, etc. Isso evitará erros ou falhas durante a concatenação.

Você pode fazer tudo de uma só vez sem dividir o arquivo, usando os trim e concat filtros:

ffmpeg -i edv_g24.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[v0][v1][v2]concat=n=3:v=1:a=0[out]" \
-map "[out]" output.mp4

Aqui, trim é usado para especificar as partes individuais dos fluxos de vídeo de entrada ( 0:v , 1:v ) que você deseja concatenar posteriormente. Essas partes são nomeadas v0 a v2 . (O filtro setpts redefine os registros de data e hora dessas partes individuais para 0, o que é necessário para a concatenação). Mais tarde, nós concatenamos as três partes.

Se você quiser cortar de um determinado timestamp até o final, use trim=start=15 em vez de especificar o intervalo.

Se os seus arquivos tiverem áudio, você terá que aparar esses fluxos separadamente:

ffmpeg -i edv_g24_2.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[1:a]atrim=0:5,asetpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; \
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4

Observe que o vídeo e o áudio serão recodificados neste caso. Não se esqueça de especificar os destinos de qualidade de saída apropriados (por exemplo, -crf para x264, x265 ou libvpx-vp9). Você pode ler mais sobre isso na Wiki do FFmpeg, por exemplo. para VP9 ou H.264 .

Usando segmentos individuais

Se você quiser dividir os clipes e depois remontá-los:

ffmpeg -i edv_g24.mp4 -ss 0 -to 10 -c copy part1.mp4
ffmpeg -i edv_g24.mp4 -ss 10 -to 15 -c copy part2.mp4
ffmpeg -i edv_g24.mp4 -ss 15 -c copy part3.mp4

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][1:v][2:v]concat=n=3:v=1:a=0[outv]" \
-map "[outv]" -t 30 output.mp4

Se os arquivos tiverem áudio, use a mesma abordagem acima:

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -t 30 output.mp4

Isso recodificará novamente o fluxo de vídeo. É um pouco mais simples, mas deveria ser equivalente ao método acima.

Usando concat demuxer

Você pode, em princípio, também tentar concatenar os fluxos de bits sem re-codificá-los, usando o demuxer de concat. Crie um arquivo chamado concat.txt e adicione as seguintes entradas (correspondentes aos clipes de vídeo criados acima):

file 'part1.mp4'
file 'short-video.mp4'
file 'part3.mp4'

Em seguida, concatene esses arquivos individuais:

ffmpeg -f concat -i concat.txt -c copy output.avi

No entanto, isso requer que seus clipes tenham o mesmo codec, resolução, framerate etc. - por isso não funciona com todos os tipos de fontes heterogêneas.

Usando o protocolo concat

O tipo de concatenação em nível de arquivo acima pode ser obtido usando o protocolo concat , com o mesmo tipo de restrições acima (mesmo codec, resolução, etc.):

ffmpeg -i "concat:part1.avi|part2.avi|part3.avi" -c copy output.mp4

Para mais informações sobre concatenação, leia a página do Wiki do FFmpeg correspondente .

    
por 15.07.2017 / 10:05