2010-05-13 17:58:09 +0000 2010-05-13 17:58:09 +0000
89
89

Como criar um vídeo a partir de imagens usando FFmpeg?

É possível usar ffmpeg criar um vídeo a partir de um conjunto de sequências, em que o número não começa de zero?

Por exemplo, eu tenho algumas imagens [test_100.jpg, test_101.jpg, test_102.jpg, …, test_200.jpg], e quero convertê-las para um vídeo. Tentei o seguinte comando, mas não funcionou (parece que o número deve começar do zero):

ffmpeg -i test_%d.jpg -vcodec mpeg4 test.avi

Algum conselho?

Respostas (10)

84
84
84
2012-08-28 13:19:14 +0000

Não há necessidade de renomear os ficheiros se se utilizar a opção -start_number switch como tal:

ffmpeg -start_number n -i test_%d.jpg -vcodec mpeg4 test.avi

onde n é o início da sequência de stills.

Nota, isto funcionará desde que a sequência não seja quebrada uma vez iniciada. Se houver lacunas e se quiser incluir todos os alambiques, pode ser necessário renumerar para preencher as lacunas.

Há alguns outros interruptores que poderá considerar úteis.

Utilizo o seguinte one-liner para obter uma taxa de fotogramas mais lenta e para comprimir as imagens e ter um vídeo menor resultante:

ffmpeg.exe -f image2 -framerate 25 -pattern_type sequence -start_number 1234 -r 3 -i Imgp%04d.jpg -s 720x480 test.avi

A opção -r 3 fixa o frame do vídeo resultante em 3 frames por segundo para que eu possa ver cada um deles ainda durante um curto período de tempo. A opção -s redimensiona as imagens para a resolução desejada a fim de gerir o tamanho do vídeo resultante.

& (Na shell do Windows, substituir -i Imgp%04d.jpg por -i "Imgp%%04d.jpg". Crédito por isto a Mike Fitzpatrick https://superuser.com/a/344178/153054 )

17
17
17
2010-07-18 17:02:21 +0000

Pode encontrar um guião de exemplo na documentação ffmpeg :

3.2 Como codificar fotografias individuais em filmes?

Se tiver um grande número de fotografias para renomear, pode usar o seguinte comando para aliviar a carga. O comando, utilizando a sintaxe da concha de bourne shell, liga simbolicamente todos os ficheiros do directório actual que correspondem *jpg ao /tmp' directory in the sequence ofimg001.jpg’, `img002.jpg’ e assim por diante.

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done

Depois correr:

ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
14
14
14
2014-07-13 07:11:20 +0000

De ffmpeg’s docs:

Usando um padrão de glob

ffmpeg também suporta bash-style globbing (* representa qualquer número de quaisquer caracteres).

Isto é útil se as suas imagens forem sequenciais mas não necessariamente numa ordem numérica sequencial, como nos exemplos anteriores.

ffmpeg -r 1 -pattern_type glob -i 'test_*.jpg' -c:v libx264 out.mp4

Assim, desde que os seus ficheiros estejam ordenados, o uso do interruptor -pattern_type glob deve funcionar para si.

11
11
11
2010-05-13 18:15:35 +0000

Tanto quanto sei, não se pode iniciar a sequência em números aleatórios (não me lembro se a deve iniciar em 0 ou 1), além disso, não pode ter lacunas, se tiver, ffmpeg assumirá que a sequência terminou e deixará de adicionar mais imagens.

Além disso, como indicado nos comentários à minha resposta, lembre-se que precisa de especificar a largura do seu índice. Como:

imagem%03d.jpg

E se usar um tipo de índice %03d, precisa de preencher os seus nomes de ficheiro com 0, como :

image001.jpg image002.jpg image003.jpg

etc.

5
5
5
2010-05-13 18:23:37 +0000

Concordo com Francisco, mas como alternativa poderia simplesmente escrever um script rápido para mover ou criar ligações simbólicas aos ficheiros com os números de sequência que ffmpeg necessita. O guião poderia então chamar ffmpeg e depois remover as ligações ou mover os ficheiros de volta para os seus locais originais.

2
2
2
2016-08-03 23:44:55 +0000

Sei que esta é uma pergunta antiga mas deparei-me com ela no Google enquanto procurava a mesma resposta. Nenhuma das respostas aqui me satisfez completamente, por isso fiz mais pesquisa e leitura e este é um comando que me veio à cabeça para o meu próprio problema.

cat {0032..1501}*.png | ffmpeg -f image2pipe -framerate 5 -i - -s 720x480 test2.avi

A razão pela qual eu usaria um comando como este é…

  1. o gato e -f image2pipe dão-lhe um melhor controlo sobre as imagens que utiliza. Por exemplo, permite-lhe usar características de bash como expansão de suporte e outros comandos como grep para afinar os seus resultados, caso escolha.
  2. Menos interruptores para recordar.
  3. Recomendo NÃO usar -r, e apenas usar -framerate em vez disso. Na minha experiência -r tende a deixar cair quadros com mais frequência.
  4. Menos complexo, sem interruptores desnecessários em uso e funcionará como está. Pode acrescentar mais complexidade (por exemplo, especificar codificador) e afinação fina para se adequar às suas necessidades.
0
0
0
2019-08-22 09:59:39 +0000

-pattern_type glob exemplos concretos com áudio*

Esta opção foi mencionada em: https://superuser.com/a/782520/128124 mas aqui estão alguns exemplos concretos da sua utilização, incluindo a adição de áudio ao vídeo de saída.

Slideshow vídeo com uma imagem por segundo

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

Adicione alguma música ao vídeo, corte quando o áudio termina quando as imagens terminam:

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

Aqui estão duas demos no YouTube:

Seja um hippie e use o formato de vídeo com patente de Theora :

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libtheora -r 30 -pix_fmt yuv420p out.ogg

As suas imagens devem ser ordenadas alfabeticamente, tipicamente como:

0001-first-thing.jpg
0002-second-thing.jpg
0003-and-third.jpg

e assim por diante.

Ver também: http://unix.stackexchange.com/questions/68770/converting-png-frames-to-video-at-1-fps/339399#339399

Vídeo de velocidade normal com uma imagem por fotograma a 30 FPS*

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

Aqui está o seu aspecto:

GIF gerado com: https://askubuntu.com/questions/648603/how-to-create-an-animated-gif-from-mp4-video-via-command-line/837574#837574

Adicione-lhe algum áudio:

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4

Resultado: https://www.youtube.com/watch?v=HG7c7lldhM4

Converta um ficheiro de música para um vídeo com uma imagem fixa para upload no YouTube*

Respondido em Como converter MP3 para o formato de vídeo permitido pelo Youtube?

Obter algumas imagens de teste sintéticas*

Estas são as imagens de teste que tenho estado a utilizar nesta resposta:

wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true
unzip opengl-rotating-triangle.zip
cd opengl-rotating-triangle
wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg

Imagens geradas com: https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292

É fixe observar o quanto o vídeo comprime a sequência de imagens muito melhor do que o ZIP, pois é capaz de comprimir através de fotogramas com algoritmos especializados:

  • opengl-rotating-triangle.mp4: 340K
  • opengl-rotating-triangle.zip: 7,3M

Sobre as opções CLI

Note no entanto que, apesar do nome, -glob isto não é tão geral como os padrões shell Glob, por exemplo: -i '*' falha: https://trac.ffmpeg.org/ticket/3620 (aparentemente porque o tipo de ficheiro é deduzido da extensão).

-r 30 faz o -framerate 1 vídeo 30 FPS para ultrapassar bugs em leitores como o VLC para os framerates baixos: https://stackoverflow.com/questions/19267443/playback-issues-in-vlc-with-low-fps-video-from-images-using-ffmpeg/41797724#41797724 Por conseguinte, repete cada frame 30 vezes para manter o efeito desejado de 1 imagem por segundo.

Passos seguintes

Você também vai querer:

TODO: aprender a cortar e concatenar múltiplos ficheiros áudio no vídeo a partir da linha de comando:

Testado em*

ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04.

Bibliografia*

0
0
0
2017-10-30 18:28:51 +0000

No meu caso, foi um pouco mais complicado por causa dos números nos ficheiros. Eis o aspecto das minhas imagens:

$ ls | head -5
2014_aq_unprocessed 001.jpg
2014_aq_unprocessed 002.jpg
2014_aq_unprocessed 003.jpg
2014_aq_unprocessed 004.jpg
2014_aq_unprocessed 005.jpg

e aqui está o comando que utilizei:

ffmpeg -i 2014_aq_unprocessed\ %3d.jpg -vcodec mpeg4 test.avi
0
0
0
2016-01-29 12:05:41 +0000

A partir da documentação , parece que pode simplesmente usar *

For example, for creating a video from filenames matching the glob pattern foo-*.jpeg:

ffmpeg -f image2 -pattern_type glob -framerate 12 -i 'foo-*.jpeg' -s WxH foo.avi

Como nota, para melhorar a qualidade, a taxa/fps pode ser importante (por exemplo, primeiro especificando uma taxa de quadros muito baixa/alta e depois passar de um segundo filtro que fará o vídeo em câmara lenta para o normal?)

0
0
0
2016-01-14 23:22:34 +0000

Pode fazer isto com convert -morph :

convert *.jpg -delay 10 -morph 10 %05d.jpg

Se quiser usar ffmpeg, eu usei

ffmpeg -pattern_type glob -i '*.jpg' -vf "setpts=10*PTS" movie.mp4

onde o 10*PTS diz ao ffmpeg para o abrandar 10 vezes. Também se pode ter aí fracções para o acelerar.