我有一个使用 VMAF 库构建的
ffmpeg
版本。我可以使用它来计算失真视频相对于参考视频的 VMAF 分数,使用如下命令:
ffmpeg -i distorted.mp4 -i original.mp4 -filter_complex "[0:v]scale=640:480:flags=bicubic[main];[main][1:v]libvmaf=model_path=model/vmaf_v0.6.1.json:log_path=log.json" -f null -
现在,我记得有一种方法可以在执行常规 ffmpeg 编码时获得 VMAF 分数。我怎样才能同时做到这一点?
我想对这样的视频进行编码,同时计算输出文件的 VMAF:
ffmpeg -i original.mp4 -crf 27 -s 640x480 out.mp4
[编辑]
好吧,把我之前说的话划掉...
ffmpeg -i original.mp4 -crf 27 -s 640x480 -f tee "out.mp4 | [f=mp4]-" \
| ffmpeg -i - -i original.mp4 -filter_complex ...
(将它们分成2行并删除Windows的
\
这是在我的 Windows PC 上运行的内容(感谢 @Rotem 的帮助)
ffmpeg -i in.mp4 -vcodec libx264 -crf 27 -f nut pipe:
|
ffmpeg -i in.mp4 -f nut -i pipe:
-filter_complex "[0:v][1:v]libvmaf=log_fmt=json:log_path=log.json,nullsink"
-map 1 -c copy out.mp4
@Rotem 和我错过的主要问题是我们需要终止
libvmaf
的输出。此外,h264
原始格式不携带标头信息,使用`nut可以缓解这个问题。
有一些注意事项:
使用@Rotem在下面的评论中建议的
testsrc
示例进行测试不会产生任何libvmaf
日志,至少据我所知,但在debug
模式下,您可以看到过滤器正在初始化.
您可能会在日志中看到
[nut @ 0000026b123afb80] Thread message queue blocking; consider raising the thread_queue_size option (current value: 8)
消息。这仅意味着帧的传输速度比第二个 ffmpeg 的处理速度更快。 FFmpeg 确实会在两端阻塞,因此不应丢失任何信息。
为了完整披露,我在 GitHub 上发布了我的 Python 测试脚本。它只运行 shell 命令,所以即使你不会 Python,也应该很容易理解。
我就是这样做的:
ffmpeg -i example_videos/original.mp4 -c:a copy -c:s copy -c:v <encoding arguments> -f rawvideo - -f matroska distorted.mkv | ffmpeg -r 25/1 -i pipe:0 -r 25/1 -i example_videos/original.mp4 -lavfi "[0:v]setpts=PTS-STARTPTS[dist];[1:v]setpts=PTS-STARTPTS[ref];[dist][ref]libvmaf=log_fmt=json:log_path='vmaf_scores.json'" -f null -
将
<encoding arguments>
替换为您要使用的编码参数,例如-c:v libx264 -crf 27
您可以随意命名输出文件,
distorted.mkv
只是一个示例文件名。
我指定
-f matroska
和 .mkv
作为输出文件的文件扩展名,因为 Matroska 是一个灵活的容器,支持各种音频和视频编解码器,但如果您要编码为 MPEG-4 容器支持的格式,例如H.264(如使用 libx264
时的情况)或 H.265,您可以将 -f matroska distorted.mkv
替换为 -f mp4 distorted.mp4