我的新佳能 Vixia HF G30 摄像机有一个选项,可以直接编码为 35 Mbit/秒的 1080p60 Mp4,效果很好。我主要用它来录制我女儿的高中篮球比赛。
我需要从相机文件中突出显示,并希望尽可能保留质量和清晰度。以下是我根据对 FFmpeg 的有限理解开发的工作流程:
步骤 1.) 将摄像机制作的 mp4 剪辑合并为一个代表一场比赛的 mp4 文件。这是我从 Windows 命令提示符(DOS 框)中用于此步骤的代表性命令:
ffmpeg -f concat -i "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\gameclipsfromcamera.txt" -c copy "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\joined_fullgame.mp4"
这会将游戏片段合并到无需转码的游戏视频中(我相信),所以这很好(它很快并且没有引入额外的压缩伪影)。
步骤 2.) 从游戏视频中剪切精彩片段。这是我在此步骤中使用的代表性命令:
ffmpeg -ss 00:00:06.00 -i "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\joined_fullgame.mp4" -acodec copy -vcodec copy -t 00:00:20.00 "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1.mp4"
这将产生从游戏视频第 6 秒开始的以下 20 秒剪辑:
突出显示示例(85 MB)
步骤 3.) 我需要在每个精彩片段的开头暂停 2 秒,并在其中添加文字覆盖来标识我的女儿。为了实现这一点,我从片段的第一帧制作了一个位图图像:
ffmpeg -i "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1.mp4" -ss 00:00:00.00 -f image2 -vframes 1 -deinterlace "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1freezeframe.bmp"
这里是结果。
然后使用 CRF 0 循环播放视频 2 秒,以免引入其他伪影:
ffmpeg -loop 1 -r 59.97 -i "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1freezeframe.bmp" -c:v libx264 -crf 0 -pix_fmt yuv420p -t 2 "\\Excelhero\f\Canon\2013.09.21_san_francisco_game2\1freezeframe.mp4"
然后添加标识 Fiona 的文本覆盖标签:
ffmpeg -i "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1freezeframe.mp4" -vf drawtext="fontfile=/Windows/Fonts/Corbelb.ttf:text='Fiona':fontsize=40:fontcolor=yellow:x=1321:y=417" -b:v 35M -minrate 35M -maxrate 35M -bufsize 35M -profile:v high -level:v 4.2 -refs 2 -pix_fmt yuv420p -bf 0 -r 59.97 "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1freezeframeannotated.mp4"
生成此文件:[ehasamples.excelhero.com/video/1freezeframeannotated.mp4]
(超级用户只允许我添加 2 个实时链接)
现在我们向剪辑中添加一个静音声音流:
ffmpeg -f lavfi -i aevalsrc=0:0:sample_rate=48000 -i "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1freezeframeannotated.mp4" -shortest -c:v copy -c:a aac -b:a 255k -strict -2 "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1freezeframeannotatedwithsilentsound.mp4"
结果如下:[ ehasamples.excelhero.com/video/1freezeframeannotatedwithsilentsound.mp4 ]
(超级用户只允许我添加 2 个实时链接)
上面是一个时长 2 秒的视频,其中我的女儿被标记为假死状态,声音流为空白。
步骤 4.)最后一步是将 2 秒的视频与摄像机的完整剪辑合并。我可以通过过滤器轻松地重新渲染,从这两个输入文件中生成一个输出文件,如下所示:
ffmpeg -i "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1freezeframeannotatedwithsilentsound.mp4" -i "\\Excelhero\f\Canon\2013.09.21_san_francisco_game2\1.mp4" -filter_complex "[0:0] [0:1] [1:0] [1:1] concat=n=2:v=1:a=1 [v] [a]" -map "[v]" -map "[a]" -c:v libx264 -r 59.97 "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1done.mp4"
但这不是一个很好的解决方案。它很慢,因为摄像机的原始镜头在引入新的压缩伪影的情况下被重新渲染。我可以选择添加“-crf 0”以获得无损重新渲染,但这会使剪辑的大小膨胀超过 1000%,在这种情况下,我们的示例剪辑的大小超过 1 GB。所以这不是一个实用的解决方案。
所以我想使用 concat 解复用器而不是过滤器:
ffmpeg -f concat -i "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\clipfiles.txt" -c copy "\\mylancomputer\f\Canon\2013.09.21_san_francisco_game2\1doneBAD.mp4"
采用这种方法,操作很快,因为不需要重新编码。但是,生成的文件无法正常播放。如下所示:
[ehasamples.excelhero.com/video/1doneBAD.mp4]
(超级用户只允许我添加 2 个实时链接)
2 秒图像显示了整个 22 秒。虽然视频无法正常播放,但声音似乎播放正常。所以我的猜测是这两个文件(来自相机的剪辑和 2 秒标签剪辑)在相对编码上相差太大。我尝试使用 MediaInfo 和 FFProbe 使它们的编码尽可能接近相同,上述一系列命令是我最好的,但显然还不够。
所以我的问题很简单:FFmpeg 是否能够让我的标记剪辑足够像来自相机的编码镜头,以便 Concat 解复用器成功?如果可以,怎么做?
整个工作流程由批处理文件驱动,对我来说非常简单,所以我喜欢它,并希望使用这种方法让我能够快速编辑游戏中的精彩片段。
相反,使用 FFmpeg 是否有更好的(更快、无需转码)工作流程?
非常感谢您的帮助。
答案1
如果您的磁盘速度很快,您可能需要使用速度更快、占用更多临时空间的无损编解码器,例如 ffvhuff 之类的。否则,请使用-preset ultrafast
。-crf 0
(与 相同-qp 0
,启用无损模式。)
顺便说一句, x264 的slow
压缩效果只比无损模式好一点点superfast
。也许如果你的动画包含一些比 1 帧前更多的位相同块,那么多个参考帧可能会有所帮助,那么更高的设置会更有效。我发现,对于 1h:22m NTSC DV 去隔行(720x480p60),分别为 27.9GB(superfast
)和 27.0GB(slow
),或 ffvhuff 为 55.0GB,或 ffv1 为 37.6GB(默认设置,使用更慢的 ffv1 压缩/解压缩设置时会更小)全部为 yuv420)。以该比特率进行 CABAC 编码/解码需要大量 CPU;我应该使用超快而不是极快,或者只是-x264-params cabac=0
。
TL;DR:使用 libx264-preset ultrafast
或 ffvhuff 作为中间文件。
当文件大小并不重要时,ffv1 或带有 CABAC 的 h.264 不值得花费 CPU 时间进行编码/解码。而且 huffyuv 不执行 yuv 4:2:0,您需要 ffvhuff 才能执行此操作。Lagarith 是 GPL,但仅用于 ffmpeg 中的解码器,并且编码器只移植到 Windows。(速度与压缩的权衡可能与 x264 相比也不太令人印象深刻,除非是无噪声源(如动画),其中熵编码器之前的预测/运行长度内容会做得很好。)
另外,您肯定可以-vf drawtext
在 bmp -> 2 秒视频步骤中使用。为什么您要为此使用硬 CBR(比特率 35M,最大比特率 35M)?为什么不也为该步骤使用无损?
通常对 x264 的特定 -profile 没用。它会根据输入到比特流中的内容,将输出中的配置文件标志设置为最低。(即,如果 ,它会将配置文件设置为高8x8dct=1
,并根据分辨率、比特率和参考帧确定级别。)编辑:-profile
还会强制 x264 降低参考帧数或其他设置,以保持给定配置文件的限制。不过,除非针对某些硬件解码器,否则很少需要使用它。
在有损最终编码中有用的是使用-preset slower
或让 x264 使用更多 CPU 时间,但在相同比特率下获得更高的质量。这几乎取代了必须调整所有旋钮,例如参考帧、网格、自适应 b 帧、运动搜索等。
为了尝试回答实际问题,对于能够连接不同的 h.264 流(来自相机的编码器和 BMP -> x264)来说,重要的事情应该只是分辨率、色彩空间(yuv420 与 yuv444 或其他),以及可能的一些 h.264 流参数,例如是否隔行扫描。
如果您打算保留整个 35Mbit/s 的速度,并且不想将其压缩为可以通过互联网发送的合理文件大小,那么您需要匹配相机硬件编码器正在执行的操作。或者,您可以通过 x264 运行整个过程,这将花费一些时间,但-preset veryslow
您可能可以达到 10Mbit/s,甚至 5Mbit/s,而几乎不会出现明显的质量损失。试试看-crf 18
,这通常是相当透明的。(是的,如果您暂停并在 x264 和源帧之间来回切换,您仍然可以轻松注意到差异)。
如果应该可以在一次 ffmpeg 调用中完成整个过程。最终以 concat 过滤器结尾的过滤器图可以具有生成 2 秒重复静止图像 + 静音的链,这些链与仅输入文件->输出的链交错。
(或者如果你真的不想对相机输出进行 xcode 处理,并且可以弄清楚你的相机输出和 x264 之间的不同:每个静止图像调用一次 ffmpeg,然后进行最后一次连接。)
手机和相机中的硬件编码器通常非常糟糕。它们看起来不错的唯一方法是通过投入大量比特率来解决问题。x264 通常可以做得更好,尤其是使用 -preset slow、slower 或 veryslow。显然会有另一代损失,但您通常可以将视频比特率降低到 2Mbit/s,以获得细节非常清晰的 1080p@24fps 好莱坞电影。嘈杂的手持源始终具有高运动,将占用更多比特,但-crf 18
质量保持不变,因此我建议将其作为足以在良好的监视器上近距离观看的东西。不过,我可能仍会保存原始源,因为存储只会变得更便宜,并且您永远无法从 x264 输出中恢复原始质量。不过,我还是会保留它们。如果您将此文件提供给任何人,或通过互联网复制它,x264-preset slow
会做得很好。即使是默认值也-preset medium
很好。如果您未设置目标比特率或质量,则默认为“我认为” -crf 23
。
我不会过多回答如何让 x264 制作出可以与相机的非 xcoded 比特流连接的输出,因为这不是我必须做的事情,而且我也不感兴趣去了解,抱歉。主要回答是为了让任何想遵循你的出发点的人不会被引导到 -crf 0 或类似的愚蠢的东西。:P