使用具有最少重新编码的 FFMPEG 添加叠加层

Adding an Overlay Using FFMPEG With Minimal Re-Encoding

FFMPEG 对于剪切视频的一部分非常有用,无需重新编码视频。

我知道也可以使用 FFMPEG 在视频的特定部分(例如从 10 秒到 20 秒)向视频添加 叠加图像

我的问题是:如果我对图像进行这种叠加,整个视频是否会因此而重新编码?或者只对相关的持续时间进行编码?

还有什么选项可以使重新编码最小化吗?
目的当然是为了保持视频的质量与原始视频一样..
(我会要求完全不重新编码,但我不明白这怎么可能...)

谢谢

如果您在视频的一部分上叠加图像,整个视频将被重新编码。避免重新编码整个内容的一种方法是剪掉您希望覆盖的部分,只重新编码该部分(请参阅 -t duration 开关和 -ss position 开关19=]

您将希望在整个过程中保持当前的编码参数。这在拆分时很容易做到,因为您可以使用编解码器开关的复制参数,例如 -c:a copy -c:v copy

概念化(注意这些不是完整的命令):

第 1 部分:电影开头(您不希望覆盖的前 10 秒)(使用 ffmpeg -i SourceFileName -t 10 -c:a copy -c:v copy SourceFileNameP1.mkv 获得,其中 SourceFileName 是您要处理的视频。 Part2:您要叠加的 10 到 20 秒之间的电影部分(通过 ffmpeg -i SourceFileName -ss 10 -t 10 -c:a copy -c:v copy SourceFileNameP2 获得) Part3:电影结束(通过`ffmpeg -ss 20 -c:a copy -c:v copy获得)

额外提示:您可以通过将 `-ss 参数移动到输出文件之前来获得更慢但更精确的切割。这将从输出中丢弃帧,而不是在创建输出之前尝试在输入上寻找正确的位置。

如果不知道源文件的编码细节,可以用ffprobe SourceFileName或者我最喜欢的mediainfo SourceFileName

获取

我建议至少对中间输出使用 Matroska 容器,因为它的灵活性和低开销。

这是一个脚本,您可以使用(在基于 Debian 的系统上)获取匹配的必要参数。

#!/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 "[=10=]" requires a single filename argument. Example: "[=10=]" Videofile
    exit 2
fi
exist=$(which mediainfo)
    if [ "$exist" == "" ];
    then getmi
    fi
target=$(pwd)"/"".nfo"
    if [ -e $target ] 
    then 
    echo Error: ".nfo" already exists
    exit 3
    fi
echo "Creating $target"
        shortinfo "" > "$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.

完成后,您可以将所有部分拼接起来。

mkvmerge -o joined.mkv Part1 + Part2Reencoded + Part3

请注意,重新编码总是会导致一些质量损失,因此片段之间的连接处可能会出现明显的缺陷。由于叠加层同时出现和消失代码引起的干扰,这可能会或可能不会引人注意。

这可能会根据 material 的长度显着减少您的重新编码时间,并且具有仅重新编码必须重新编码的内容的额外好处。

涵盖了如何叠加重新编码的片段 ,您可以调整已接受的答案以匹配您的 material。

另一种方法是使用播放器:

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]"

无需编码。无质量损失。即时满足。