FFMPEG is really useful for cutting a part of a video, without re-encoding the video.
I know it is also possible to use FFMPEG for adding an Overlay Image to a video, in a certain part of the video (for example from 10secs till 20secs).
My question is: If I do this overlaying of an image, will the whole video get re-encoded because of that? Or just the relevant duration will be encoded?
Also are there any options that I can use to make the re-encoding minimal?
The purpose if of course to keep the quality of the video like the original one..
(I would ask for no re-encoding at all, but I don't see how that might be possible...)
Thank you
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.
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.