Secuencia de imágenes FFMPEG con varias duraciones

16

Digamos que tengo un archivo mp3 de 1 minuto de duración. Y tengo 20 imágenes png. Quiero combinar estas imágenes y un audio en un archivo de video, pero no quiero que cada imagen dure 3 segundos en la pantalla, quiero que algunas imágenes duren 5 segundos, otras 1 segundo, etc.

La única forma en que puedo pensar es simplemente copiar las imágenes que deberían durar más tiempo, por ejemplo, para que image1, image2, image3 sean exactamente iguales, esto me da 3 veces más tiempo en video.

Sin embargo, esto consume mucho tiempo y espacio. ¿Hay algún interruptor / parámetro en ffmpeg que me permita hacer eso?

Flot2011
fuente
Como descubrió, ffmpeg debería mostrar cada imagen con la misma longitud. Si desea variar la longitud, tendrá que duplicar las imágenes de antemano o crear videos separados de cada duración deseada y luego concatenarlos. Quizás otros usuarios tengan mejores ideas, pero este tipo de tarea podría ser más fácil con un editor como Kdenlive, etc.
llogan
Lo estoy haciendo desde el script php, por lo que el editor no es lo que estoy buscando.
Flot2011

Respuestas:

21

Usando ffmpeg 2.0 hay un par de formas de hacer esto:

  1. Un método es usar tiempos de modificación de archivos. Primero configure el tiempo de modificación de los archivos de imagen para que cada archivo de imagen tenga un tiempo de modificación mayor que el anterior; La diferencia horaria es la duración de la imagen anterior (con una resolución de 1 segundo). Luego use la opción image2 demuxer -ts_from_file 1. Por ejemplo:

    touch -t 01010000.00 image01.png
    touch -t 01010000.03 image02.png
    touch -t 01010000.08 image03.png
    ...
    ffmpeg -ts_from_file 1 -i image%2d.png -i audio.mp3 -c:a copy -vf fps=25 out.avi
    
  2. Otro método es usar el concatdemuxer , que toma una lista de archivos para concatenar, con duraciones opcionales. Primero cree un archivo que enumere sus imágenes y duraciones que tenga este aspecto:

    ffconcat version 1.0
    file image01.png
    duration 3
    file image02.png
    duration 5
    file image03.png
    

    Luego proporcione este archivo como entrada para ffmpeg. Por ejemplo:

    ffmpeg -i in.ffconcat -i audio.mp3 -c:a copy -vf fps=25 out.avi
    

Es posible que deba duplicar el último archivo después de la duración final. -c:a copycopia el audio mp3 tal como está; si desea convertirlo a otro códec de audio, puede especificarlo en lugar de copy. También es posible que desee especificar un códec de video diferente con -c:vun formato de píxel diferente -pix_fmt, como -c:v libx264 -pix_fmt yuv420p. -vf fps=25hará que la velocidad de cuadros de salida sea de 25 fps. Si su audio es más largo y desea que se corte después de las imágenes, use la -shortestopción.

mark4o
fuente
Alguna idea de por qué esto simplemente no parece funcionar (quiero decir, seguí la segunda opción (e intenté primero) al pie de la letra, pero solo emite un video negro sin imágenes o las imágenes solo parpadean para un cuadro, no varios segundos como se especifica en el archivo ffconcat.
sup
@sup: Esto todavía funciona para mí. Si el video es negro, entonces su reproductor puede no ser compatible con el formato de video que está utilizando; pruebe en -c:v libx264 -profile:v baseline -pix_fmt yuv420p out.mp4lugar de out.avi, o pruebe con un reproductor diferente como mpv o ffplay. También asegúrese de estar utilizando una versión actual de FFmpeg y duplique el último nombre de archivo de imagen después de la duración final.
mark4o
Hm, raro, U usa mpv y la compilación estática ffmpeg descargada de ffmpeg.org, y simplemente ignora las duraciones. De todos modos, encontré otra forma de hacer esto, por lo que no es tan importante: ffmpeg.org/pipermail/ffmpeg-user/2015-July/027702.html
sup
1

Asumiendo ffmpeg -i in.ffconcat -vf fps=25 out.avi

(2018: contenido del archivo in.ffconcat): esto funciona:

ffconcat versión 1.0
file text.png
duración 30.0
file text.png

mientras esto no

ffconcat versión 1.0
file text.png
duración 30.0

es decir, en el segundo caso

ffprobe out.avi -show_entries format=duration -v 0

[FORMATO]
duración = 0.040000
[/FORMATO]
Darek Adamkiewicz
fuente