I have a few hours long MP4 video (h264+AAC) and I need to replace small parts of it with another video (or audio only). The reason is that the file is a recording of a live session and I need to blackscreen/mute parts of it before publishing.

I would like to use ffmpeg. I've found a lot of information about filter complex, concat, etc... but I would like to know if there is any simpler way before I dwell into all of this. Or at least a hint which functionality of filter_complex I should use.

Until now I do it by hand in Premiere Elements where I take the main video and put another clip into second track. And I would like to automate the whole process...

  • Do you have a list of where and how long this needs to be done? – Gyan Jun 28 '16 at 10:53
  • Yes, the "input" of this process is a list of times (from-to or from+length) to "anonymize". And I will create some form of tool that will call ffmpeg to do it.... – Radek Hladík Jun 28 '16 at 11:33
  • So, will those portions of the video be blacked out or replaced with another video? Similarly for audio, muted or another audio? – Gyan Jun 28 '16 at 11:44
  • I would like to replace them with short video clip and I would like to choose if I replace audio and/or video track. That short clip will probably be black but may contain some sort of text "this portion of the video has been....") and same with the audio. Blackout and mute would be probably enough for now but I need to be ready for more :-) And it is important that the timing of the main video will remain unchanged... – Radek Hladík Jun 28 '16 at 11:54

Assuming you want to blackout the video and mute the audio where needed, your basic command template would be

ffmpeg -i video.mp4 -f lavfi -i "color=black:s=1280x720:r=25" -filter_complex \
"[0:v][1]overlay=enable='between(t,25,35)'[a]; \
 [a][1]overlay=enable='between(t,80,90)'[b]; \
 [b][1]overlay=enable='between(t,94,115)'[c]; \
 [n][1]overlay=enable='between(t,4805,4821)'[video]; \
 [0:a]volume=0:enable='between(t,25,35)', \
      volume=0:enable='between(t,80,90)', \
      volume=0:enable='between(t,94,115)', \
      volume=0:enable='between(t,4805,4821)'[audio]" \
-map "[video]" -map "[audio]"  output.mp4

The color size and rate should be the same as your video.

If you want to replace the blackscreen with an image, remove the -f lavfi and the color expression and add -loop 1 before -i image.jpg.

  • I accepted this as an answer. Just to be clear, with the video you create multiple steps ([a],[b],[c]) each with one blackout while in the audio you create only one ([audio]) with all the mutes? – Radek Hladík Jun 28 '16 at 12:30
  • Yes, since overlay requires two inputs. It's best to terminate the filterchain and start a new one. – Gyan Jun 28 '16 at 12:33
  • It seems to work. Just one question. Would it be possible to avoid re-encoding the "untouched" parts? I understand that there would be some margins around the blackout parts because of keyframes but I would like to copy the rest of the file... – Radek Hladík Jun 28 '16 at 12:50
  • Depending on how many censored segments there are, it would be too much trouble, both in intermediate file creation and stitching it back together. Basic method would be to use segment muxer in copy mode with -segment_times values to split video. Then perform overlay in the required segments and encode to same parameters as original video. Then use concat demuxer to join untouched and re-encoded segments back together. Best to re-encode entire audio using the method in my answer. – Gyan Jun 28 '16 at 13:02
  • 1
    Add shortest to the overlays like this: [a][1]overlay=enable='between(t,80,90)':shortest=1[b]; – Gyan Jun 29 '16 at 9:42

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.