Como cortar partes de vídeo indesejadas e juntar as restantes em um vídeo usando o FFmpeg?

2

Eu li sobre o corte e emenda usando concat mas isso não é suficiente para mim.

Eu gostaria de cortar partes de vídeo marcadas e participar em um único arquivo de vídeo sem recodificação. É possível cortar e mesclar (na memória) de uma só vez?

Não deve haver limite teórico sobre o número de partes de vídeo a serem cortadas ou unidas. O áudio deve estar em sincronia.

Vídeo: H.264 + AAC

Editar:

Das respostas, aprendi que a codificação de vídeo ainda é necessária.

Gostaria de esclarecer que o corte de videoclipes no meio de um arquivo de vídeo pode ser feito em várias etapas. Eu estava pensando que o processamento do vídeo de uma só vez seria o melhor desempenho salvando alguma atividade de E / S. No entanto, não é um objetivo em si.

J Pollack
fonte
Em vez de descer a questão, por favor, comente-a para que eu possa melhorá-la.
J Pollack
Para esclarecer - você quer dizer que tem um arquivo de entrada e deseja unir várias seções de entrada / saída e, em seguida, combinar essas seções em uma única saída?
occvtech
Uma solução geral sem qualquer recodificação não é possível: a menos que você inicie e pare em um I-Frame, o quadro em que você parar será codificado em relação a um quadro excluído.
David Yaw
@occvtech: Você está absolutamente certo - eu quero cortar algumas seções de um arquivo de vídeo.
J Pollack
@ David-Yaw: Como eu começaria ou pararia em um I-Frame? Eu sou um novato absoluto no mundo do vídeo, mas tenho alguns antecedentes de programação. Você poderia me fornecer uma amostra de algum tipo?
J Pollack

Respostas:

5

Sua pergunta, se eu entendi direito, tem quatro partes principais:

  • Como cortar um segmento de tempo de um filme
  • Como mesclar vários segmentos juntos
  • Como fazer o acima sem transcodificar o filme, portanto não perdendo qualidade
  • Como fazer o acima eficientemente em termos de velocidade

Cortando um segmento de tempo

Você pode cortar um segmento pulando para o ponto inicial com o -ss opção, em seguida, definir a duração do segmento com -tou definir o ponto final com -to:

# skip 30 seconds, then copy the next 60 seconds
ffmpeg -ss 30 -t 60 full-movie.mp4 segment.mp4

Na documentação do ffmpeg, por favor consulte a seção 5.4 Opções Principais sobre a diferença entre colocar o -ss e -t opções antes do arquivo de entrada ou antes do arquivo de saída. Depois de experimentar isso, você poderá encontrar essa diferença como relevante no seu caso.

Nota importante: O exemplo acima faz com que o vídeo seja transcodificado. Discutiremos abaixo a possibilidade de fazer isso sem transcodificação.

Mesclando vários segmentos

Existem três métodos principais para realizar uma mesclagem de filmes, dois deles são melhor explicados neste Artigo ffmpeg wiki e o terceiro é o demuxer concat . Se todos os seus segmentos forem idênticos em termos de formato de contêiner e especificação de codificação / v, você provavelmente encontrará o método mais fácil de ser concat: protocolo:

# merge the segments
ffmpeg -i "concat:seg1.mp4|seg2.mp4|seg3.mp4" final.mp4

É importante notar que esta fusão, como o corte, mais uma vez transcodifica o filme, por isso temos aqui uma transcodificação de uma transcodificação, potencialmente degradando a qualidade do vídeo, por isso realmente queremos evitar essa transcodificação o máximo que pudermos!

Cortando e mesclando sem transcodificação

A razão pela qual os exemplos nas seções anteriores exigem transcodificação é porque cada arquivo e cada segmento resultante é um filme autônomo que foi embalado para fornecer todas as coisas que você espera quando você abre um filme completo, como a duração do filme e outros metadados. Mas, ei, você não está tentando reproduzi-los como filmes independentes, você quer que esses segmentos se tornem parte de um fluxo de vídeo maior. Então, ao invés de servir o ffmpeg com filmes em caixa, você deve re-empacotar novamente os arquivos de entrada em um contêiner de streaming em tempo real, esquecendo-se das coisas de cabeçalho que você realmente não precisa neste momento. No caso do H.264, o formato streaming mux é chamado de MPEG-TS, e aqui está como você redireciona seu fluxo sem transcodificá-lo:

# re-muxing the whole movie (see a better option in next example)
ffmpeg -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb full-movies-as-ts.ts

Bem, já que você já está nessa, também pode aproveitar essa oportunidade para cortar apenas o segmento de que precisa:

# skip 30 seconds and re-mux a 60 seconds segment
ffmpeg -ss 30 -t 60 -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb segment.ts

Quando você mescla os segmentos TS, você também pode voltar para um contêiner mp4:

# merge the segments and re-mux them as mp4
ffmpeg -i "concat:seg1.ts|seg2.ts|seg3.ts" -c:v copy -c:a copy -movflags empty_moov -flags global_header -bsf:v dump_extra edited-final.mp4

Então agora temos tudo feito sem nunca transcodificar o filme, preservando a qualidade original. Mas como sempre, há uma ressalva ...

EMBARGO : O corte pode ser feito apenas em um limite de quadro-chave. Explicação: O H.264 organiza os quadros compactados em pacotes, cada um começando com uma imagem completa e compactada do primeiro quadro, seguida pelos deltas dos quadros a seguir, diminuindo assim o armazenamento necessário para cada pacote. Para nosso propósito, cada pacote é como um zíper fechado de todos os quadros por essa duração - é tudo ou nenhum. Se você quer apenas um pedaço do pacote, então você tem que descompactá-lo e zip-lo de volta, em outras palavras - para transcodificá-lo. Portanto, o método acima é relevante apenas se você tiver um quadro-chave em cada posição em que deseja cortar o filme. Por exemplo, se você tiver um quadro-chave a cada 5 segundos, poderá cortá-lo a cada 5 segundos.

Então agora a questão é se você pode aceitar as limitações dos pontos de corte, especialmente porque você provavelmente não tem idéia de onde no seu filme você tem keyframes. E essa é a razão que eu sugeri acima para ler em 5.4 Opções Principais sobre a especificação -s e -t antes da entrada ou antes da saída. Se você especificar antes da entrada, o ffmpeg encontrará um quadro-chave próximo para realizar sua solicitação, que será "mais ou menos" onde você deseja executar o corte. Se você não se importa com a exatidão do corte, então bom, vá em frente.

Mas se você precisar que o corte esteja na posição exata, então você não tem escolha, você deve decodificar o filme para identificar o quadro que está procurando. Bem, pelo menos temos alguns boa notícia: em vez de transcodificação e recodificação, você pode fazer com uma única transcodificação, o que melhora um pouco a situação:

# skip PRECISELY 30 seconds and transcode a 60 seconds TS segment
ffmpeg -i full-movie.mp4 -ss 30 -t 60 -bsf:v h264_mp4toannexb segment.ts

Como os segmentos resultantes estarão em TS, não há necessidade de outra transcodificação ao mesclar os segmentos juntos.

Rapidez

No Artigo ffmpeg wiki sobre fusão Há uma explicação sobre como executar todo o processo através de pipes, eliminando assim a necessidade de arquivos intermediários e acelerando todo o processo. NÃO. Vai te levar mais longo . A razão pela qual fazer tudo na memória vai demorar mais, não é porque vai durar mais tempo, mas porque você não terá resultados intermediários enquanto imagina como fazer a coisa toda, e você se verá executando todo o processo novamente e novamente. Então a teoria dos tubos é boa, mas no seu caso você deve começar a trabalhar e aperfeiçoar cada passo. Você verá que fazer tudo funcionar e produzir um resultado decente exigirá mais alguns ajustes e ajustes. Depois de dominar todo o processo e desejar fazer alguns scripts para edição em massa automatizada, você poderá revisitar o conceito de tubulação.

Espero que o acima ajuda.

avnr
fonte
Uhh tantos switches e parâmetros. :) Como na verdade o corte seria feito no arquivo TS? É possível cortar vários pedaços de uma só vez?
J Pollack
Nesse caso, a questão é vaga, como se você já soubesse como cortar e mesclar, mas queria saber se isso pode ser feito sem recodificar. Então agora você me confundiu - por que é importante para você se tudo é feito na memória de uma só vez?
avnr
Desculpe se eu te confundi. Teoricamente eu sei tirar um vídeo - cortar o começo e o fim de um vídeo. No entanto, não sei como cortar várias partes do meio de um vídeo. Eu também queria saber se é possível fazer de uma só vez (para performance). Não é tão importante assim.
J Pollack
Ok, acho que entendi. Vou editar a resposta e vamos dar a partir daí, quando eu postar a edição, deixe-me saber se estamos na mesma página.
avnr
Editado para sua revisão
avnr