Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Let's say I have an mp3 file of 1 minute length. And I have 20 png images. I want to combine these images and an audio into a video file, but I do not want each image to last 3 seconds on screen, I want some images to last 5 seconds, others 1 second etc.

The only way I can think of is just copy the images that should last more time, e.g. to have image1, image2, image3 to be exactly the same, this gives me 3x more time in video.

However this is very time and space consuming. Is there any switch / parameter in ffmpeg that allows me to do that?

share|improve this question
    
As you found out ffmpeg should display each image for the same length. If you want to vary the length you will have to duplicate the images beforehand or create separate videos of each desired duration and then concatenate them. Maybe some other users have better ideas, but this type of task might be easier with an editor such as Kdenlive, etc. – LordNeckbeard Jul 9 '13 at 17:22
    
I am doing it from php script, so editor is not what I am looking for. – Flot2011 Jul 10 '13 at 0:53
up vote 10 down vote accepted

Using ffmpeg 2.0 there are a couple of ways to do this:

  1. One method is to use file modification times. First set the modification time of the image files so that each image file has a modification time greater than the one before it; the time difference is the duration of the previous image (with 1 second resolution). Then use the image2 demuxer option -ts_from_file 1. For example:

    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. Another method is to use the concat demuxer, which takes a list of files to concatenate, with optional durations. First create a file listing your images and durations that looks like this:

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

    Then provide this file as input to ffmpeg. For example:

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

You may need to duplicate the last file after the final duration. -c:a copy copies the mp3 audio as-is; if you want to convert it to another audio codec then you can specify that instead of copy. You may also want to specify a different video codec with -c:v or a different pixel format with -pix_fmt, such as -c:v libx264 -pix_fmt yuv420p. -vf fps=25 will make the output frame rate 25 fps. If your audio is longer and you want it cut off after the images, use the -shortest option.

share|improve this answer
    
Any idea why this just does not seem to work (I mean, I followed the second (and tried to first) option to the letter but it just outputs either a black video with not images or the images just flash for one frame, not several seconds as specified in the ffconcat file. – sup Jul 25 '15 at 11:31
    
@sup: This still works for me. If the video is black then your player may not support the video format you are using; try -c:v libx264 -profile:v baseline -pix_fmt yuv420p out.mp4 instead of out.avi, or try a different player such as mpv or ffplay. Also be sure you are using a current version of FFmpeg, and duplicate the last image file name after the final duration. – mark4o Jul 27 '15 at 22:01
    
Hm, weird, U use mpv and the ffmpeg static build downloaded from ffmpeg.org, and it just ignores the durations. Anyway, I found another way how to do this, so it is not that important: ffmpeg.org/pipermail/ffmpeg-user/2015-July/027702.html – sup Jul 28 '15 at 7:51

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .