Ciao ho bisogno di estrarre fotogrammi dai video tramite ffmpeg .. C'è un modo più veloce per farlo che questo:Il modo più veloce per estrarre i frame usando ffmpeg?
ffmpeg -i file.mpg -r 1/1 $filename%03d.jpg
?
Ciao ho bisogno di estrarre fotogrammi dai video tramite ffmpeg .. C'è un modo più veloce per farlo che questo:Il modo più veloce per estrarre i frame usando ffmpeg?
ffmpeg -i file.mpg -r 1/1 $filename%03d.jpg
?
Se il passo di codifica JPEG è troppo le prestazioni ad alta intensità, si può sempre memorizzare i fotogrammi non compressi come immagini BMP:
ffmpeg -i file.mpg -r 1/1 $filename%03d.bmp
Questo ha anche il vantaggio di non incorrere in ulteriori perdite di qualità attraverso quantizzazione da transcodifica in JPEG. (PNG è anche senza perdita di dati, ma tende a richiedere molto più tempo rispetto a JPEG per la codifica.)
grazie! Proverò a questo – Stpn
questo sembra emettere un frame in più che c'è nel video (numero che posso ottenere con il filtro showinfo o ffprobe) – Guig
Ciò risulta in * un sacco * di frame dropping sulla mia macchina. Posso dire a ffmpeg di rendere tutto? – Evi1M4chine
È venuto attraverso questa domanda, quindi ecco un confronto veloce. Confrontare questi due modi diversi per estrarre un fotogramma al minuto da un video 38m07s lunga:
time ffmpeg -i input.mp4 -filter:v fps=fps=1/60 ffmpeg_%0d.bmp
1m36.029s
Questo richiede molto perché ffmpeg analizza l'intero file video per ottenere i fotogrammi desiderati.
time for i in {0..39} ; do ffmpeg -accurate_seek -ss `echo $i*60.0 | bc` -i input.mp4 -frames:v 1 period_down_$i.bmp ; done
0m4.689s
Si tratta di circa 20 volte più veloce. Usiamo la ricerca rapida per andare all'indice del tempo desiderato e estrarre un frame, quindi chiamare ffmpeg più volte per ogni indice di tempo. Notare che -accurate_seek
is the default e assicurarsi di aggiungere -ss
prima dell'opzione video di input -i
.
Si noti che è meglio usare -filter:v -fps=fps=...
invece di -r
come the latter may be inaccurate. Anche se the ticket is marked as fixed, io ancora ho esperienza alcuni problemi, quindi meglio giocare sul sicuro.
feb 2016: a partire da ffmpeg 2.1, l'opzione di ricerca precisa è ora predefinita - https: //trac.ffmpeg .org/wiki/Seeking – mafrosis
'bc' non è un pacchetto nativo di Ubuntu, invece si può usare bash:' let "i = $ i * 60" '. BTW - ottima idea –
Un buon consiglio aggiungendo '-ss' prima di' -i'. In caso contrario, l'intero video verrà decodificato e i fotogrammi non richiesti verranno scartati – MoustafaAAtta
Se si sa esattamente che incornicia per estrarre, ad esempio 1, 200, 400, 600, 800, 1000, provare a utilizzare:
select='eq(n\,1)+eq(n\,200)+eq(n\,400)+eq(n\,600)+eq(n\,800)+eq(n\,1000)' \
-vsync vfr -q:v 2
Sto usando questo con un tubo di montaggio di ImageMagick per ottenere 10 anteprima di fotogrammi da qualsiasi video. Ovviamente i numeri di telaio avrete bisogno di capire utilizzando ffprobe
ffmpeg -i myVideo.mov -vf \
select='eq(n\,1)+eq(n\,200)+eq(n\,400)+eq(n\,600)+eq(n\,800)+eq(n\,100)',scale=320:-1 \
-vsync vfr -q:v 2 -f image2pipe -vcodec ppm - \
| montage -tile x1 -geometry "1x1+0+0<" -quality 100 -frame 1 - output.png
.
piccola spiegazione:
+
acronimo di OR e *
per E\,
è semplicemente sfuggire alla ,
carattere-vsync vfr -q:v 2
non sembra funzionare, ma io non so perché - qualcuno?Uno '' 'troppo. Dovrebbe essere: ' '' ffmpeg -i $ 1 -vf \ select = 'eq (n \, 1) + eq (n \, 200) + eq (n \, 400) + eq (n \, 600) + eq (n \, 800) + eq (n \, 100) ', scala = 320: -1 \ -vsync vfr -q: v 2 -f image2pipe -vcodec ppm - \ | montage -tile x1 -geometry "1x1 + 0 + 0 <" -quality 100 -frame 1 - output.png'''' – cauchy
Nel mio caso ho bisogno di frame almeno ogni secondo. Ho usato l'approccio "cerca di" sopra, ma mi sono chiesto se potevo parallelizzare il compito.Ho usato i processi N con approccio FIFO qui: https://unix.stackexchange.com/questions/103920/parallelize-a-bash-for-loop/216475#216475
open_sem(){
mkfifo /tmp/pipe-$$
exec 3<>/tmp/pipe-$$
rm /tmp/pipe-$$
local i=$1
for((;i>0;i--)); do
printf %s 000 >&3
done
}
run_with_lock(){
local x
read -u 3 -n 3 x && ((0==x)) || exit $x
(
"[email protected]"
printf '%.3d' $? >&3
)&
}
N=16
open_sem $N
time for i in {0..39} ; do run_with_lock ffmpeg -ss `echo $i` -i /tmp/input/GOPR1456.MP4 -frames:v 1 /tmp/output/period_down_$i.jpg & done
Essenzialmente biforcato il processo con & ma limitato il numero di thread simultanei a N.
Questo ha migliorato la 'cercano di' approccio da 26 secondi a 16 secondi nel mio caso. L'unico problema è che il thread principale non esce in modo pulito sul terminale poiché lo stdout viene allagato.
http://ffmpeg.org/trac/ffmpeg/wiki/Seeking%20with%20FFmpeg può essere utile a voi – rogerdpack
^aggiornato url: https://trac.ffmpeg.org/wiki/Seeking – Lambart
Se si dispone di CPU cicli da risparmiare, puoi estrarre da più video in parallelo: 'parallel -i {} -r 1/1 {.} -% 03d.bmp ::: * mpg' –