Tenho quadros de vídeo no formato PNG a 1 FPS e estou tentando convertê-los em um vídeo usando o 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 é capturado a 1FPS).
Se eu tentar:
ffmpeg -i data/input-%4d.png -r 1 data/output.mp4
Recebo algo que o VLC não quer reproduzir 🙂
Agora, se eu pegar o primeiro vídeo (o FF) e aplicar um filtro para desacelerá-lo (por exemplo, -filter:v "setpts=24.0*PTS"
), posso fazê-lo reproduzir como um vídeo de 1 FPS, mas é claro que o preço é o tamanho do arquivo. Ele está gerando um monte de quadros repetidos, eu acho.
Então, a questão é como eu crio um vídeo que tem exatamente 1 FPS e realmente reproduz nessa velocidade? O formato de saída, aliás, não é ” isso é importante para mim.
Comentários
Resposta
Se você quiser um one-liner para FFMPEG que gere um vídeo reproduzido a 1 quadro por segundo, o que você deseja fazer é especificar as taxas de quadros para entrada e saída, como este:
ffmpeg -r 1 -i data / input-% 4d.png -pix_fmt yuv420p -r 10 data / output.mp4
O -r 1
significa que o vídeo será reproduzido a 1 das imagens originais por segundo.
O -r 10
significa que o vídeo será reproduzido a 10 quadros por segundo.
(O -pix_fmt yuv420p
existe apenas para garantir a compatibilidade com uma ampla gama de programas de reprodução. É necessário aqui, por exemplo, para que o vídeo possa ser 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 e ainda produzirá um vídeo que o VLC irá reproduzir.
Claro, o comando acima significa que cada imagem original está sendo multiplicada, mas é um método mais simples do que o “diminuir a velocidade” que você mencionou e, dependendo do codec, pode não produzir um vídeo muito maior do que um vídeo real de 1 FPS.
Para testar isso, acabei de produzir um vídeo real de 1 FPS, que saiu para 2,24 kiB. Em seguida, produzi um vídeo com as mesmas imagens de entrada, mas saída a 24 FPS, e saiu para 5,76 kiB. Isso é quase o dobro do tamanho e nem perto de 24 vezes o tamanho. 🙂
Comentários
- +1 em -pix_fmt. Fácil de esqueça que algumas pessoas insistem em usar WMP 🙂
- por que você quer que o formato de saída seja 10 fps enquanto a entrada é apenas 1? Não ‘ criar 90% de quadros redundantes que são exatamente iguais?
- @Herbert ele cria quadros redundantes para que você possa obter a taxa de quadros de até 10, o que é feito apenas para que o VLC não ‘ t reclama , e visualmente não ‘ t altera o vídeo. O codificador é inteligente o suficiente para ver que os frames são todos idênticos, então você não ‘ não acaba com um arquivo muito maior
- @chiliNUT clear, o quadro-chave, que nem todos os formatos, mas a maioria dos formatos sensatos, servem. Obrigado !
Resposta
Use ambos -framerate
e -r
Por exemplo, para ter um vídeo final em 1FPS:
ffmpeg -framerate 1 -pattern_type glob -i "*.png" \ -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
Isso é semelhante ao que Convertendo quadros PNG em vídeo a 1 FPS | Unix & Linux Stack Exchange diz, mas eu precisava de -framerate
em vez de -r
para que funcione.
Isso é mencionado no wiki em: http://trac.ffmpeg.org/wiki/Slideshow#Framerates
Ele define a taxa de quadros de saída para 30
, que o VLC pode manipular, e copia cada imagem 30 vezes, para que o vídeo de saída pareça estar a 1 FPS. Veja também: Problemas de reprodução no VLC com vídeo de baixo fps de imagens usando ffmpeg | Stack Overflow
O VLC pode então reproduzir o vídeo normalmente.
Testado no Ubuntu 16.10, VLC 2.2.4, ffmpeg
3.0.5, em um diretório com 10 PNGs.
Veja também: https://stackoverflow.com/questions/19267443/vlc-freezes-for-low-1-fps-video-created-from-images-with-ffmpeg
Comentários
- Qual ‘ s a diferença entre
-r
e-framerate
? - @Royi eu não ‘ realmente sei, exceto que é a única coisa que funcionou para mim 🙂 Mas se você conseguiu extraia das páginas
man
, deixe-me saber 😉 Uma citação significativa é ” -r Como opção de entrada, ignore carimbos de data / hora armazenados no arquivo e, em vez disso, geram carimbos de data / hora assumindo fps de taxa de quadros constante. Não é o mesmo que a opção -framerate usada para alguns formatos de entrada como image2 ou v4l2 (costumava ser a mesma em versões anteriores do FFmpeg). Em caso de dúvida, use -framerate em vez da opção de entrada -r. ”
Resposta
E se você aumentar ligeiramente o seu segundo exemplo da seguinte maneira:
$ ffmpeg -r 1 -i data/input-%4d.png -c:v libx264 out.mp4
O -r 1
precisa vir antes dos arquivos .png, não depois.
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 é então aplicada ao próximo arquivo de entrada ou saída.
Comentários
- Infelizmente, isto não funciona. No entanto, mencionar que o pedido é importante me economizou muito tempo. Obrigado.
Resposta
Este é um bug no VLC (que ainda existe na versão 3.0.6). Após alguns experimentos, percebi que VLC trava para vídeos com FPS inferior a 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 possa ser reproduzido em VLC ( don “t 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 é adequado para VLC).
Exemplo: se você tem uma pasta com 12 imagens e gostaria de gerar um vídeo com 1 FPS (que pode ser reproduzido em VLC), você precisa duplicar cada imagem várias vezes (digamos 10 vezes) e, em seguida, dizer FFMPEG para gerar um vídeo de 10 FPS, desta forma obteremos um vídeo com um total de 120 frames, onde cada imagem será reproduzida por 1 segundo (já que é duplicada 10 vezes), que é simplesmente uma farsa de 1 FPS.
Eu prefiro usar o parâmetro fps
em vez de
(que é mostrado em outra resposta) que pode, em alguns casos, ser problemático (de acordo com 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 de -framerate
e -vf fps
é importante , pois esta 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 especificado Arquivo. Portanto, a ordem é importante …
ffmpeg
é inteligente o suficiente para descobrir o codec de vídeo apenas a partir da extensão do arquivo de formato de contêiner,.mp4
. Tente adicionar à linha de comando, para informar o codec e os parâmetros de codificação.-r 1
.