Communitygithub.com

视频工具路由器

自动将任何视频任务路由到最合适的工具——在运行之前就做出选择,避免使用成本高昂的DaVinci Resolve处理普通转码。

视频工具路由器 是什么?

该技能是一个智能决策引擎,用于在Windows笔记本上处理视频任务时自动选择最合适的工具。它基于详细的决策树,优先选择FFmpeg进行流复制(无像素变化)、转码/缩放/压缩等工作;使用auto-editor去除静音/死区;使用MoviePy进行程序化视频组装(文字/叠加/转场);仅在需要调色、HLG→SDR色调映射、降噪、稳定、超分辨率或多片段创意后期时,才使用DaVinci Resolve(Python API)。它还支持Blender(渲染3D标题/动态图形为帧后通过ffmpeg封装)和Descript MCP(AI/基于文本的编辑)。技能文档提供了精确的可复制命令,并包含对iPhone HEVC 10-bit HLG素材的特别防护——在导出为SDR H.264前必须进行色调映射,否则颜色会发灰/褪色。其背后的性能基准测试(VMAF分数、运行时间、文件大小)诚实呈现了单次运行结果,并明确指出普通转码在质量上没有区别——所有工具都能达到98.4-99.8的VMAF,因此不应因“质量更高”而选择某一工具。唯一需要DaVinci Resolve的场景是纠正性或创造性工作,此时其15倍于FFmpeg的时间成本才物有所值。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/kaustubhupadhyaya/editor-pack/tree/HEAD/skills/video-tool-router

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

视频工具路由器 是做什么的?

选择最便宜且能完全满足任务的工具。在这台机器上,转码质量受限于源文件,且无差异化(每个工具都能达到VMAF 98.4-99.8),因此永远不要因为“质量更高”而选择某个工具进行普通转码。仅当任务是纠正性或创造性时(调色、色调映射、降噪、稳定、超分、多片段后期),才选择DaVinci Resolve——这是唯一它作为正确工具的领域。它的运行时间是FFmpeg的~15倍,加上更重的设置,而其在调色/降噪/稳定/超分方面的优势是领域标准预期,并非下方基准测试所测量的(该基准只涵盖普通转码)。

决策树(匹配第一条规则)

  1. 无像素变化 — 剪切 / 裁剪 / 拼接 / 合并 / 重新封装 / 修改容器 / 提取音频 -> FFmpeg 流复制(-c copy)。约1.2秒,无损。最快的真正编辑——当像素无需改变时始终优先使用它。两个注意事项:(a) 剪切是关键帧精确的,而非帧精确——起始点会吸附到最近的关键帧;如果需要精确帧边界,则需重新编码。(b) 输出保持源编解码器(HEVC)——如果需要H.264交付物,此规则不适用;转到规则2。

  2. 转码 / 缩放 / 压缩(像素变化,无修正)-> FFmpeg libx264。 默认 -preset medium -crf 20。当速度重要时使用 veryfast/ultrafast——质量几乎没有差别(ultrafast仍然达到VMAF 99.66)。仅在存储/带宽受限时才使用 veryslow——ultrafast的40倍计算量换来了+0.12 VMAF(肉眼不可见),但文件大小几乎减半。即便如此,medium 已经实现了几乎所有的文件缩小效果(13.3 MB vs veryslow的12.6 MB),因此 veryslow 很少值得花费约6倍于medium的时间。

  3. 对说话人头部或教程音频进行静音/死区去除 -> auto-editor。 警告:在HEVC上非常慢(软件解码),并且仅当音频实际存在空白时才有用。对于连续音频素材(骑行/道路/音乐片段)是无用功——它会运行约30+分钟,却剪掉0秒。

  4. 程序化组装 — 通过Python脚本进行剪切+文字/叠加/转场 -> MoviePy 2.x。 预计速度与ffmpeg相当,加上Python开销。当组合逻辑在代码中比在长串 ffmpeg filter_complex 中更容易实现时使用。

  5. 调色 / HLG->SDR色调映射 / 降噪 / 稳定 / 超分(SuperScale)/ 多片段创意后期 -> 通过Python API使用DaVinci Resolve。唯一一个认为“在Resolve中处理”是正确的场景。约15倍于FFmpeg的时间,颜色管理(非透明直通)。其质量优势在此领域是标准,未在下方基准测试中体现。设置在其单独部分。

  6. 3D标题 / 动态图形 -> Blender 无界面 -> PNG帧 -> ffmpeg封装。 注意:Blender 5.1的 image_settings.file_format 枚举没有 FFMPEG/视频选项。不要尝试 image_settings.file_format='FFMPEG' 或脚本化的VSE视频导出——在该版本中已损坏。渲染图像帧,然后使用ffmpeg封装。

  7. AI / 基于文本的编辑(按转录本编辑、移除填充词、“让它更短”)-> Descript MCP。

精确命令(可直接复制粘贴)

1. 流复制(不重新编码)

# 裁剪:-t 是持续时间(无歧义)。裁剪是关键帧精确的,输出保持HEVC。
ffmpeg -ss 10 -i in.mov -t 15 -c copy out.mov
# 拼接(list.txt每行:file 'clip1.mov')
ffmpeg -f concat -safe 0 -i list.txt -c copy out.mov
# 重新封装容器 / 提取音频(不重新编码)
ffmpeg -i in.mov -c copy out.mp4
ffmpeg -i in.mov -vn -c:a copy out.m4a

(使用 -t <秒> 表示持续时间。避免在 -c copy 中使用 -ss ... -to ...:-to 的参考点与输入侧搜索存在歧义,可能产生错误长度。如需精确帧边界,去掉 -c copy 并重新编码——这会重新引入HEVC解码成本。)

2. 转码 HEVC -> H.264

# 默认平衡
ffmpeg -i in.mov -c:v libx264 -preset medium -crf 20 -c:a aac -b:a 192k out.mp4
# 速度优先(质量几乎没有差别)
ffmpeg -i in.mov -c:v libx264 -preset veryfast -crf 20 -c:a aac -b:a 192k out.mp4
# 转码时缩放到720p
ffmpeg -i in.mov -vf scale=-2:720 -c:v libx264 -preset medium -crf 20 -c:a aac out.mp4

3. 静音去除

auto-editor in.mp4 --edit audio:threshold=4% -o out.mp4
# 如果不确定音频是否有空白,先检查裁剪效果:
auto-editor in.mp4 --edit audio:threshold=4% --preview

4. MoviePy 2.x(重命名的API:subclipped / with_position / with_duration)

from moviepy import VideoFileClip, TextClip, CompositeVideoClip
clip = VideoFileClip("in.mov").subclipped(10, 25)
# 注意:MoviePy 2.x 的 TextClip 需要字体文件路径,而不是像 "Arial" 这样的字体族名称。
txt = (TextClip(text="Hello", font=r"C:\Windows\Fonts\arial.ttf", font_size=48, color="white")
       .with_duration(5).with_position("center"))
final = CompositeVideoClip([clip, txt])
final.write_videofile("out.mp4", codec="libx264", preset="medium",
                      ffmpeg_params=["-crf", "20"])

6. Blender 3D/动态图形 -> 帧 -> 封装

# 渲染动画为PNG帧(在5.1版本中不要设置 file_format='FFMPEG')
blender -b scene.blend -o "//frames/f_####" -F PNG -a
# 将帧封装为H.264(将 -framerate 与场景fps匹配)
ffmpeg -framerate 30 -i frames/f_%04d.png -c:v libx264 -preset medium -crf 20 -pix_fmt yuv420p out.mp4

HLG防护(在进行任何SDR H.264导出前务必执行)

部分iPhone素材是10位HLG。如果不进行色调映射,直接使用libx264输出到SDR会导致颜色发灰/褪色。

# 1. 检查传输特性
ffprobe -v error -select_streams v:0 -show_entries stream=color_transfer -of default=nk=1:nw=1 in.mov
  • 输出为 arib-std-b67 (HLG) 或 smpte2084 (PQ) -> 素材为HDR:在编码前/编码时进行色调映射。
  • 其他值(bt709, unknown)-> 已经是SDR:使用正常转码命令。
# 2. HLG/PQ -> SDR BT.709 色调映射 + H.264 单次完成(并将输出标记为bt709)
ffmpeg -i in.mov -vf \
"zscale=t=linear:npl=100,format=gbrpf32le,zscale=p=bt709,tonemap=tonemap=hable:desat=0,zscale=t=bt709:m=bt709:r=tv,format=yuv420p" \
-c:v libx264 -preset medium -crf 20 -color_primaries bt709 -color_trc bt709 -colorspace bt709 \
-c:a aac -b:a 192k out_sdr.mp4

npl=100 是用于线性化的标称峰值亮度;如果明亮高光被裁切则提高此值。 替代方案:让DaVinci Resolve的颜色管理进行Rec.2020-HLG -> Rec.709转换(如果你已经在调色,则路由到Resolve——它比ffmpeg的色调映射更精确)。

DaVinci Resolve Python API 设置(纠正/创意处理路径)

以下已包含注意事项:必须在Python 3.11上运行(py -3.11)——默认的3.14无法初始化 fusionscript.dll。RESOLVE_SCRIPT_API / RESOLVE_SCRIPT_LIB 是持久化的环境变量。Resolve必须正在运行(或使用 -nogui 启动)。使用一个临时的项目,显式设置格式+编解码器,然后渲染并轮询。

# 运行方式: py -3.11 resolve_render.py
import os, sys, time
sys.path.append(os.path.join(os.environ["RESOLVE_SCRIPT_API"], "Modules"))  # 必需的头部
import DaVinciResolveScript as dvr

resolve = dvr.scriptapp("Resolve")          # Resolve 必须已运行(或先启动 -nogui)
pm      = resolve.GetProjectManager()

proj_name = "temp_render_" + str(int(time.time()))   # 保持名称以便清理时可以匹配
proj    = pm.CreateProject(proj_name)
pool    = proj.GetMediaPool()
items   = resolve.GetMediaStorage().AddItemListToMediaPool([r"C:\in\clip.mov"])
tl      = pool.CreateTimelineFromClips("temp_timeline", items)   # 同时设为当前时间线

# ---- 在此应用证明使用Resolve合理的修正 ----
# (调色 / 项目颜色管理用于HLG->SDR / SuperScale超分 / 降噪 / 稳定)

proj.SetCurrentRenderFormatAndCodec("mp4", "H264")   # 显式格式+编解码器
proj.SetRenderSettings({
    "TargetDir": r"C:\out",
    "CustomName": "out",
    "SelectAllFrames": True,
})
pid = proj.AddRenderJob()
proj.StartRendering(pid)

while proj.IsRenderingInProgress():                   # 渲染+等待循环
    time.sleep(1)
print("render:", proj.GetRenderJobStatus(pid))

# 清理:在删除临时项目前先关闭当前项目
pm.CloseProject(proj)
pm.DeleteProject(proj_name)                           # 与我们生成的名称匹配

环境变量(供参考/重新持久化):

RESOLVE_SCRIPT_API = C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\Scripting
RESOLVE_SCRIPT_LIB = C:\Program Files\Blackmagic Design\DaVinci Resolve\fusionscript.dll

此机器上的实际性能

  • HEVC软件解码是真正的瓶颈。 对于这段iPhone素材,每个转码工具都很慢;veryslow 处理15秒的720p视频耗时约5分钟。每个工具都承担相同的解码开销——区别仅在于解码之后做什么。
  • 优先使用流复制(约1.2秒) 当不需要像素变化(且HEVC输出可接受)时。如果必须重新编码且速度重要,使用FFmpeg ultrafast/veryfast(约7秒)。
  • DaVinci Resolve比FFmpeg慢约15倍,且输出经过颜色管理(文件更大,输出有意与源不同)。仅在对调色/色调映射/降噪/稳定/超分/创意后期有价值时才值得使用。
  • auto-editor在长HEVC片段上可能耗时30+分钟,且可能什么也没去掉——仅在说话人头部/教程音频(确实有停顿)时运行它。

经验基础(相信路由,而非小数点后第二位)

任务:裁剪第10-25秒(15秒),然后转码HEVC->H.264 720p,串行运行以便公平CPU计时,与未裁剪的源文件比较VMAF。素材:iPhone HEVC 720p30(来自9个片段集合中的一个代表性片段)。数字为单次运行(n=1),无重复——大差距(路由决策)是可靠的;小差距(如MoviePy vs ffmpeg medium)在单次运行噪声范围内。

工具/设置时间大小VMAF结论
FFmpeg 流复制(-c copy,保持HEVC)1.2秒11.0 MB无损最快;仅用于裁剪/拼接/重新封装,无像素变化,输出保持HEVC
FFmpeg libx264 ultrafast crf207.4秒22.3 MB99.66最快的真正转码;质量已达到源限制上限
FFmpeg libx264 medium crf2047.9秒13.3 MB99.71默认平衡;获得几乎所有体积优势
FFmpeg libx264 veryslow crf20297秒(约5分钟)12.6 MB99.78VMAF+0.12(肉眼不可见),比medium小约0.7 MB——仅限体积受限时
MoviePy(x264 medium crf20)53.5秒13.4 MB99.44*约等于ffmpeg速度+Python开销(差距在噪声范围内);用于脚本化合成
Blender VSE视频导出失败——5.1版本无视频枚举;渲染帧+ffmpeg封装
DaVinci Resolve(API,默认H264)109秒48.2 MB98.40*慢约15倍,颜色管理;仅限纠正/创意用途
auto-editor(完整81秒片段)2021秒(约34分钟)——剪掉0秒:音频是连续的——用错了工具

* MoviePy和Resolve的VMAF是在匹配的无裁剪传递上重新测量的,因此与裁剪后的ffmpeg行并非完全可比较。Resolve的48.2 MB和98.40来自不同的传递(无裁剪的重新测量结果为15.24 MB):Resolve的分数低于未修改源文件,因为它是颜色管理的,而非透明直通,且其更大文件是质量优先的默认比特率产物。CQ/大小匹配的Resolve渲染会改变两者的比较——3.75倍的大小是默认设置依赖的,而非本质的。

路由建立于以下要点: (1) 普通转码的质量无差异化——不要追求它。(2) FFmpeg预设扫描是速度与比特率效率的权衡,而非质量权衡。(3) “最精致”仅对纠正/创意工作有意义;在那里DaVinci Resolve是正确的工具(领域标准预期,此处未测量)——而不是其他地方。

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

相关技能