¿La forma más rápida de extraer fotogramas usando ffmpeg?
Hola, necesito extraer fotogramas de videos usando ffmpeg. ¿Existe una manera más rápida de hacerlo que esta?
ffmpeg -i file.mpg -r 1/1 $filename%03d.jpg
?
Si el paso de codificación JPEG requiere demasiado rendimiento, siempre puedes almacenar los fotogramas sin comprimir como imágenes BMP:
ffmpeg -i file.mpg -r 1/1 $filename%03d.bmp
Esto también tiene la ventaja de no incurrir en más pérdida de calidad a través de la cuantificación mediante la transcodificación a JPEG. (PNG tampoco tiene pérdidas, pero tiende a tardar mucho más en codificarse que JPEG).
Me encontré con esta pregunta, así que aquí hay una comparación rápida. Compare estas dos formas diferentes de extraer un fotograma por minuto de un vídeo de 38m07s de duración:
time ffmpeg -i input.mp4 -filter:v fps=fps=1/60 ffmpeg_%0d.bmp
1m36.029s
Esto lleva mucho tiempo porque ffmpeg analiza todo el archivo de vídeo para obtener los fotogramas deseados.
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
Esto es aproximadamente 20 veces más rápido. Usamos la búsqueda rápida para ir al índice de tiempo deseado y extraer un fotograma, luego llamamos a ffmpeg varias veces para cada índice de tiempo. Tenga en cuenta que -accurate_seek
es el valor predeterminado
y asegúrese de agregarlo -ss
antes de la -i
opción de entrada de video.
Tenga en cuenta que es mejor utilizarlo -filter:v -fps=fps=...
en lugar de, -r
ya que este último puede ser inexacto. Aunque el ticket está marcado como solucionado , todavía experimenté algunos problemas, así que será mejor que vayamos a lo seguro.
Esto es más simple que todos los demás comandos hasta ahora:
ffmpeg -i input.mp4 '%04d.png'
Cambie 04
a la cantidad de dígitos que necesite para contener todos los fotogramas. Asegúrese de tener siempre un 0
antes del número para que los nombres de los fotogramas de salida se rellenen con ceros.
Si sabe exactamente qué cuadros extraer, por ejemplo, 1, 200, 400, 600, 800, 1000, intente usar:
select='eq(n\,1)+eq(n\,200)+eq(n\,400)+eq(n\,600)+eq(n\,800)+eq(n\,1000)' \
-vsync vfr -q:v 2
Estoy usando esto con una tubería para el montaje de Imagemagick para obtener una vista previa de 10 cuadros de cualquier video. Obviamente, los números de cuadro que necesitarás calcular usandoffprobe
ffmpeg -i myVideo.mov -vf \
select='eq(n\,1)+eq(n\,200)+eq(n\,400)+eq(n\,600)+eq(n\,800)+eq(n\,1000)',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
.
Pequeña explicación:
- En expresiones ffmpeg
+
significa OR y*
AND \,
simplemente está escapando del,
personaje- Sin
-vsync vfr -q:v 2
él no parece funcionar, pero no sé por qué. ¿Alguien?