Repita / faça loop de entrada de vídeo com ffmpeg?


52

Eu só quero fazer um loop em um vídeo mp4 com ffmpeg e manter as configurações e o codec atuais.

Por exemplo, se input.mp4 tem 0:10 de comprimento e eu gostaria de fazer um loop 4 vezes para que output.mp4 tenha 0:40, como eu poderia alterar a seguinte linha de comando para fazer isso?

ffmpeg -i input.mp4 -c copy output.mp4

Eu tentei...

ffmpeg -loop 4 -i input.mp4 -c copy output.mp4

... mas recebo o erro "Loop de opção não encontrado".


Use o quicktime 7 pro e mov container. Portanto, você não terá um tamanho de arquivo maior do que o código-fonte aberto.
Дмитрий Мышков

Respostas:


69

Concat desmuxer

Isso permite que você faça um loop de uma entrada sem precisar recodificar.

  1. Faça um arquivo de texto. Conteúdo de um arquivo de texto de exemplo para repetir 4 vezes.

    file 'input.mp4'
    file 'input.mp4'
    file 'input.mp4'
    file 'input.mp4'
    
  2. Em seguida, execute ffmpeg:

    ffmpeg -f concat -i list.txt -c copy output.mp4
    

Para usuários do Linux

Este exemplo é o mesmo que acima, mas você não precisa fazer manualmente list.txt:

for i in {1..4}; do printf "file '%s'\n" input.mp4 >> list.txt; done
ffmpeg -f concat -i list.txt -c copy output.mp4

Com os shells modernos mais usados, você pode até evitar a criação do list.txtarquivo completamente. Por exemplo, com o bash:

ffmpeg -f concat -i <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -c copy output.mp4

Veja também:


filtro de loop

Exemplo usando o filtro de loop para fazer loop 4 vezes, cada loop é de 75 quadros, cada loop ignora os primeiros 25 quadros da entrada:

ffmpeg -i input -filter_complex loop=loop=3:size=75:start=25 output
  • Ou use a abreviação: loop=3:75:25
  • A filtragem requer recodificação.
  • Este filtro coloca todos os quadros na memória .
  • Usar loop=3fará um loop 4 vezes.
  • Para fazer um loop infinitamente, use -1.
  • Você deve listar o número de quadros a serem repetidos (mostrado como 75 no exemplo acima). O valor máximo é 32767.
  • Veja também ffmpeg -h filter=loop.

filtro de filme

O filtro de filme tem uma opção de loop. Veja a resposta abaixo de Monah Tuk. A filtragem requer recodificação. Para áudio, use o filtro de filmes.


-stream_loop opção

Veja a resposta abaixo por Thingy e a resposta por Gyan.

Observe que esta opção era incorreta (consulte os relatórios de erros # 5719 , # 6121 e # 7043 ), portanto, pode não funcionar para construções antigas (qualquer coisa anterior a 2018/06/27, incluindo o ramo de lançamento do FFmpeg 4.0.x). Para usuários de compilações antigas, como mencionado por mulvya no ticket # 6121, uma solução alternativa é primeiro redimensionar para MKV ou TS e depois usar -stream_loopno próximo comando.


-loop opção

A -loopopção é específica para o desmuxador de arquivo de imagem e o muxer de gif , portanto, não pode ser usado para arquivos de vídeo típicos, mas pode ser usado para fazer loop infinito de uma série de imagens de entrada. Este exemplo repetirá repetidamente, mas -t 30limitará a duração da saída a 30 segundos:

ffmpeg -loop 1 -i %03d.png -t 30 output.mkv

Ou para repetir uma saída GIF:

ffmpeg -i input -loop 3 output.gif

Isso funciona bem com arquivos mp4?
Thomas King

3
Eu recebo este erro> <(for i in {1..4}; do printf "file '%s'\n" input.mp4; done) -bash: /dev/fd/63: Permission denied
JZ11 9/11

11
@ Jamesfzhang - Eu acho que é porque você precisa de um caminho absoluto para o arquivo (como explicado aqui: trac.ffmpeg.org/wiki/Concatenate ). Para isso, você pode escrever: ffmpeg -safe 0 -f concat -i <(para i em {1..4}; faça printf "arquivo '$ PWD' / '% s' \ n" input.mp4; ) -c cópia output.mp4
Plenus Franckly

11
Quanto a mim isso funciona para repetir tempo integral vídeo sem fames pular para 4 vezesffmpeg -i video.mp4 -filter_complex "loop=4:32767" output.mp4
Vlad

Esta questão é de 4 anos e ninguém notou que o link para a segunda questão na -stream_loopsecção está a apontar para o mesmo bilhete como o primeiro ...
Leonid Usov

15

Pelo menos no FFmpeg 2.8.x (mas o oldie também deve funcionar), você pode usar lavficomo formato de entrada e gráfico de filtro complexo usando moviee setptsfiltros como argumento para a -iopção.

Próximo comando fazendo este trabalho para você:

ffmpeg -re -f lavfi -i "movie=filename=input.mp4:loop=0, setpts=N/(FRAME_RATE*TB)" output.mp4

Zero loop=argumentos significa loop infinito. Valores maiores que conjuntos de zero repetem contagens. setptsfiltros necessários para o ajuste do PTS para repetições posteriores e posteriores; caso contrário, a maioria dos muxers de saída falhará com o aumento do PTS não monotônico: o loop não recalca o PTS.

Observe que o uso de filtros assumindo que ignorar quadros sem decodificação / codificação é impossível: por design, os filtros lidam apenas com quadros decodificados.

No FFmpeg 2.8.2, nova opção de entrada foi -stream_loopintroduzida. Primeiro, parece que funciona mais simples e permite copiar conteúdo sem transcodificar:

ffmpeg -re -stream_loop -1 -i input.mp4 -c copy -y output.mp4

Mas ele não recalcula o PTS e o arquivo de saída está errado. Se você adicionar um filtro para corrigir o PTS (consulte setpts), deverá remover -c copytambém. Somente filtros de fluxo de bits podem lidar com pacotes codificados, mas não há nenhum filtro de fluxo de bits para corrigir o PTS (consulte: https://ffmpeg.org/ffmpeg-bitstream-filters.html )

Em qualquer caso, o ffmpeg na segunda passagem falha com erro:

input.mp4: Resource temporarily unavailable

Solução conhecida para mim : use o contêiner para o arquivo de entrada sem limites de PTS (contêiner de streaming). Um deles, me conhece, é o MPEG-TS. Então, você pode simplesmente converter seu arquivo MP4 para o MPEG-TS:

ffmpeg -i input.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts input.ts

E use o próximo comando para compor o arquivo infinito:

ffmpeg -re -stream_loop -1 -i input.ts -c copy -strict -2 -bsf:a aac_adtstoasc -y output.mp4

(filtros de fluxo de bits devem ser usados ​​apenas se necessário, nas minhas amostras é necessário)

FFmpeg> = 2.8.2 é necessário neste caso.


11
A execução desse comando gera um erro: "[mp4 @ 00000000053fa1a0] Não foi possível encontrar a tag do codec rawvideo no fluxo # 0, o codec atualmente não é suportado no contêiner". Se eu adicionar -vcodec h264 antes da entrada, esse erro desaparecerá, mas o codificador não sairá. Fornecer uma contagem de loop diferente de zero produz muitos erros, mas sai. O arquivo não é uma saída válida.
Gyan

11
A documentação para stream_loop diz "Loop 0 significa nenhum loop, loop -1 significa loop infinito".
Gyan

Parece arquivos de entrada incorretos. Você poderia compartilhar? "Loop 0 significa sem loop, loop -1 significa loop infinito." - Parece que eu ver docs velhos :-)
Monah Tuk

11
Eu esqueci: filtros assumindo transcodificação (decodificar / codificar). Por design. Então você deve remover -c copy. Resposta corrigida.
Monah Tuk

11
É bom saber, mas essa é uma limitação significativa se você tiver um loop grande para gerar.
Gyan

14

Com o ffmpeg 2.8.4, o comando a seguir cria o output.mp4 que é uma cópia repetida do input.mp4 até o processo ffmpeg ser parado:

ffmpeg -stream_loop -1 -i input.mp4 -c copy output.mp4

Este comando não será finalizado por si só, e o arquivo de saída crescerá infinitamente.


2
Parece ser o método mais rápido
josef

2
O método mais rápido é um eufemismo, esse método aumenta vídeos de várias horas em questão de segundos.
SleighBoy

Este é um ótimo método conveniente, porque não há necessidade de criar um arquivo com linhas repetidas.
Markus Zeller

-1

P: "... como eu poderia alterar a seguinte linha de comando para fazer isso? Ffmpeg -i input.mp4 -c copy output.mp4"?

R: O método simples que evita problemas de quais comandos funcionam com qual versão é a 'solução trivial':

ffmpeg -i input.mp4 -i input.mp4 -i input.mp4 -i input.mp4 -c copy output.mp4

Veja também: https://trac.ffmpeg.org/wiki/Concatenate para muitos exemplos.


2
Isso não faz nenhuma concatenação. Pelo menos um dos métodos concat deve ser usado: protocolo, filtro ou desmuxer. Nesse comando, o mapeamento automático do ffmpeg selecionará um vídeo, um áudio e um fluxo de legendas entre as entradas. Como são idênticos, é equivalente ao primeiro comando do OP.
Gyan

Obrigado por testar o Mulvya, pois difere do comportamento descrito nos Documentos: ffmpeg.org/ffmpeg.html#Description - Se houver semelhança nos nomes dos arquivos usando "-i -i /tmp/test%d.mp4" ( et al.) também é possível.
Rob
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.