To get each image to have a different time shown, instead of all images having the same time, you'll have to use the concat demuxer and a text file.
Create a text file like the following, ordering the images as you'd want them.
file img_001.jpg
outpoint 5
file img_002.jpg
outpoint 3
file img_003.jpg
outpoint 9
.... [keep going until you've included all the images]
Then you run the following command:
ffmpeg -f concat -i [name you gave above text file] [your commands] output.mp4
Explanation
- The command uses
-f concat
demuxer to add all the files listed in the text file to a single output.
- The text file lists the file name, then lists the amount of time to show it in seconds.
- If just the three files in the example are run, you will get a 17 second video that shows 3 images; the first for 5 seconds, the second for 3 seconds, and the third for 9 seconds.
- The framerate will be whatever you specify under
[your commands]
(the correct flag here would be -r
) or default to 30 fps (I think) if you do not specify anything.
- You can give partial seconds with a decimal.
- You can put full file paths with the file name, but will also have to include
-safe 0
after concat
for it to work. This is not necessary if they are relative paths.
Differences when working with video files instead of images:
In the text file, the format is usually like what is found in this similar question/answer, where you specify an "inpoint" as well as an "outpoint". The inpoint is where in the video input timeline you want to start, and the outpoint is for how many seconds you want to go. However, when the input file is an image (instead of a video) the inpoint creates an error, so you have to leave it out.
A Caveat
The concat demuxer requires all input files to have the same streams. This means basically everything like framerate and codec must be the same, but the container can be different. I've never tried this method with different image types, but I assume something like a mix of jpeg and png inputs would throw an error.
If you want to concatenate files of different types, you will have to use the concat filter. It's not as intuitive, but you have full control and won't need a text file. The above demuxer solution in the filter form looks like this (line breaks added for readability):
ffmpeg -loop 1 -t 5 -i img_001.jpg
-t 3 -i img_002.jpg
-t 9 -i img_003.jpg
filter_complex "[0:v:0][0:a:0]
[1:v:0][1:a:0]
[2:v:0][2:a:0]
concat=n=3:v=1:a=1
[outv][outa]"
-map "[outv]" -map "[outa]"
[your commands] output.mp4
Basically, you name all the inputs at the beginning of the command. -loop 1
lets ffmpeg treat the images like looping video, so you don't have an inpoint. A video file can specify an inpoint with -ss
before the -t
, and will take 0 seconds as the default if not specified. filter_complex
does all the work. The items like [0:v:0]
are calling the inputs, specifying which input and what stream. concat=n=3:v=1:a=1
tells how many files the filter should expect (n=3
) and how many video and audio streams to output (v=1:a=1
). [outv][outa]
Are kind of like user created variables. You would either send these to additional filters, or map them to the output (-map "[outv]" -map "[outa]"
).
Like I said, the filter is not very intuitive, so if you need further help writing your filtergraph, ask another question or follow the links I've already given.