Adding an Overlay Using FFMPEG With Minimal Re-Encoding

Another way of doing this is with a player:

ffplay -f lavfi "movie=main.mkv[bg];movie=logo.png[fg];[bg][fg]overlay=W-w-10:H-h-10:enable=between'(t,10,20)'[out0];amovie=main.mkv[out1]"

No encoding needed. No quality loss. Instant gratification.


The whole video will get re-encoded if you overlay an image on part of it. One way you could avoid re-encoding the entire thing would be to clip out the portion you wish to overlay and only re-encode that piece (see the -t duration switch and the -ss position switch in the documentation

You will want to maintain the current encoding parameters throughout the process. This is easy to do when splitting as you can use the copy parameter for the codec switch(es) such as -c:a copy -c:v copy

To conceptualize (note that these are not complete commands):

Part1: Beginning of Movie (first 10 seconds which you do not wish to overlay) (obtained with ffmpeg -i SourceFileName -t 10 -c:a copy -c:v copy SourceFileNameP1.mkv where SourceFileName is your video to process. Part2: Part of movie between 10 and 20 seconds that you want to overlay (obtained with ffmpeg -i SourceFileName -ss 10 -t 10 -c:a copy -c:v copy SourceFileNameP2) Part3: End of movie (obtained with `ffmpeg -ss 20 -c:a copy -c:v copy)

Bonus tip: you can get slower but more exact cutting by moving the `-ss parameter to before the output file. This will drop frames from the output rather than attempting to seek to the correct position on the input prior to creating output.

If you don't know the encoding details of the source file, you can obtain them with ffprobe SourceFileName or my favorite mediainfo SourceFileName

I'm recommending using a Matroska container for at least the intermediate output due to it's flexibility and low overhead.

Here's a script you can use (on Debian based systems) to obtain the necessary parameters to match.

#!/bin/bash
#mknfo.sh
#Written by Elder Geek for the Stack Exchange network
# 1/1/2018 
####################################################################################################
#bash script to create an nfo file which includes information to help joining video clips          #
####################################################################################################
# This function will create an nfo file including the tech specs for a specified media file        #
####################################################################################################
function shortinfo {
   echo $@
      mediainfo --Inform="General;Duration=%Duration/String2%\nFile size=%FileSize/String1%\nBit Rate=%OverallBitRate/String% " "$@"
   echo -n "Video: "
   mediainfo --Inform="Video;FrameRate=%FrameRate/String% BitRate=%BitRate/String% Resolution=%Width%x%Height% Codec=%CodecID%" "$@";
    echo -n "Audio: "
   mediainfo --Inform="Audio;Mode=%BitRate_Mode/String% BitRate=%BitRate/String% Format=%Format%" "$@";
   echo "-----------------------------------------------------------------------------"
}
####################################################################################################
# This function will check for the existence of mediainfo and attempt installation if not found     #
####################################################################################################
function getmi {
   echo "mediainfo is required and not found. Attempt install Y/N"
   read -n 1 solve
    if [ $solve=={Yy} ]
    then sudo apt-get -y install mediainfo
    else echo "Cannot continue"
    exit 1
    fi
}
####################################################################################################
# Main program                                             #
####################################################################################################
if [ $# -ne 1 ] 
    then    
    echo Error 
    echo "$0" requires a single filename argument. Example: "$0" Videofile
    exit 2
fi
exist=$(which mediainfo)
    if [ "$exist" == "" ];
    then getmi
    fi
target=$(pwd)"/"$1".nfo"
    if [ -e $target ] 
    then 
    echo Error: "$1.nfo" already exists
    exit 3
    fi
echo "Creating $target"
        shortinfo "$1" > "$target"
    exit 0


Now you'll want to re-encode the overlay section (Part2) of the video to exactly match the parameters (same audio and video codecs and same bitrate and sample rate as the original of Part1 and Part3 to allow for joining.

Once this is complete you can join all the pieces together.

mkvmerge -o joined.mkv Part1 + Part2Reencoded + Part3

Note that re-encoding always results in some quality loss so the joins between the pieces may show visible defects. This may or may not be noticeable with the distraction caused by the overlay appearing and disappearing at the same time codes.

This may reduce your re-encoding time significantly depending on the length of the material and has the added benefit of only re-encoding that which must be re-encoded.

How to overlay your re-encoded segment is covered here and you can adjust the accepted answer to match your material.