如何从原始视频中提取相同的帧并从原始视频中剪辑

如何从原始视频中提取相同的帧并从原始视频中剪辑

我试图比较转码后的 x265 视频与原始高比特率 x264 的质量。为此,我将一帧作为 png 并缩放以查找像素差异https://gitlab.gnome.org/YaLTeR/identity

原始视频

$ ffprobe Original.mkv 2>&1 | egrep 'Duration|Stream'
  Duration: 00:45:29.08, start: 0.000000, bitrate: 7156 kb/s
  Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1920x1080 [SAR 1:1 DAR 16:9], 23.98 fps, 23.98 tbr, 1k tbn (default)
  Stream #0:1(eng): Audio: eac3, 48000 Hz, 5.1(side), fltp, 640 kb/s (default)
  Stream #0:2(eng): Subtitle: subrip

我正在将视频的一部分转换为 x265

$ ffmpeg -ss 00:40:00 -i Original.mkv -t 00:10:00 -c:v libx265 -crf 20 -c:a copy Original-x265.mkv

现在我试图从两个视频中获取相同的帧

ffmpeg -ss 00:40:09 -i Original.mkv -frames:v 1 -q 1 original.png
ffmpeg -ss 00:00:09 -i Original-x265.mkv -frames:v 1 -q 1 original-x265.png

但两幅图像不同。如何从两个视频中获取相同的图像来比较质量?

答案1

使用-c:a copy会阻止精确剪切。
-c:a copy用替换-c:a aac,或通过添加参数来忽略音频流-an

-c:a copy强制 FFmpeg 复制音频流而不重新编码。
使用“流复制”时,FFmpeg 无法在中间分割音频数据包,也无法在准确的时间开始输入。

每个音频数据包每个音频通道有 1024 个样本。
在每秒 48000 个样本的情况下,音频数据包持续时间为 1024/48000 = 21.3 毫秒。
我们的搜索误差约为 21 毫秒。
视频帧的持续时间约为 1/25 = 40 毫秒。
使用时,-c:a copy视频的误差至少是帧周期的一半(误差约为 1 帧)。
出于某种原因,我不知道误差大于 1 帧。


使用带有帧计数器的合成视频重现该问题:

构建合成视频和音频(用作测试输入):

ffmpeg -y -r 23.976 -f lavfi -i testsrc=size=192x108:rate=1:duration=65432 -f lavfi -i sine=frequency=500 -vf "setpts=N/23.976/TB" -c:v libx264 -g 117 -acodec aac -ar 48000 -pix_fmt yuv420p -t 2729 Original.mkv

使用以下方法提取帧-c:a copy

ffmpeg -y -ss 00:40:00 -i Original.mkv -t 00:10:00 -c:v libx265 -crf 20 -c:a copy Original-x265.mkv

ffmpeg -y -ss 00:40:09 -i Original.mkv -frames:v 1 -update 1 original.png
ffmpeg -y -ss 00:00:09 -i Original-x265.mkv -frames:v 1 -update 1 original-x265.png

输出:

original.png
在此处输入图片描述

original-x265.png
在此处输入图片描述

有4帧的差异!


使用以下方法提取帧-c:a aac(重新编码音频):

ffmpeg -y -ss 00:40:00 -i Original.mkv -t 00:10:00 -c:v libx265 -crf 20 -c:a aac Original-x265.mkv

ffmpeg -y -ss 00:40:09 -i Original.mkv -frames:v 1 -update 1 original.png
ffmpeg -y -ss 00:00:09 -i Original-x265.mkv -frames:v 1 -update 1 original-x265.png

输出:

original.png
在此处输入图片描述

original-x265.png
在此处输入图片描述

框框是一樣的!


注意,我没有测试字幕流的效果。
我们可以通过添加参数来禁用字幕流-sn

答案2

尝试这个:

ffmpeg -hide_banner -ss 00:00:00 -i input.mkv -t 1 -vf "select='eq(pict_type,I)'" -vsync vfr out-%02d.png

这将仅提取从 00:00:00 到 00:00:01 的关键帧。将时间戳更改为您需要的时间戳。

相关内容