使用FFMPEG以最小的重新编码添加覆盖

spa*_*man 5 video ffmpeg video-editing

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

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

我的问题是:如果我对图像进行覆盖,是否会因此而对整个视频重新编码?还是只是相关的持续时间会被编码?

还有什么我可以用来使重新编码最少的选项?
目的当然是保持视频质量像原始视频一样。.
(我根本不要求重新编码,但我不知道这怎么可能...)

谢谢

Eld*_*eek 3

如果您在视频的一部分上叠加图像,整个视频将被重新编码。避免重新编码整个内容的一种方法是剪掉您想要覆盖的部分,然后只重新编码该部分(请参阅文档中的-t duration开关和开关)-ss position

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

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

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

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

如果您不知道源文件的编码详细信息,您可以使用ffprobe SourceFileName或 my favorite获取它们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 "$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.
Run Code Online (Sandbox Code Playgroud)

完成后,您可以将所有部分连接在一起。

mkvmerge -o joined.mkv Part1 + Part2Reencoded + Part3

请注意,重新编码总是会导致一些质量损失,因此片段之间的连接可能会出现可见的缺陷。由于覆盖代码同时出现和消失而造成的干扰,这可能会或可能不会被注意到。

这可能会显着减少重新编码时间,具体取决于材料的长度,并且具有仅重新编码必须重新编码的内容的额外好处。

此处介绍了如何覆盖重新编码的片段,您可以调整接受的答案以匹配您的材料。