76

I have many videos and I need to put an image in front of them for about 5 seconds, but adding it manually and rendering it each time would take really long, so I am asking if it is possible to do so via ffmpeg and if you could, please, help me out with it since I have no experience with ffmpeg. I've found some commands already but none of them worked. This one for example.

ffmpeg -itsoffset 5 -i in.mp4 -r 25 -loop 1 -i intro.png -filter_complex "[1:v] fade=out:125:25:alpha=1 [intro]; [0:v][intro] overlay [v]" -map "[v]" -map 0:a -acodec copy out.mp4
2
  • 2
    Did your just copy that command or wrote that according to your needs? I'm asking because this command involves things like a fade out and all kinds of other stuff not covered in your question. Do you just need to overlay an image or do you need more than that?
    – timonsku
    Commented Jul 7, 2014 at 12:18
  • 1
    I copied it from somewhere, all I need is just to put the image in front of video.
    – Azthy
    Commented Jul 8, 2014 at 9:11

3 Answers 3

112

You can do a simple image overlay using the following syntax:

ffmpeg -i input.mp4 -i image.png \
-filter_complex "[0:v][1:v] overlay=25:25:enable='between(t,0,20)'" \
-pix_fmt yuv420p -c:a copy \
output.mp4

overlay=25:25 means we want to position the image 25px to the right and 25px down, originating from the top left corner (0:0).

enable='between(t,0,20)' means we want the image to show between second 0 and 20.

[0:v][1:v] means that we want the first video file we import with -i, in our case input.mp4 or how ffmpeg sees it, video input file number 0, to be under video input file 1, in our case image.png. :v just means we want the video track from these file sources. [0:a] would mean we want the first imported audio track. Which would also come from input.mp4 but would point to the audio track instead of the video track in the mp4 file.

If you want a certain image quality/settings and not the settings ffmpeg chooses, add the image and or audio encoding options you want to use. The default video encoder will be x264. Check the H.264 encoding guide for possible settings.

The -acodec copy / -c:a copy that you have in your command f.e. would simply re-use the audio from the source file. Though you can't do that with the video of course (in this case), that has to be transcoded because we are creating a new video source.

If you want to transcode audio, remove the -c:a copy part. You may have to explicitly specify an encoder, e.g. -c:a aac -strict experimental. See the AAC encoding guide for more info.

17
  • 5
    Your command replaces a fragment of the original video file, but a user may want to add (thus increasing the video length) an image before and/or after the video. Please help with this
    – porton
    Commented Jun 4, 2017 at 20:47
  • 1
    @PTS In fact, that is exactly the question being asked here, which you did not answer at all. Nowhere did he ask how to overlay an image on top of the video, but how to insert it before the video starts (using the overlay filter). Note the wording of the question, the -itsoffset in his example code, and the undesirable alternative (rendering it separately).
    – Wlerin
    Commented Jul 8, 2018 at 8:46
  • 2
    He may have tried it because of the apparently confusing wording. If it wasn't what he wanted then he probably wouldn't have accepted it as an answer to this question. If you have a problem with that you are always free to ask a new question covering the case you are looking for.
    – timonsku
    Commented Jul 8, 2018 at 21:55
  • 2
    @laurent that depends on your source file and or output. pix_fmt stands for pixel format. There are a lot of different pixel formats available for different codecs, specifying one ensure you don't end up with something that doesn't work out for you. yuv420p is the most supported pixel format when it comes to h264 but there is also yuv422p and yuv444p for example.
    – timonsku
    Commented Mar 29, 2019 at 14:24
  • 3
    Is there a way to also resize the image before overlaying it, or does that have to be done beforehand? Commented Mar 18, 2021 at 22:04
18

This is an addition to the excellent answer by PTS and an answer for chovy. If you want to place the overlay at the lower right corner, FFMPEG can calculate that for you very easily.

Use the modified command:

ffmpeg -i input.mp4 -i image.png \
-filter_complex "[0:v][1:v] overlay=W-w:H-h:enable='between(t,0,20)'" \
-pix_fmt yuv420p -c:a copy \
output.mp4

The W-w means main video width minus overlay width, and the same for H-h.

4
  • 2
    Thank you for telling the secret answer: what is W-w, it's really unclearly said in documentation about it.
    – Alex Sham
    Commented Nov 1, 2020 at 18:27
  • 2
    @AlexSham W is an ffmpeg alias for the width of the video you are overlaying on, and w is the alias for the width of the image being overlaid. Same with H and h. These can also be referred to as main_w (or _h) and overlay_w (or _h) Commented Mar 18, 2021 at 22:08
  • Thanks for this trick. What if w is bigger than W or h is bigger than H. My objective is to center the overlay on the video no matter what their sizes are. I am afraid ffmpeg might throw an exception if there are negative values. Also does filter_complex make the output video the same size as the input video always? Or does it make it the same size as the bigger size of the input video and overlay png?
    – aytunch
    Commented Jul 22, 2021 at 16:16
  • I'm not sure about the functionality if the overlay is larger, as that is an unusual use case. Perhaps something like (W-w)/2?
    – Slappy_G
    Commented Jul 24, 2021 at 22:55
1

If you wanna resize the image.

ffmpeg -i input.mp4 -i image.png -filter_complex "[1:v]scale=480:854[overlay]; [0:v][overlay]overlay=0:0:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy output.mp4
1
  • Piece of advice: please don't ever answer in comments. That is not what they are for.
    – Dr Mayhem
    Commented May 13 at 17:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.