0

I'm trying to add blankspace to the end of a video (1 audio stream, 1 video stream) using ffmpeg. I'm curious what the best way of doing this is. I'm not very keen on using filter_complex so if there's another simple/viable method, that would be good. I've been trying to use the color filter using the command below, it's making a video with bad timestamps though. On playback it freezes in various parts of the blankspaced segment, my command is missing something.

ffmpeg -i input.mkv -filter_complex "color=black:s=1280x720:d=15[b0];[0:v][b0]concat=n=2:v=1:a=0" output.mkv

I receive the green/yellow message below at the point where it starts to render the black frames.

[Parsed_color_0 @ 0000000922e0fd900] EOF timestamp not reliable

This method is effectively making another video and concatenating it to the first one. I'm wondering if in general: Can you create frames in an existing video...? Or is that outside of how ffmpeg works?

enter image description here

  • @llogan That would be great, pic posted. I also looked up tpad and tried: ffmpeg -i testvid.mkv -vf tpad=start=360:color=0xF0F8FF out.mkv But it said "No such filter: 'tpad'". Guessing I'm doing that one wrong too. – kite Mar 28 at 13:57
  • 1
    It's always better to copy and paste the log, since it's text anyway, instead of making a screenshot. It makes answering easier. – llogan Mar 28 at 18:47
3

Method 1: concat demuxer

  • Pros: Avoids re-encoding the main video and therefore preserves quality since it is stream copied. Fast.
  • Cons: Requires several steps. Harder to get right, because the blank video needs to have the same attributes as the main video.

Make the black video using same attributes and same number and type of streams as the main input. This example makes a 15 second black video, frame rate of 24, size is 1280x720:

 ffmpeg -f lavfi -i color=c=black:s=1280x720:r=24:d=15 black.mkv

Make input.txt. The order in this text file determines the order that they will appear when concatenating.

file 'main.mkv'
file 'black.mkv'

Concatenate:

ffmpeg -f concat -i input.txt -c copy output.mkv

Method 2: concat filter

  • Pro: Can all be done in one command.
  • Con: Filtering requires encoding, so no stream copying of the main video as in the concat demuxer. Some attributes must still be matched.

Use the color source filter to make the 15 second, 24 fps, 1280x720 black video and append it to the end of the main video with the concat filter:

ffmpeg -i main.mkv -filter_complex "color=c=black:s=1280x720:r=24:d=15[black];[0:v][black]concat=n=2:v=1:a=0[v]" -map "[v]" output.mkv

If you prefer the black to be at the beginning instead then switch the order for the concat filter inputs, such as [black][0:v]concat….


Method 3: tpad and apad filters

  • Pro: Easy. No need to match any attributes.
  • Cons: Filtering requires encoding, so no stream copying of the main video as in the concat demuxer. Relatively new filters: use FFmpeg 4.2 or newer, or even better use a build from the current git master branch.

Append 15 seconds of black video to the end of the main video:

ffmpeg -i main.mkv -filter_complex "tpad=stop_duration=15" output.mkv

If you want it at the beginning instead use start_duration instead of stop_duration. If you want to clone the frames instead, or want a different color than black then refer to the tpad filter documentation.

| improve this answer | |
  • This helps significantly, just 3 issues: (1) Why is there the 'c' in "color=c=black"? Is there a difference vs using "color=black" (seemed the same when tried)? In 14.8 of the docs it lists titles of sections as "color,c" and "duration,d". Doesn't this mean d and duration are interchangeable cmds? Then why does "c=black" give an error? (2) What does 'pad' in "pad video frames" mean? (3) Does ffmpeg not have a way to add frames to an existing video in a 'single' simplified cmd? I was hoping to re-encode like 'method 2', but to create 'new frames', I can't afford to overwrite existing frames. – kite Mar 29 at 20:06
  • 1
    @kite 1) It is recommended to include the option name with the value instead of just the value; especially when many other options are being declared. It makes things less ambiguous and you know what you're going to get. c is a shortened alias for the color option in the color filter. Same with d and duration as you mentioned. c=black gives an error (probably No such filter: 'c') because you are telling it that c is the filter name, but there is no filter named c. Order is like this: filterA=option1=value1:option2=value2,filterB=optionB1=valueB1:optionB2=valueB2. – llogan Mar 29 at 21:17
  • 1
    @kite 2) "pad" just means to extend, fill, or add. For example, take a 5 second input and extend/fill/add/pad it with black frames at the beginning and/or end to make it 8 seconds. In a way it's similar to padding in CSS if you're familiar with that element. 3) Both methods #2 and #3 are single commands, and method #3 is fairly simple. Neither method is overwriting any frames. They are just creating new frames and adding to them the end (and/or beginning if you prefer) of the main input. – llogan Mar 29 at 21:17
  • Apologies for my confusion, I misread the video durations and made the wrong assumptions. One final Q: For a movie with [0:0]video+[0:1]audio stream, for method 3 using tpad: adding an "apad=pad_dur=10" worked fine. Of interest though: The docs said you could use -shortest to extend audio streams to the same length as the video stream. Upon trying -filter_complex "tpad=stop_duration=15;apad" -shortest it seems to render an infinitely long video out. I tried writing it like [0:1]apad but no difference either. My intent was to use -shortest to avoid writing out the pad_dur=10 part. – kite Mar 30 at 8:17
  • 1
    @kite IIRC, that's a known bug. – llogan Mar 30 at 17:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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