Ho fotogrammi video in formato PNG a 1 FPS e sto cercando di convertirli in un video usando ffmpeg.
Se faccio qualcosa del genere:
ffmpeg -i data/input-%4d.png data/output.mp4
ottengo un video a 25 FPS che è fondamentalmente un avanzamento molto veloce dellinput (che viene catturato a 1 FPS).
Se provo:
ffmpeg -i data/input-%4d.png -r 1 data/output.mp4
Ottengo qualcosa che VLC non vuole riprodurre 🙂
Ora, se prendo il primo video (quello FF) e applico un filtro per rallentarlo (es. -filter:v "setpts=24.0*PTS"
), posso farlo riprodurre come un video a 1 FPS, ma ovviamente il prezzo è la dimensione del file. Immagino che generi un mucchio di fotogrammi ripetuti.
Quindi, la domanda è: come faccio a creare un video che abbia esattamente 1 FPS e che venga effettivamente riprodotto a quella velocità? Il formato di output, btw, non lo è “. È importante per me.
Commenti
Risposta
Se desideri un one-liner per FFMPEG che generi un video che viene riprodotto a 1 fotogramma al secondo, quello che vuoi fare è specificare i framerate sia per linput che per loutput, in questo modo:
ffmpeg -r 1 -i data / input-% 4d.png -pix_fmt yuv420p -r 10 data / output.mp4
-r 1
significa che il video verrà riprodotto a una delle immagini originali al secondo.
-r 10
significa che il video verrà riprodotto a 10 fotogrammi al secondo.
(Il -pix_fmt yuv420p
serve solo a garantire la compatibilità con unampia gamma di programmi di riproduzione. È richiesto qui, ad esempio, affinché il video possa essere riprodotto da Windows Media Player.)
Ho testato molti diversi framerate di output e 10 sembra essere il numero più basso che puoi usare che produrrà comunque un video riprodotto da VLC.
Ovviamente, il comando sopra indica che ogni immagine originale viene moltiplicata, ma è un metodo più semplice di quello “rallenta” che hai menzionato e, a seconda del codec, potrebbe non produrre un video molto più grande di un vero video 1-FPS.
Per testare questo, ho appena prodotto un vero video 1-FPS, che è risultato 2.24 kiB. Ho quindi prodotto un video con le stesse immagini in ingresso ma in uscita a 24 FPS, ed è uscito a 5,76 kiB. È poco più del doppio e non è neanche lontanamente 24 volte più grande. 🙂
Commenti
- +1 su -pix_fmt. Facile da dimentica che alcune persone insistono nellusare WMP 🙂
- perché vuoi che il formato di output sia 10 fps mentre linput è solo 1? ‘ creare frame ridondanti al 90% che sono esattamente gli stessi?
- @Herbert crea frame ridondanti in modo che tu possa ottenere il frame rate fino a 10, il che è fatto solo così VLC non ‘ non si lamenta e visivamente non ‘ cambia il video. Il codificatore è abbastanza intelligente da vedere che i fotogrammi sono tutti identici, quindi non ‘ ti ritroverai con un file molto più grande
- @chiliNUT chiaro, la cosa del keyframe, che non tutti i formati, ma la maggior parte dei formati sani andrà bene. Grazie !
Risposta
Utilizza entrambi -framerate
e -r
Ad esempio, per avere un video finale simile a 1FPS:
ffmpeg -framerate 1 -pattern_type glob -i "*.png" \ -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4
Questo è simile a quello che Conversione di fotogrammi PNG in video a 1 FPS | Unix & Linux Stack Exchange dice, ma avevo bisogno di -framerate
invece di -r
affinché funzioni.
Questo è menzionato nel wiki allindirizzo: http://trac.ffmpeg.org/wiki/Slideshow#Framerates
Imposta il framerate di output su 30
, che VLC può gestire, e copia ogni immagine 30 volte, in modo che il video di output sembri essere a 1 FPS. Vedi anche: Problemi di riproduzione in VLC con video a basso fps da immagini utilizzando ffmpeg | Stack Overflow
VLC è quindi in grado di riprodurre il video normalmente.
Testato su Ubuntu 16.10, VLC 2.2.4, ffmpeg
3.0.5, in una directory con 10 PNG.
Vedi anche: https://stackoverflow.com/questions/19267443/vlc-freezes-for-low-1-fps-video-created-from-images-with-ffmpeg
Commenti
- Che ‘ è la differenza tra
-r
e-framerate
? - @Royi I don ‘ Non lo so davvero, tranne che è lunica cosa che ha funzionato per me 🙂 Ma se ci sei riuscito estrailo dalle pagine
man
, fammelo sapere 😉 Una citazione significativa è ” -r Come opzione di input, ignora qualsiasi timestamp memorizzati nel file e invece generano timestamp assumendo fps a frame rate costante. Non è la stessa dellopzione -framerate usata per alcuni formati di input come image2 o v4l2 (era la stessa nelle versioni precedenti di FFmpeg). In caso di dubbio, utilizza -framerate invece dellopzione di input -r. ”
Risposta
E se aumenti leggermente il tuo secondo esempio come segue:
$ ffmpeg -r 1 -i data/input-%4d.png -c:v libx264 out.mp4
Il -r 1
deve essere prima dei file .png, non dopo.
Dalla documentazione FFmpeg :
Come regola generale, le opzioni vengono applicate al file specificato successivo. Pertanto, lordine è importante e puoi avere la stessa opzione sulla riga di comando più volte. Ogni occorrenza viene quindi applicata al file di input o output successivo.
Commenti
- Purtroppo questo non funziona. Tuttavia, menzionare che lordine è importante mi ha fatto risparmiare molto tempo. Grazie.
Risposta
Questo è un bug in VLC (che esiste ancora nella versione 3.0.6). Dopo alcuni esperimenti mi sono reso conto che VLC si arresta in modo anomalo per i video con FPS inferiore a 10 . Quindi tutti i video con 10 FPS o più non dovrebbero essere un problema. Pertanto, attualmente non esiste un modo pulito per ottenere un video con 1 FPS riproducibile in VLC ( don “t arrenditi, continua a leggere ).
Una soluzione alternativa è -come mostrato nella risposta sopra- simulare leffetto di 1 FPS duplicando le immagini (quando in realtà abbiamo un FPS uguale a 10 o più, che va bene per VLC).
Esempio: se hai una cartella con 12 immagini e desideri generare un video con 1 FPS (che è riproducibile in VLC), devi duplicare ciascuna immagine più volte (diciamo 10 volte), quindi dire FFMPEG per generare un video a 10 FPS In questo modo otterremo un video con un totale di 120 fotogrammi, in cui ogni immagine verrà riprodotta per 1 secondo (poiché è duplicata 10 volte), che è semplicemente un falso per 1 FPS.
Preferisco utilizzare il parametro fps
anziché
(mostrato in unaltra risposta) che in alcuni casi potrebbe essere problematico (secondo documentazione ufficiale ).
ffmpeg -framerate 1 -i "img (%d).jpg" -c:v libvpx-vp9 -vf "fps=10,format=yuv420p" out.mkv
Poiché linput -framerate
è inferiore alloutput fps
, FFMPEG duplicherà i fotogrammi per raggiungere la frequenza fotogrammi di output desiderata (che è 10 in base al comando sopra).
È anche importante notare che lordine di -framerate
e -vf fps
è importante , poiché questa configurazione verrà applicata al successivo video menzionato (ingresso o uscita). Questo secondo i documenti ufficiali :
le opzioni vengono applicate al successivo specificato file. Pertanto, lordine è importante …
ffmpeg
è abbastanza intelligente da capire il codec video solo dallestensione del file in formato contenitore,.mp4
. Prova ad aggiungere-vcodec libx264 -vpre hq
alla riga di comando, per dirgli il codec e i parametri di codifica.-r 1
.