¿Cómo crear un video a partir de imágenes usando FFmpeg?

86

¿Es posible usar ffmpegcrear un video a partir de un conjunto de secuencias, donde el número no comienza desde cero?

Por ejemplo, tengo algunas imágenes [test_100.jpg, test_101.jpg, test_102.jpg, ..., test_200.jpg], y quiero convertirlas en un video. Intenté el siguiente comando, pero no funcionó (parece que el número debería comenzar desde cero):

ffmpeg -i test_% d.jpg -vcodec mpeg4 test.avi

¿Algún consejo?

JakeGould
fuente
Ha pasado un tiempo desde que preguntaste esto, pero si todavía estás interesado en la pregunta, la respuesta es SÍ. He publicado los detalles y un ejemplo a continuación: stackoverflow.com/a/12160155/181638
Assad Ebrahim
@casperOne sería útil para tener una idea de por qué esto está fuera de tema. Parece un problema de programación específico. La etiqueta tiene FFmpeg 3.7k seguidores, y con 27k puntos de vista con claridad personas les resulta útil ..
geotheory
2
@geotheory Las estadísticas de la etiqueta son irrelevantes. ffmpeg es un programa muy parecido a WinRar. Si bien puede programar contra las bibliotecas en ffmpeg , esta pregunta no se trata de eso. El uso de ffmpeg desde la línea de comandos se debe preguntar en Super User , donde se trata el tema.
casperOne

Respuestas:

81

No es necesario cambiar el nombre de los archivos si se usa el -start_numberinterruptor de esta manera:

ffmpeg -start_number n -i test_%d.jpg -vcodec mpeg4 test.avi

donde nes el comienzo de la secuencia de imágenes fijas.

Tenga en cuenta que esto funcionará siempre que la secuencia no se rompa una vez que comience. Si hay huecos y desea que se incluyan todas las imágenes fijas, puede ser necesario volver a numerar para llenar los huecos.

Hay algunos otros interruptores que pueden resultarle útiles.

Utilizo el siguiente one-liner para obtener una velocidad de fotogramas más lenta y para comprimir las imágenes y obtener un video resultante más pequeño:

ffmpeg.exe -f image2 -framerate 25 -pattern_type sequence -start_number 1234 -r 3 -i Imgp%04d.jpg -s 720x480 test.avi

La -r 3opción establece la velocidad de fotogramas del video resultante en 3 fotogramas por segundo para que pueda ver cada fotograma durante un corto período de tiempo. La -sopción vuelve a escalar las imágenes a la resolución deseada para administrar el tamaño del video resultante.

(En el shell de Windows, reemplácelo -i Imgp%04d.jpgcon -i "Imgp%%04d.jpg". Acredite esto a Mike Fitzpatrick https://superuser.com/a/344178/153054 )

Assad Ebrahim
fuente
44
¿Cuál es la diferencia entre -r y -framerate?
1
son el mismo IIRC
rogerdpack
22
No hay necesidad de numerar tonterías, siempre y cuando esté contento de aceptar el orden en que aparecen (diga) 'ls' ... solo use: ffmpeg -pattern_type glob -i '* .jpg' movie.mp4
Orwellophile
2
¿Hay algún cambio para controlar el intervalo de tiempo entre las imágenes, por ejemplo, me gustaría mostrar la primera imagen 13s, el segundo 15s, 24s para el tercero, el intervalo de tiempo está definido por el usuario, es posible?
zionpi
2
ver también trac.ffmpeg.org/wiki/…
david.libremone
38

puede usar este fragmento de código a continuación:

 cat *.jpg | ffmpeg -f image2pipe -r 1 -vcodec mjpeg -i - -vcodec libx264 out.mp4

fuente
Esto no rota los JPG a la rotación indicada en los metadatos.
Erik Johansson
17

Puede encontrar un script de ejemplo en la documentación de ffmpeg :

3.2 ¿Cómo codifico imágenes individuales en películas?

Si tiene un gran número de imágenes para cambiar de nombre, puede usar el siguiente comando para aliviar la carga. El comando, utilizando la sintaxis de shell bourne, vincula simbólicamente todos los archivos en el directorio actual que coinciden con * jpg a /tmp' directory in the sequence ofimg001.jpg ', `img002.jpg' y así sucesivamente.

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done

Entonces corre:

ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
gaizka
fuente
2
Sería mejor hacer que x = 0 comience para que el nombre de la imagen comience img000.jpg ya que esto es lo que espera ffmpeg. Además, el enlace simbólico no funcionó para mí, ya que ffmpeg no pudo encontrar los archivos, así que tuve que usar cp en su lugar (obvios inconvenientes de velocidad y espacio, pero los eliminé después de todos modos). mv también funcionaría si no te importa perder los originales.
Tenga en cuenta que en esta respuesta, el comando proporcionado crea enlaces duros, no enlaces simbólicos. Con respecto al uso de cpsi el enlace no funciona, si su sistema de archivos lo admite cp --reflink=auto, logrará un uso de velocidad / espacio mucho mejor.
Félix Saparelli
12

De los documentos de ffmpeg:

Usando un patrón glob

ffmpeg también es compatible con globing de estilo bash (* representa cualquier número de caracteres).

Esto es útil si sus imágenes son secuenciales pero no necesariamente en un orden numérico secuencial como en los ejemplos anteriores.

ffmpeg -r 1 -pattern_type glob -i 'test_*.jpg' -c:v libx264 out.mp4

Por lo tanto, siempre que sus archivos estén ordenados, usar el -pattern_type globinterruptor debería funcionar para usted.

Nevin Williams
fuente
Tenga en cuenta que este globo es más limitado que los globos de shell normales: trac.ffmpeg.org/ticket/3620 aparentemente porque el tipo de imagen se deduce de la extensión.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
11

Hasta donde yo sé, no puede comenzar la secuencia en números aleatorios (no recuerdo si debe comenzar en 0 o 1), además, no puede tener espacios, si lo hace, ffmpeg asumirá que la secuencia ha terminado y deja de agregar más imágenes.

Además, como se indica en los comentarios a mi respuesta, recuerde que debe especificar el ancho de su índice. Me gusta:

imagen% 03d.jpg

Y si usa un tipo de índice% 03d, debe rellenar sus nombres de archivo con 0, como:

image001.jpg image002.jpg image003.jpg

etc.

Francisco Soto
fuente
1
Si los nombres de los archivos de imagen tienen ceros a la izquierda, la cadena de formato también debe especificar el ancho como "% 03d".
1
Si ese es el único obstáculo, puede escribir un script para cambiar el nombre o vincular sus imágenes a un conjunto reindexado correctamente.
Cascabel
1
Sí, he trabajado con esto antes, escribí un contenedor en Ruby hace un tiempo donde llamaste instance.addImage (), luego instance.processVideo () y crearía un directorio temporal, copia / renombra las imágenes con los índices adecuados y crea el video. Es bastante fácil.
@Jefromi He creado un enlace simbólico, pero ¿cómo le doy la ruta del archivo de enlace simbólico a ffmpeg? ¿Solo asume que el archivo de enlace simbólico es la imagen que estoy tratando de convertir? Estoy en win7 por cierto
La secuencia puede comenzar en cualquier lugar de 0 a 4 inclusive.
Assad Ebrahim
5

Estoy de acuerdo con Francisco, pero como solución alternativa, podría escribir un script rápido para mover o crear enlaces simbólicos a los archivos con los números de secuencia que necesita ffmpeg. El script podría llamar a ffmpeg y luego eliminar los enlaces o mover los archivos a sus ubicaciones originales.

Jason B
fuente
1

buscar

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i"
/tmp/img"$counter".jpg; x=$(($x+1)); done

fuente
1

Sé que esta es una vieja pregunta, pero la encontré en Google mientras buscaba la misma respuesta. Ninguna de las respuestas aquí me satisfizo por completo, así que busqué y leí más y este es un comando que se me ocurrió para mi propio problema.

cat {0032..1501}*.png | ffmpeg -f image2pipe -framerate 5 -i - -s 720x480 test2.avi

La razón por la que usaría un comando como este es ...

  1. Cat y -f image2pipe le brindan un control más preciso sobre las imágenes que usa. Por ejemplo, le permite usar funciones bash como la expansión de soporte y otros comandos como grep para ajustar sus resultados si lo desea.
  2. Menos interruptores para recordar.
  3. Recomiendo NO usar -r, y solo usar -framerate en su lugar. En mi experiencia, -r tiende a soltar cuadros más a menudo.
  4. Menos complejo, no hay interruptores innecesarios en uso y funcionará tal cual. Puede agregar más complejidad (por ejemplo, especificar el codificador) y ajustar para satisfacer sus necesidades.
David Bobb
fuente
Para la pregunta del OP, -start_numberes todo lo que se necesita.
Gyan
0

Usé el codificador flv ya que mi video estaba en un reproductor flash (Jwplayer)

ffmpeg -i% d.jpg -vcodec flv test.flv


fuente
0

De la documentación , parece que simplemente puedes usar *

For example, for creating a video from filenames matching the glob pattern foo-*.jpeg:

ffmpeg -f image2 -pattern_type glob -framerate 12 -i 'foo-*.jpeg' -s WxH foo.avi

Como nota, para mejorar la calidad, la velocidad / fps puede ser importante (por ejemplo, ¿primero especificar una velocidad de cuadro muy baja / alta y luego pasar de un segundo filtro que hará que el video en cámara lenta sea normal?)

ntg
fuente
0

En mi caso, fue un poco más complicado debido a los números en los archivos. Así es como se ven mis imágenes:

$ ls | head -5
2014_aq_unprocessed 001.jpg
2014_aq_unprocessed 002.jpg
2014_aq_unprocessed 003.jpg
2014_aq_unprocessed 004.jpg
2014_aq_unprocessed 005.jpg

y aquí está el comando que usé:

ffmpeg -i 2014_aq_unprocessed\ %3d.jpg  -vcodec mpeg4 test.avi
Mona Jalal
fuente
0

Usted puede hacer esto con convert -morph:

convert *.jpg -delay 10 -morph 10 %05d.jpg

Si quieres usar ffmpeg, yo usé

ffmpeg -pattern_type glob -i '*.jpg' -vf "setpts=10*PTS" movie.mp4

donde 10*PTSle dice a ffmpeg que lo ralentice 10 veces. También puede tener fracciones allí para acelerarlo.

Martin Thoma
fuente
Esto es solo interpolar su secuencia de imagen original a un nuevo espacio, no crea un archivo de video como el OP solicitado.
f0ster
0

-pattern_type glob ejemplos concretos con audio

Esta opción se mencionó en: https://superuser.com/a/782520/128124 pero aquí hay algunos ejemplos concretos de su uso, incluida la adición de audio al video de salida.

Vídeo de presentación de diapositivas con una imagen por segundo

ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
  -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Agregue algo de música, corte cuando el audio cuando finalicen las imágenes:

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Aquí hay dos demos en YouTube:

Sea un hippie y use el formato de video sin patente de Theora :

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libtheora -r 30 -pix_fmt yuv420p out.ogg

Sus imágenes, por supuesto, deben ordenarse alfabéticamente, generalmente como:

0001-first-thing.jpg
0002-second-thing.jpg
0003-and-third.jpg

y así.

Ver también: http://unix.stackexchange.com/questions/68770/converting-png-frames-to-video-at-1-fps/339399#339399

Video de velocidad normal con una imagen por cuadro a 30 FPS

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -c:v libx264 -pix_fmt yuv420p out.mp4

Así es como se ve:

GIF generado con: https://askubuntu.com/questions/648603/how-to-create-an-animated-gif-from-mp4-video-via-command-line/837574#837574

Agregue un poco de audio:

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4

Resultado: https://www.youtube.com/watch?v=HG7c7lldhM4

Convierta un archivo de música en un video con una imagen fija para cargar en YouTube

Respondido en: ¿Cómo convertir MP3 a formato de video permitido por Youtube?

Obtenga algunas imágenes de entrada de prueba sintéticas

Estas son las imágenes de prueba que he estado usando en esta respuesta:

wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true
unzip opengl-rotating-triangle.zip
cd opengl-rotating-triangle
wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg

Imágenes generadas con: https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292

Es genial observar cuánto comprime el video la secuencia de imágenes mucho mejor que ZIP, ya que puede comprimir a través de cuadros con algoritmos especializados:

  • opengl-rotating-triangle.mp4: 340K
  • opengl-rotating-triangle.zip: 7.3M

Sobre las opciones de CLI

Sin embargo, -globtenga en cuenta que a pesar del nombre, esto no es tan general como los patrones de Shell Glob, por ejemplo: -i '*'falla: https://trac.ffmpeg.org/ticket/3620 (aparentemente porque el tipo de archivo se deduce de la extensión).

-r 30hace que el -framerate 1video sea de 30 FPS para superar errores en jugadores como VLC para bajas tasas de cuadros: https://stackoverflow.com/questions/19267443/playback-issues-in-vlc-with-low-fps-video-from-images-using- ffmpeg / 41797724 # 41797724 Por lo tanto, repite cada fotograma 30 veces para mantener el efecto deseado de 1 imagen por segundo.

Próximos pasos

También querrás:

TODO: aprenda a cortar y concatenar múltiples archivos de audio en el video desde la línea de comandos:

Probado en

ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04.

Bibliografía

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
fuente