我试图比较转码后的 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
输出:
有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
输出:
框框是一樣的!
注意,我没有测试字幕流的效果。
我们可以通过添加参数来禁用字幕流-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 的关键帧。将时间戳更改为您需要的时间戳。