Convertendo quadros PNG em vídeo a 1 FPS

21

Tenho quadros de vídeo no formato PNG a 1 FPS e estou tentando convertê-los em um vídeo usando ffmpeg.

Se eu fizer algo assim:

ffmpeg -i data/input-%4d.png data/output.mp4

Eu recebo um vídeo a 25FPS, que é basicamente um avanço muito rápido da entrada (que é capturada a 1FPS).

Se eu tentar:

ffmpeg -i data/input-%4d.png -r 1 data/output.mp4

Eu recebo algo que o VLC não quer jogar :)

Agora, se eu pegar o primeiro vídeo (o FF) e aplicar um filtro para abrandá-lo (por exemplo -filter:v 'setpts=24.0*PTS'), posso fazê-lo tocar como um vídeo de 1 FPS, mas é claro que o preço é o tamanho do arquivo. Está gerando um monte de quadros repetidos, eu acho.

Então, a questão é como criar um vídeo com exatamente 1 FPS e que seja reproduzido nessa velocidade? O formato de saída, btw, não é tão importante para mim.

Assaf Lavie
fonte
Não sei se ffmpegé inteligente o suficiente para descobrir o codec de vídeo apenas na extensão de arquivo no formato container .mp4. Tente adicionar -vcodec libx264 -vpre hqà linha de comando, para informar os parâmetros de codec e codificação.
Warren Young
Na verdade, percebi tudo bem, e como mencionei, funcionou bem e só produziu resultados estranhos quando adicionei -r 1.
Assaf Lavie
Eu acho que você pode ter melhor sorte em uma resposta ffmpeg em stackoverflow.com ou superuser.com .
Damien

Respostas:

19

Se você deseja uma linha única para o FFMPEG que gera um vídeo que é reproduzido a 1 quadro por segundo, o que você deseja fazer é especificar as taxas de quadros para a entrada e a saída, assim:

ffmpeg -r 1 -i data / input-% 4d.png -pix_fmt yuv420p -r 10 data / output.mp4

Os -r 1meios que o vídeo será reproduzido em 1 das imagens originais por segundo.
Os -r 10meios que o vídeo será reproduzido a 10 quadros por segundo.

( -pix_fmt yuv420pEstá disponível para garantir a compatibilidade com uma ampla variedade de programas de reprodução. É necessário aqui, por exemplo, para que o vídeo seja reproduzido pelo Windows Media Player.)

Testei muitas taxas de quadros de saída diferentes e 10 parece ser o número mais baixo que você pode usar que ainda produzirá um vídeo que o VLC reproduzirá.

Obviamente, o comando acima significa que cada imagem original está sendo multiplicada, mas é um método mais simples do que o "abrandar" que você mencionou e, dependendo do codec, pode não produzir um vídeo muito maior que um verdadeiro 1-FPS vídeo.

Para testar isso, acabei de produzir um verdadeiro vídeo de 1 FPS, que chegou a 2,24 kiB. Em seguida, produzi um vídeo com as mesmas imagens de entrada, mas com saída a 24 FPS, e saiu para 5,76 kiB. Isso é apenas o dobro do tamanho, e nem perto de 24 vezes o tamanho. :)

SOU
fonte
+1 em -pix_fmt. Fácil esquecer algumas pessoas insistem em usar WMP :-)
Smalltown2k
por que você deseja que o formato de saída seja 10 fps enquanto a entrada é apenas 1? Não criaria quadros redundantes de 90% exatamente iguais?
Herbert
@ Herbert cria quadros redundantes para que você possa obter uma taxa de quadros de até 10, o que é feito apenas para que o VLC não reclame e visualmente não mude o vídeo. O codificador é inteligente o suficiente para ver que os quadros são todos idênticos, para que você não termine com um arquivo muito maior
chiliNUT
@chiliNUT claro, a coisa do quadro-chave, que nem todos os formatos, mas a maioria dos formatos sãos serve. Obrigado!
Herbert
5

Use ambos -frameratee-r

Por exemplo, para ter um vídeo final parecido com 1FPS:

ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
    -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

É semelhante ao que Converter quadros PNG em vídeo a 1 FPS | O Unix e Linux Stack Exchange diz, mas eu precisava, em -frameratevez de -rfuncionar.

Isso é mencionado no wiki em: http://trac.ffmpeg.org/wiki/Slideshow#Framerates

Ele define a taxa de quadros de saída para a 30qual o VLC pode manipular e copia cada imagem 30 vezes, para que o vídeo de saída pareça estar em 1 FPS. Veja também: Problemas de reprodução no VLC com vídeo de baixa taxa de quadros por segundo usando ffmpeg | Estouro de pilha

O VLC pode então reproduzir o vídeo normalmente.

Testado no Ubuntu 16.10, VLC 2.2.4, ffmpeg3.0.5, em um diretório com 10 PNGs.

Consulte também: /programming/19267443/vlc-freezes-for-low-1-fps-video-created-from-images-with-ffmpeg

Ciro Santilli adicionou uma nova foto
fonte
Qual é a diferença entre -re -framerate?
Royi 17/03/19
@ Royi Eu realmente não sei, exceto que é a única coisa que funcionou para mim :-) Mas se você conseguiu extraí-lo das manpáginas, avise-me ;-) Uma citação significativa é "-r opção de entrada, ignore os registros de data e hora armazenados no arquivo e gere registros de data e hora assumindo taxa de quadros constante fps.Não é o mesmo que a opção -framerate usada para alguns formatos de entrada como image2 ou v4l2 (costumava ser o mesmo em versões anteriores do FFmpeg). Em caso de dúvida, use -framerate em vez da opção de entrada -r. "
Ciro Santilli # 17/17
3

E se você aumentar um pouco o segundo exemplo da seguinte maneira:

$ ffmpeg -r 1 -i data/input-%4d.png -c:v libx264 out.mp4

As -r 1necessidades vêm antes dos arquivos .png, não depois.

Na documentação do FFmpeg :

Como regra geral, as opções são aplicadas ao próximo arquivo especificado. Portanto, a ordem é importante e você pode ter a mesma opção na linha de comando várias vezes. Cada ocorrência é aplicada ao próximo arquivo de entrada ou saída.

slm
fonte
Infelizmente, isso não funciona. Entretanto, mencionar que o pedido é importante me salvou muito tempo. Obrigado.
Mohammed Noureldin
0

Este é um erro no VLC (que ainda existe na versão 3.0.6). Após algumas experiências, percebi que o VLC falha em vídeos com FPS menor que 10 . Portanto, todos os vídeos com 10 FPS ou mais não devem ser um problema. Portanto, atualmente não há uma maneira limpa de obter um vídeo com 1 FPS que pode ser reproduzido no VLC ( não desista, continue lendo ).

Uma solução alternativa é, como mostrado na resposta acima, falsificar o efeito de 1 FPS duplicando as imagens (quando na verdade temos um FPS igual a 10 ou mais, o que é bom para o VLC).

Exemplo: se você possui uma pasta com 12 imagens e deseja gerar um vídeo com 1 FPS (reproduzível no VLC), é necessário duplicar cada imagem várias vezes (digamos 10 vezes) e informar ao FFMPEG para gerar um vídeo de 10 FPS. Dessa forma, obteremos um vídeo com um total de quadros de 120, onde cada imagem será reproduzida por 1 segundo (duplicada 10 vezes), o que é simplesmente falso para 1 FPS.

Prefiro usar o fpsparâmetro do que-r (o que é mostrado em outra resposta) que pode, em alguns casos, ser problemático (de acordo com a documentação oficial ).

ffmpeg -framerate 1 -i "img (%d).jpg" -c:v libvpx-vp9 -vf "fps=10,format=yuv420p" out.mkv

Como a entrada -framerateé menor que a saída fps, o FFMPEG duplicará os quadros para atingir a taxa de quadros de saída desejada (que é 10, de acordo com o comando acima).

Também é importante notar que a ordem -frameratee -vf fpsé importante , pois essa configuração será aplicada ao próximo vídeo mencionado (entrada ou saída). Isso está de acordo com os documentos oficiais :

as opções são aplicadas ao próximo arquivo especificado. Portanto, a ordem é importante ...

Mohammed Noureldin
fonte