Come creare un video dalle immagini usando FFmpeg?


86

È possibile utilizzare ffmpegcreare un video da una serie di sequenze, in cui il numero non inizia da zero?

Ad esempio, ho alcune immagini [test_100.jpg, test_101.jpg, test_102.jpg, ..., test_200.jpg] e voglio convertirle in video. Ho provato il seguente comando, ma non ha funzionato (sembra che il numero dovrebbe iniziare da zero):

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

Qualche consiglio?


È passato un po 'di tempo da quando lo hai fatto, ma se sei ancora interessato alla domanda, la risposta è SÌ - ho pubblicato i dettagli e un esempio di seguito: stackoverflow.com/a/12160155/181638
Assad Ebrahim

@casperOne sarebbe utile per avere un'idea del perché questo è fuori tema. Sembra un problema di programmazione specifico. Il tag FFmpeg ha 3,7k follower e con 27k visualizzazioni chiaramente la gente lo trova utile ..
geotheory

2
@geotheory Le statistiche dei tag sono irrilevanti. ffmpeg è un programma molto simile a WinRar. Sebbene sia possibile programmare contro le librerie in ffmpeg , questa domanda non riguarda questo. L'uso di ffmpeg dalla riga di comando deve essere richiesto su Super User , dove si trova sull'argomento.
casperIl

Risposte:


81

Non è necessario rinominare i file se si utilizza l' -start_numberopzione in questo modo:

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

dov'è nl'inizio della sequenza di immagini fisse.

Nota, questo funzionerà fintanto che la sequenza non viene interrotta una volta iniziata. Se ci sono spazi vuoti e si desidera includere tutti gli alambicchi, potrebbe essere necessario rinumerare per riempire gli spazi vuoti.

Ci sono alcuni altri interruttori che potresti trovare utili.

Uso il seguente one-liner per ottenere un frame rate più lento e per comprimere le immagini e ottenere un video risultante 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' -r 3opzione imposta il framerate del video risultante su 3 fotogrammi al secondo in modo che io possa vedere ciascuno fermo per un breve periodo di tempo. L' -sopzione ridimensiona le immagini alla risoluzione desiderata per gestire le dimensioni del video risultante.

(Nella shell di Windows, sostituirlo -i Imgp%04d.jpgcon -i "Imgp%%04d.jpg". Accreditarlo per Mike Fitzpatrick https://superuser.com/a/344178/153054 )


4
qual è la differenza tra -r e -framerate?

1
sono lo stesso IIRC
rogerdpack il

22
Non c'è bisogno di numerare assurdità, purché tu sia felice di accettare l'ordine in cui appaiono (diciamo) 'ls' ... basta usare: ffmpeg -pattern_type glob -i '* .jpg' movie.mp4
Orwellophile

2
Esiste un interruttore per controllare l' intervallo di tempo tra le immagini, ad esempio, vorrei mostrare la prima immagine 13s, la seconda 15s, 24s per la terza, l'intervallo di tempo è definito dall'utente, è possibile?
Zionpi,


38

puoi utilizzare questo frammento di codice qui sotto:

 cat *.jpg | ffmpeg -f image2pipe -r 1 -vcodec mjpeg -i - -vcodec libx264 out.mp4

Ciò non ruota i JPG nella rotazione indicata nei metadati.
Erik Johansson,

17

Puoi trovare uno script di esempio nella documentazione di ffmpeg :

3.2 Come posso codificare singole immagini in filmati?

Se si dispone di un numero elevato di immagini da rinominare, è possibile utilizzare il comando seguente per alleggerire il carico. Il comando, usando la sintassi della shell bourne, collega simbolicamente tutti i file nella directory corrente che corrispondono a * jpg a /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

Quindi eseguire:

ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg

2
Faresti meglio a fare x = 0 per iniziare così il nome dell'immagine inizia img000.jpg poiché questo è ciò che ffmpeg si aspetta. Anche il collegamento simbolico non ha funzionato per me poiché ffmpeg non è riuscito a trovare i file, quindi ho dovuto usare cp (ovvi problemi di velocità e spazio, ma li ho comunque dopo). mv funzionerebbe anche se non ti dispiace perdere gli originali.

Si noti che in questa risposta, il comando fornito crea collegamenti fisici, non collegamenti simbolici. Per quanto riguarda l'uso di cpse il collegamento non funziona, se il tuo filesystem lo supporta cp --reflink=autootterrà un utilizzo della velocità / spazio molto migliore.
Félix Saparelli,

12

Dai documenti di ffmpeg:

Utilizzando un modello glob

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

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

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

Quindi, fintanto che i file sono ordinati, l'utilizzo -pattern_type globdell'interruttore dovrebbe funzionare per te.


Si noti che questo glob è più limitato dei normali globs di shell: trac.ffmpeg.org/ticket/3620 apparentemente perché il tipo di immagine viene dedotto dall'estensione.
Ciro Santilli 17 改造 中心 法轮功 六四 事件

11

Per quanto ne so, non puoi iniziare la sequenza in numeri casuali (non ricordo se dovresti avviarla da 0 o 1), inoltre, non può avere spazi vuoti, se lo fa, ffmpeg supporrà che la sequenza sia finita e smettere di aggiungere più immagini.

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

immagine% 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

eccetera.


1
Se i nomi dei file di immagine hanno zeri iniziali, la stringa di formato deve anche specificare la larghezza come "% 03d".

1
Se questo è l'unico ostacolo, potresti semplicemente scrivere uno script per rinominare o collegare in modo simbolico le tue immagini a un set correttamente reindicizzato.
Cascabel,

1
Sì, ho già lavorato con questo, ho scritto un wrapper in Ruby qualche tempo fa in cui hai chiamato instance.addImage (), quindi instance.processVideo () e avrebbe creato una directory temporale, copiando / rinominando le immagini con indici adeguati e crea il video. È abbastanza facile

@Jefromi Ho creato un collegamento simbolico ma come posso fornire il percorso del file symlink a ffmpeg? Suppone solo che il file symlink sia l'immagine che sto cercando di convertire? Sono su win7 a proposito

La sequenza può iniziare ovunque da 0 a 4 inclusi.
Assad Ebrahim,

5

Sono d'accordo con Francisco, ma come soluzione alternativa potresti semplicemente 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 quindi chiamare ffmpeg e quindi rimuovere i collegamenti o spostare i file nella loro posizione originale.


1

consultare

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

1

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, quindi ho fatto più ricerche e letture e questo è un comando che mi è venuto in mente per il mio problema.

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

Il motivo per cui avrei usato un comando come questo è ...

  1. Cat e -f image2pipe ti offrono un controllo più preciso sulle immagini che usi. Ad esempio, ti consente di utilizzare le funzionalità di bash come l'espansione della parentesi e altri comandi come grep per ottimizzare i risultati, se lo desideri.
  2. Meno interruttori da ricordare.
  3. Consiglio di NON usare -r e di usare invece -framerate. Nella mia esperienza -r tende a far cadere i frame più spesso.
  4. Interruttori meno complessi, non necessari e funzioneranno così come sono. È possibile aggiungere maggiore complessità (ad esempio, specificando l'encoder) e perfezionare la messa a punto in base alle proprie esigenze.

Per la domanda del PO, -start_numberè tutto ciò che serve.
Gyan il

0

Ho usato l'encoder flv poiché il mio video stava andando in un flash player (Jwplayer)

ffmpeg -i% d.jpg -vcodec flv test.flv


0

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à, la velocità / fps potrebbe essere importante (ad esempio, prima specificare un frame rate molto basso / alto e quindi passare da un secondo filtro che renderà il video al rallentatore normale?)


0

Nel mio caso, è stato un po 'più complicato a causa dei numeri nei file. Ecco come appaiono 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

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 10*PTSdice a ffmpeg di rallentarlo 10 volte. Puoi anche avere frazioni lì per accelerarlo.


Si tratta solo di interpolare la sequenza dell'immagine originale in un nuovo spazio, non crea un file video come richiesto dall'OP.
f0ster

0

-pattern_type glob esempi concreti con l'audio

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

Presentazione video con un'immagine al secondo

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

Aggiungi un po 'di musica, interrompi quando l'audio termina con le 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:

Diventa un hippie e usa il formato video illimitato di brevetti 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 immagini dovrebbero ovviamente essere ordinate in ordine alfabetico, in genere 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 ad esso:

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

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

Risposta a: Come convertire MP3 in formato video consentito da Youtube?

Ottieni alcune immagini di input di test sintetici

Queste sono le immagini di prova 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 comprime la sequenza di immagini in modo migliore rispetto a ZIP in quanto è in grado di comprimere attraverso i frame con algoritmi specializzati:

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

Informazioni sulle opzioni della CLI

Si noti tuttavia che, nonostante il nome, -globquesto non è così generale come gli schemi della shell Glob, ad esempio: -i '*'fail: https://trac.ffmpeg.org/ticket/3620 (apparentemente perché il tipo di file viene dedotto dall'estensione).

-r 30realizza il -framerate 1video 30 FPS per superare bug nei giocatori come VLC per framerate bassi: 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.

Prossimi passi

Dovrai anche:

TODO: impara a tagliare e concatenare più file audio nel video dalla riga di comando:

Testato su

ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04.

Bibliografia

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.