video - reproducir - ffmpeg tutorial
La forma más rápida de extraer marcos usando ffmpeg? (4)
En mi caso necesito marcos al menos cada segundo. Usé el enfoque de "buscar" que se encuentra arriba, pero me pregunté si podría paralelizar la tarea. Usé los procesos N con enfoque FIFO aquí: 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
(
"$@"
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
Básicamente, bifurqué el proceso con & pero limité la cantidad de hilos concurrentes a N.
Esto mejoró el enfoque de "buscar" de 26 segundos a 16 segundos en mi caso. El único problema es que el hilo principal no sale limpiamente de vuelta al terminal ya que stdout se inunda.
Hola, necesito extraer fotogramas de videos usando ffmpeg ... ¿Hay una forma más rápida de hacerlo que esto?
ffmpeg -i file.mpg -r 1/1 $filename%03d.jpg
?
Me encontré con esta pregunta, así que aquí hay una comparación rápida. Compara estas dos formas diferentes de extraer un cuadro por minuto de un video de 38m07s de largo:
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 video para obtener los cuadros 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 cuadro, luego llamar ffmpeg varias veces para cada índice de tiempo. Tenga en cuenta que -accurate_seek
es el valor predeterminado y asegúrese de agregar -ss
antes de la opción de entrada de video -i
.
Tenga en cuenta que es mejor usar -filter:v -fps=fps=...
lugar de -r
ya que este último puede ser inexacto. Aunque el ticket está marcado como fijo , todavía experimenté algunos problemas, así que es mejor ir a lo seguro.
Si el paso de codificación JPEG es demasiado intensivo en el rendimiento, siempre puede almacenar los marcos 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 también es sin pérdida, pero tiende a tomar mucho más tiempo que JPEG para codificar).
Si sabe exactamente qué marcos extraer, p. Ej. 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 pipa para el montaje de Imagemagick para obtener una vista previa de 10 marcos de todos los videos. Obviamente, los números de los cuadros necesitarán descubrir usando 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
.
Poca explicación
- En expresiones ffmpeg
+
significa OR y*
para Y -
/,
simplemente está escapando del personaje - Sin
-vsync vfr -q:v 2
parece que no funciona, pero no sé por qué, ¿alguien?