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 -t
ou 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.