FFmpeg puede capturar imágenes de videos que pueden usarse como miniaturas para representar el video. Las formas más comunes de hacerlo están capturadas en el FFmpeg Wiki .
Pero, no quiero elegir marcos aleatorios en algunos intervalos. Encontré algunas opciones usando filtros en FFmpeg para capturar cambios de escena:
El filtro thumbnail
intenta encontrar los cuadros más representativos en el video:
ffmpeg -i input.mp4 -vf "thumbnail,scale=640:360" -frames:v 1 thumb.png
y el siguiente comando selecciona solo los cuadros que tienen más del 40% de los cambios en comparación con los anteriores (y probablemente sean cambios de escena) y genera una secuencia de 5 PNG.
ffmpeg -i input.mp4 -vf "select=gt(scene\,0.4),scale=640:360" -frames:v 5 thumb%03d.png
Información de crédito para los comandos anteriores a Fabio Sonnati . El segundo parecía mejor, ya que podía obtener n imágenes y elegir el mejor. Lo probé y generó la misma imagen 5 veces.
Un poco más de investigación me llevó a:
ffmpeg -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.png
-vsync vfr
asegura que obtengas imágenes diferentes. Esto siempre selecciona el primer fotograma del video, en la mayoría de los casos el primer fotograma es créditos / logotipo y no tiene sentido, así que agregué un -ss
3 para descartar los primeros 3 segundos del video.
Mi comando final se ve así:
ffmpeg -ss 3 -i input.mp4 -vf "select=gt(scene\,0.5)" -frames:v 5 -vsync vfr out%02d.jpg
Esto fue lo mejor que pude hacer. Me di cuenta de que, dado que elijo solo 5 videos, todos son en su mayoría desde el comienzo del video y pueden perderse escenas importantes que ocurren más adelante en el video
Me gustaría elegir tu cerebro para cualquier otra opción mejor.
fuente
libopenjpeg
... no estoy seguro si eso hace la diferencia.mjpeg
codificador para mí, y también compruebojpegoptim
yexiv2
, ambos funcionan bien para mí con todos los resultados JPG de sus comandos de ejemplo.Respuestas:
¿Qué tal si busca, idealmente, el primer marco de cambio> 40% dentro de cada uno de 5 intervalos de tiempo, donde los intervalos de tiempo son el 1 °, 2 °, 3 °, 4 ° y 5 ° 20% del video.
También puede dividirlo en 6 períodos de tiempo y pasar por alto el primero para evitar créditos.
En la práctica, esto significaría establecer los fps en un número bajo mientras aplica la verificación de cambio de escena y su argumento para tirar el primer fragmento del video.
...algo como:
fuente
Unable to find a suitable output format for 'fps=fps=1/600'
. La solución es agregar-vf
antes de ese argumento (ver stackoverflow.com/questions/28519403/ffmpeg-command-issue )Definir el significado es difícil, pero si desea que las miniaturas de N abarquen todo el archivo de video de manera eficiente, esto es lo que uso para generar miniaturas en producción con contenido cargado por el usuario.
Pseudocódigo
Dónde:
ffmpeg -i <movie>
solo offprobe
que tiene un buen escritor de salida JSON por ciertoSimplemente lo anterior escribe el fotograma clave central de cada partición de la película. Por ejemplo, si la película tiene 300 segundos de duración y desea 3 miniaturas, se necesita un fotograma clave después de 50, 150 y 250 segundos. Para 5 miniaturas sería 30s, 90s, 150s, 210s, 270s. Puede ajustar N dependiendo de la duración de la película D, por ejemplo, una película de 5 minutos tendrá 3 miniaturas pero más de 1 hora tendrá 20 miniaturas.
Actuación
Cada invocación del
ffmpeg
comando anterior toma una fracción de segundo (!) Para ~ 1GB H.264. Esto se debe a que salta instantáneamente a la<time>
posición (mente-ss
antes-i
) y toma el primer fotograma clave que es prácticamente completo JPEG. No se pierde tiempo en hacer que la película coincida con la posición exacta del tiempo.Postprocesamiento
Puede mezclar arriba con
scale
o cualquier otro método de cambio de tamaño. También puede eliminar marcos de color sólido o intentar mezclarlo con otros filtros comothumbnail
.fuente
-ss N
a antes-i
es un consejo increíble. ¡gracias!Una vez hice algo similar, pero exporté todos los cuadros del video (en 1 fps) y los comparé con una utilidad perl que encontré que calcula la diferencia entre las imágenes. Comparé cada cuadro con las miniaturas anteriores, y si era diferente de todas las miniaturas, lo agregué a la colección de miniaturas. La ventaja aquí es que si su video se mueve de la escena A a B y regresa a A, ffmpeg exportará 2 cuadros de A.
fuente
Prueba esto
Con este comando, puedo generar la cantidad requerida de miniaturas que son representativas de todo el video.
fuente
fps
ser(no_of_frames_req * fps_of_vid) / total_video_frames
?Esto es lo que hago para generar una miniatura periódica para transmisiones m3u8 en vivo para usar como póster. Descubrí que ejecutar una tarea ffmpeg continua solo para generar miniaturas consume toda mi CPU, por lo que ejecuto un cronjob cada 60 segundos que genera todas las miniaturas para mis transmisiones.
Si necesita hacerlo con más frecuencia de 60 segundos (limitación de cronjob), puede hacer un
while
bucle en su script y se ejecutará para siempre. Simplemente agregue asleep 30
para cambiar la frecuencia a 30 segundos. Sin embargo, no recomiendo hacer esto con una gran cantidad de videos, ya que la ejecución anterior puede no completarse antes de que comience la siguiente.Idealmente con cronjob solo lo ejecuto cada 5 minutos.
fuente