Conversione di fotogrammi PNG in video a 1 FPS


21

Ho fotogrammi video in formato PNG a 1 FPS e sto provando a convertirli in un video usando ffmpeg.

Se faccio qualcosa del genere:

ffmpeg -i data/input-%4d.png data/output.mp4

Ottengo un video a 25FPS che è sostanzialmente un avanzamento molto veloce dell'input (che viene catturato a 1FPS).

Se provo:

ffmpeg -i data/input-%4d.png -r 1 data/output.mp4

Ho qualcosa che VLC non vuole giocare :)

Ora, se prendo il primo video (quello FF) e applico un filtro per rallentarlo (ad esempio -filter:v 'setpts=24.0*PTS'), posso farlo riprodurre come un video 1 FPS, ma ovviamente il prezzo è la dimensione del file. Sta generando un sacco di frame ripetuti, immagino.

Quindi, la domanda è: come faccio a creare un video con esattamente 1 FPS e in realtà viene riprodotto a quella velocità? Il formato di output, a proposito, non è così importante per me.


Non sono sicuro che ffmpegsia abbastanza intelligente da capire il codec video solo dall'estensione del file in formato contenitore .mp4. Prova ad aggiungere -vcodec libx264 -vpre hqalla riga di comando, per dirgli il codec e i parametri di codifica.
Warren Young,

In realtà l'ho capito bene, e come ho già detto ha funzionato bene e ho prodotto risultati strani solo quando l'ho aggiunto -r 1.
Assaf Lavie il

Penso che potresti avere più fortuna con una risposta ffmpeg su stackoverflow.com o superuser.com .
Damien,

Risposte:


19

Se vuoi un one-liner per FFMPEG che genera un video che viene riprodotto a 1 fotogramma al secondo, quello che vuoi fare è specificare framerate sia per l'input che per l'output, in questo modo:

ffmpeg -r 1 -i data / input-% 4d.png -pix_fmt yuv420p -r 10 data / output.mp4

Ciò -r 1significa che il video verrà riprodotto su 1 delle immagini originali al secondo.
Ciò -r 10significa che il video verrà riprodotto a 10 fotogrammi al secondo.

-pix_fmt yuv420plì solo per garantire la compatibilità con una vasta gamma di programmi di riproduzione. Qui è necessario, ad esempio, che il video sia riproducibile da Windows Media Player.)

Ho testato molti framerate di output diversi, e 10 sembra essere il numero più basso che puoi usare che produrrà comunque un video che verrà riprodotto da VLC.

Naturalmente, il comando sopra indica che ogni immagine originale viene moltiplicata, ma è un metodo più semplice di quello "rallentalo" che hai citato e, a seconda del codec, potrebbe non produrre un video molto più grande di un vero 1-FPS video.

Per testarlo, ho appena prodotto un vero video 1-FPS, che è uscito a 2,24 kiB. Ho quindi prodotto un video con le stesse immagini di input ma l'output a 24 FPS ed è uscito a 5,76 KiB. Questo è poco più del doppio delle dimensioni e in nessun luogo vicino a 24 volte le dimensioni. :)


+1 su -pix_fmt. Facile dimenticare che alcune persone insistono sull'uso di WMP :-)
Smalltown2k

perché vorresti che il formato di output fosse 10 fps mentre l'ingresso è solo 1? Non creerebbe frame ridondanti al 90% esattamente uguali?
Herbert,

@Herbert crea fotogrammi ridondanti in modo da poter ottenere un frame rate fino a 10, il che viene fatto solo in modo che VLC non si lamenta e visivamente non cambia il video. L'encoder è abbastanza intelligente da vedere che i frame sono tutti identici in modo da non finire con un file molto più grande
chiliNUT

@chiliNUT chiaro, la cosa del fotogramma chiave, che non tutti i formati, ma la maggior parte dei formati sani farà. Grazie!
Herbert,

5

Usa entrambi -frameratee-r

Ad esempio, per avere un video finale che assomiglia 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 converte i fotogrammi PNG in video a 1 FPS | Unix & Linux Stack Exchange dice, ma -framerateinvece ho dovuto -rfarlo funzionare.

Questo è menzionato nel wiki su: 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 appaia a 1 FPS. Vedi anche: Problemi di riproduzione in VLC con video a basso fps da immagini usando ffmpeg | Stack Overflow

VLC è quindi in grado di riprodurre il video normalmente.

Testato su Ubuntu 16.10, VLC 2.2.4, ffmpeg3.0.5, in una directory con 10 PNG.

Vedi anche: /programming/19267443/vlc-freezes-for-low-1-fps-video-created-from-images-with-ffmpeg


Qual è la differenza tra -re -framerate?
Royi

@Royi Non lo so davvero, tranne per il fatto che è l'unica cosa che ha funzionato per me :-) Ma se sei riuscito a estrarlo dalle manpagine, fammi sapere ;-) Una citazione significativa è "-r Come un opzione di input, ignora tutti i timestamp memorizzati nel file e genera invece timestamp assumendo un frame rate costante fps. Questa non è la stessa dell'opzione -framerate utilizzata per alcuni formati di input come image2 o v4l2 (era la stessa nelle versioni precedenti di FFmpeg). In caso di dubbi, utilizzare -framerate anziché l'opzione di input -r. "
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件

3

Che cosa succede se aumenti leggermente il secondo esempio come segue:

$ ffmpeg -r 1 -i data/input-%4d.png -c:v libx264 out.mp4

Le -r 1esigenze devono venire prima dei file .png, non dopo.

Dalla documentazione di FFmpeg :

Come regola generale, le opzioni vengono applicate al successivo file specificato. Pertanto, l'ordine è 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.


Purtroppo questo non funziona. Tuttavia, ricordare che l' ordine è importante mi ha fatto risparmiare un sacco di tempo. Grazie.
Mohammed Noureldin il

0

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 almeno 10 FPS non dovrebbero essere un problema. Quindi al momento non esiste un modo pulito per ottenere un video con 1 FPS riproducibile in VLC ( non mollare, continua a leggere ).

Una soluzione alternativa è -come mostrato nella risposta sopra- per falsare l'effetto di 1 FPS duplicando le immagini (quando in realtà abbiamo un FPS uguale a 10 o più, il che è ok per VLC).

Esempio: se hai una cartella con 12 immagini e desideri generare un video con 1 FPS (che è riproducibile in VLC), devi duplicare ogni immagine più volte (diciamo 10 volte), quindi dire a FFMPEG per generare un video 10 FPS. In questo modo avremo un video con un totale di 120 fotogrammi, in cui ogni immagine verrà riprodotta per 1 secondo (poiché viene duplicata 10 volte), che è semplicemente un falso per 1 FPS.

Preferisco usare il fpsparametro piuttosto che-r (che è mostrato in un'altra risposta) che può in alcuni casi essere problematico (secondo la documentazione ufficiale ).

ffmpeg -framerate 1 -i "img (%d).jpg" -c:v libvpx-vp9 -vf "fps=10,format=yuv420p" out.mkv

Poiché l'input -framerateè inferiore all'output fps, FFMPEG duplicherà i frame per raggiungere la frequenza dei frame di output desiderata (che è 10 secondo il comando sopra).

È anche importante notare che l'ordine di -framerateed -vf fpsè importante , poiché questa configurazione verrà applicata al prossimo video citato (in entrata o in uscita). Questo è secondo i documenti ufficiali :

le opzioni vengono applicate al successivo file specificato. Pertanto, l'ordine è importante ...

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.