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

Come creare un video da immagini usando FFmpeg?

È possibile usare ffmpeg per creare un video da un insieme di sequenze, dove il numero non inizia da zero?

Per esempio, ho alcune immagini [test\100.jpg, test_101.jpg, test\102.jpg, …, test\200.jpg], e voglio convertirle in un video. Ho provato il seguente comando, ma non ha funzionato (sembra che il numero debba iniziare da zero):

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

Qualche consiglio?

Risposte (10)

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

Non c'è bisogno di rinominare i file se si usa l'interruttore -start_number in questo modo:

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

dove n è l'inizio della sequenza di foto.

Nota, questo funzionerà finché la sequenza è ininterrotta una volta iniziata. Se ci sono dei vuoti e vuoi che tutti i fotogrammi siano inclusi, allora potrebbe essere necessaria una rinumerazione per riempire i vuoti.

Ci sono altri interruttori che potresti trovare utili.

Io uso il seguente one-liner per ottenere un frame rate più lento e per comprimere le immagini e avere un video più piccolo:

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

L'opzione -r 3 imposta il framerate del video risultante a 3 fotogrammi al secondo in modo da poter vedere ogni foto per un breve periodo di tempo. L'opzione -s ridimensiona le immagini alla risoluzione desiderata per gestire la dimensione del video risultante.

(nella shell di Windows, sostituire -i Imgp%04d.jpg con -i "Imgp%%04d.jpg". Il merito è di Mike Fitzpatrick https://superuser.com/a/344178/153054 )

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

Puoi trovare uno script di esempio nella documentazione di ffmpeg :

3.2 Come faccio a codificare singole immagini in filmati?

Se hai un gran numero di immagini da rinominare, puoi usare il seguente comando per alleviare il peso. Il comando, usando la sintassi della shell bourne, collega simbolicamente tutti i file nella directory corrente che corrispondono a *jpg alle /tmp' directory in the sequence ofimg001.jpg’, `img002.jpg’ e così via.

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

Poi esegui:

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

Da ffmpeg’s docs:

Usare un pattern glob

ffmpeg supporta anche il globbing in stile bash (* rappresenta qualsiasi numero di qualsiasi carattere).

Questo è utile se le tue immagini sono sequenziali ma non necessariamente in un ordine numericamente sequenziale come negli esempi precedenti.

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

Quindi, finché i tuoi file sono ordinati, usare lo switch -pattern_type glob dovrebbe funzionare per te.

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

Per quanto ne so, non puoi iniziare la sequenza in numeri casuali (non ricordo se dovresti iniziarla a 0 o 1), inoltre, non può avere spazi vuoti, se lo fa, ffmpeg assumerà che la sequenza sia finita e smetterà di aggiungere altre immagini.

Inoltre, come detto nei commenti alla mia risposta, ricorda che devi specificare la larghezza del tuo indice. Come:

image%03d.jpg

E se usi un tipo di indice %03d, devi riempire i tuoi nomi di file con 0, come :

image001.jpg image002.jpg image003.jpg

ecc.

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

Sono d'accordo con Francisco, ma come soluzione alternativa potresti scrivere uno script veloce per spostare o creare collegamenti simbolici ai file con i numeri di sequenza di cui ffmpeg ha bisogno. Lo script potrebbe poi chiamare ffmpeg e quindi rimuovere i collegamenti o spostare i file nelle loro posizioni originali.

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

So che questa è una vecchia domanda ma mi sono imbattuto in Google mentre cercavo la stessa risposta. Nessuna delle risposte qui mi ha soddisfatto completamente così ho fatto altre ricerche e letture e questo è un comando che ho trovato per il mio problema.

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

Il motivo per cui userei un comando come questo è…

  1. Cat e -f image2pipe ti danno un controllo più fine sulle immagini che usi. Per esempio ti permette di usare le caratteristiche di bash come l'espansione delle parentesi e altri comandi come grep per mettere a punto i tuoi risultati se vuoi.
  2. Meno interruttori da ricordare.
  3. Raccomando di NON usare -r, e di usare invece -framerate. Nella mia esperienza -r tende a far cadere fotogrammi più spesso.
  4. Meno complesso, nessun interruttore inutile in uso e funzionerà così com'è. Puoi aggiungere più complessità (per esempio, specificando l'encoder) e mettere a punto per soddisfare le tue esigenze.
0
0
0
2019-08-22 09:59:39 +0000

-pattern_type glob esempi concreti con audio

Questa opzione è stata menzionata in: https://superuser.com/a/782520/128124 ma qui ci sono alcuni esempi concreti del suo utilizzo, compresa l'aggiunta di audio al video in uscita.

Slideshow video con un'immagine al secondo

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

Aggiungici della musica, tagliando l'audio alla fine delle immagini:

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

Ecco due demo su YouTube:

Sii un hippie e usa il formato video senza brevetto 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

Le tue immagini dovrebbero ovviamente essere ordinate in ordine alfabetico, tipicamente come:

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

e così via.

Vedi anche: http://unix.stackexchange.com/questions/68770/converting-png-frames-to-video-at-1-fps/339399#339399

Video a velocità normale con un'immagine per fotogramma a 30 FPS

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

Ecco come appare:

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

Aggiungi un po’ di audio:

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

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

Convertire un file musicale in un video con un'immagine fissa per il caricamento su YouTube

Risposto a: Come convertire MP3 in un formato video consentito da YouTube?

Ottieni alcune immagini sintetiche di test in ingresso

Queste sono le immagini di test che ho usato in questa risposta:

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

Immagini generate con: https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292

È bello osservare quanto il video comprima la sequenza di immagini molto meglio di ZIP in quanto è in grado di comprimere attraverso i frame con algoritmi specializzati:

  • opengl-rotating-triangle.mp4: 340K
  • opengl-rotating-triangle.zip: 7.3M

A proposito delle opzioni CLI

Nota però che nonostante il nome, -glob questo non è così generale come gli schemi Glob della shell, es: -i '*' fallisce: https://trac.ffmpeg.org/ticket/3620 (apparentemente perché il tipo di file è dedotto dall'estensione).

-r 30 rende il video -framerate 1 a 30 FPS per superare i bug in lettori come VLC per bassi framerate: https://stackoverflow.com/questions/19267443/playback-issues-in-vlc-with-low-fps-video-from-images-using-ffmpeg/41797724#41797724 Quindi ripete ogni fotogramma 30 volte per mantenere l'effetto desiderato di 1 immagine al secondo.

Passi successivi

Vorrai anche:

TODO: imparare a tagliare e concatenare più file audio nel video dalla linea di comando:

Testato su

ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04.

Bibliografia

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

Nel mio caso, è stato un po’ più complicato a causa dei numeri nei file. Ecco come sono le mie immagini:

$ 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

ed ecco il comando che ho usato:

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

Dalla documentazione , sembra che tu possa semplicemente usare *

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

Come nota, per migliorare la qualità, il rate/fps potrebbe essere importante (ad esempio, specificando prima un frame rate molto basso/alto e poi passare da un secondo filtro che renderà il video in slow motion normale?)

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

Puoi farlo con convert -morph :

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

Se vuoi usare ffmpeg, ho usato

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

dove lo 10*PTS dice a ffmpeg di rallentare 10 volte. Puoi anche avere delle frazioni per accelerarlo.