关于 davinci-resolve
davinci-resolve 是围绕 DaVinci Resolve Scripting API 的自动化技能,适用于视频编辑和制作流程。它通过 Python 或 Lua 脚本管理项目、时间线、媒体、调色、渲染和 Fusion 合成。
主要功能
- 01管理项目与媒体池
- 02创建和编辑时间线
- 03自动应用 LUT 与调色
- 04配置并批量执行渲染
- 05脚本化 Fusion 合成
- 06导入和导出时间线
适用场景
- 01批量渲染项目中的时间线
- 02为视频轨道上的片段应用 LUT
- 03将 Resolve 纳入制作流程
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ terminalskills/ skills --skill davinci-resolve安装后在 Claude Code 中输入/davinci-resolve确认已加载。
附带文件_scores.json
详细介绍
DaVinci Resolve
概述
自动化 DaVinci Resolve——这款专业非线性编辑软件内置调色、Fusion 视觉特效和 Fairlight 音频功能。本技能介绍 Resolve 脚本 API(Python 和 Lua),可通过编程方式控制项目、时间线、媒体池、调色、渲染任务和 Fusion 合成。构建批处理工作流、自动执行重复编辑、管理渲染队列,并将 Resolve 集成到制作流程中。
说明
第 1 步:脚本 API 设置
Resolve 必须处于运行状态。从 Workspace > Scripts 菜单或控制台运行的脚本无需设置。从终端启动脚本时,请在 Resolve 的 Preferences > System > General > “External scripting using” 下启用该功能(Local),并设置以下变量(取值来自 Blackmagic 的 README):
# Linux (use /home/resolve instead of /opt/resolve on some ISO installs)
export RESOLVE_SCRIPT_API="/opt/resolve/Developer/Scripting"
export RESOLVE_SCRIPT_LIB="/opt/resolve/libs/Fusion/fusionscript.so"
export PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/"
# macOS: API=/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting
# LIB=/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so
# Windows: API=%PROGRAMDATA%\Blackmagic Design\DaVinci Resolve\Support\Developer\Scripting
# LIB=C:\Program Files\Blackmagic Design\DaVinci Resolve\fusionscript.dll
import DaVinciResolveScript as dvr
resolve = dvr.scriptapp("Resolve")
pm = resolve.GetProjectManager()
project = pm.GetCurrentProject()
mediaPool = project.GetMediaPool()
timeline = project.GetCurrentTimeline()
放置在 ~/.local/share/DaVinciResolve/Fusion/Scripts/Utility 中的用户脚本(Linux;macOS 和 Windows 对应的路径见 README)会显示在 Workspace > Scripts 下。Resolve 未运行或外部脚本功能关闭时,scriptapp 会返回 None。仅限 Studio 版的调用(部分 AI 功能)在免费版中会返回 False。
第 2 步:项目和媒体池
# Project management
pm = resolve.GetProjectManager()
pm.CreateProject("New Project") # returns None if the name already exists
project = pm.GetCurrentProject()
project.SetSetting("timelineResolutionWidth", "3840")
project.SetSetting("timelineResolutionHeight", "2160")
project.SetSetting("timelineFrameRate", "24")
# Media Pool — create bins and import
mediaPool = project.GetMediaPool()
rootFolder = mediaPool.GetRootFolder()
dailies_bin = mediaPool.AddSubFolder(rootFolder, "Dailies")
mediaPool.SetCurrentFolder(dailies_bin)
clips = mediaPool.ImportMedia([
"/mnt/footage/harbour/scene01_take01.mov",
"/mnt/footage/harbour/scene01_take02.mov",
])
# Set clip metadata (ImportMedia returns a list of MediaPoolItems)
clip = clips[0]
clip.SetClipProperty("Comments", "Best take")
clip.SetClipColor("Green")
第 3 步:时间线操作
# Create and populate timelines
timeline = mediaPool.CreateEmptyTimeline("Assembly Edit v1") # becomes the current timeline
mediaPool.AppendToTimeline([clips[0], clips[1]])
# or in one call: mediaPool.CreateTimelineFromClips("Assembly Edit v1", clips)
# Append subclip with in/out points
mediaPool.AppendToTimeline([{
"mediaPoolItem": clips[0],
"startFrame": 0,
"endFrame": 120, # First 5 seconds at 24fps
}])
# Inspect timeline
items = timeline.GetItemListInTrack("video", 1)
for item in items:
print(f" Frame {item.GetStart()}-{item.GetEnd()}: {item.GetName()}")
# Markers
timeline.AddMarker(1000, "Blue", "Review Point", "Check color here", 1, "reviewTag") # frameId, color, name, note, duration, customData
markers = timeline.GetMarkers()
第 4 步:自动化调色
SetLUT 属于节点图,而非片段;SetCDL 接受字符串。节点索引从 1 开始。
resolve.OpenPage("color")
items = timeline.GetItemListInTrack("video", 1)
for item in items:
graph = item.GetNodeGraph()
graph.SetLUT(1, "/mnt/luts/FilmLook.cube")
item.SetCDL({
"NodeIndex": "1",
"Slope": "1.1 1.0 0.95",
"Offset": "0.0 0.0 0.02",
"Power": "1.0 1.0 1.05",
"Saturation": "1.1",
})
# Copy the current grade of one clip onto the others
source = items[0]
source.CopyGrades(items[1:])
graph.ApplyGradeFromDRX(path, gradeMode) 会应用导出的静帧(gradeMode 为 0 表示不含关键帧)。不存在 ApplyGradeFromTimelineClip。
第 5 步:渲染队列和批量导出
先加载预设,再覆盖设置,最后加入队列。AddRenderJob() 会返回一个任务 ID 字符串。
project.LoadRenderPreset("YouTube - 2160p") # names come from project.GetRenderPresetList()
project.SetRenderSettings({
"SelectAllFrames": True,
"TargetDir": "/mnt/renders/harbour",
"CustomName": "harbour_v1",
"ExportVideo": True,
"ExportAudio": True,
})
job_id = project.AddRenderJob()
# Batch: one job per timeline
job_ids = []
for i in range(1, project.GetTimelineCount() + 1):
tl = project.GetTimelineByIndex(i)
project.SetCurrentTimeline(tl)
project.SetRenderSettings({"TargetDir": f"/mnt/renders/{tl.GetName()}", "CustomName": tl.GetName()})
job_ids.append(project.AddRenderJob())
project.StartRendering(job_ids) # or StartRendering() for the whole queue
import time
while project.IsRenderingInProgress():
for jid in job_ids:
st = project.GetRenderJobStatus(jid)
print(jid, st.get("JobStatus"), st.get("CompletionPercentage"))
time.sleep(5)
其他键:MarkIn/MarkOut、FormatWidth、FormatHeight、FrameRate、VideoQuality、AudioCodec、ColorSpaceTag。编解码器和容器:project.GetRenderFormats()、GetRenderCodecs(fmt)、SetCurrentRenderFormatAndCodec(fmt, codec)。project.RenderWithQuickExport(preset, {"TargetDir": ..., "CustomName": ...}) 会在当前时间线上运行 Quick Export 预设。
第 6 步:Fusion 脚本编写和集成
# Add Fusion text overlay to a clip
resolve.OpenPage("fusion")
item = timeline.GetItemListInTrack("video", 1)[0]
fusion_comp = item.GetFusionCompByIndex(1) if item.GetFusionCompCount() else item.AddFusionComp()
text_node = fusion_comp.AddTool("TextPlus", -32768, -32768)
text_node.StyledText = "Episode 1"
text_node.Font = "Arial"
text_node.Size = 0.08
text_node.Center = {"x": 0.5, "y": 0.9}
时间线导入/导出:
mediaPool.ImportTimelineFromFile("/mnt/edits/harbour_v3.edl", {
"timelineName": "Imported Edit",
"importSourceClips": True,
"sourceClipsPath": "/mnt/footage/harbour/",
})
timeline.Export("/mnt/edits/harbour_v3.fcpxml", resolve.EXPORT_FCPXML_1_10)
timeline.Export("/mnt/edits/harbour_v3.edl", resolve.EXPORT_EDL, resolve.EXPORT_CDL) # EDL and AAF need a subtype
# Types: EXPORT_AAF, EXPORT_DRT, EXPORT_EDL, EXPORT_FCP_7_XML, EXPORT_FCPXML_1_8/1_9/1_10, EXPORT_OTIO, EXPORT_ALE, EXPORT_TEXT_CSV
示例
示例 1:将数据库文件夹中的所有项目批量渲染为 ProRes 422 HQ
用户提示词:“编写一个 Python 脚本,遍历当前 Resolve 数据库文件夹中的每个项目,将每条时间线渲染为 ProRes 422 HQ,输出到 /mnt/renders/harbour-doc/assembly-v1/(以项目名称和时间线名称命名),并在完成后打印摘要。”
Agent 会编写一个脚本,调用 GetProjectListInCurrentFolder(),使用 LoadProject() 遍历每个项目,再通过 GetTimelineByIndex() 遍历时间线;应用 LoadRenderPreset(...)(或使用 GetRenderCodecs("mov") 返回的编解码器调用 SetCurrentRenderFormatAndCodec)和 SetRenderSettings,并根据项目名称和时间线名称设置目标目录;随后添加渲染任务,收集 AddRenderJob() 返回的 ID,调用 StartRendering(job_ids),在循环中轮询 IsRenderingInProgress(),并打印完成统计信息。
示例 2:将 LUT 和调色应用于第一条视频轨道上的所有片段
用户提示词:“我有一个位于 /home/editor/luts/FilmLook.cube 的 FilmLook.cube LUT。编写一个 Resolve 脚本,将此 LUT 应用到视频轨道 1 上每个片段的节点 1,然后将饱和度调至 1.15,并添加轻微的暖色偏移。”
Agent 会创建一个 Python 脚本,通过 resolve.OpenPage("color") 切换到 Color 页面,获取视频轨道 1 上的所有项目,并通过 item.GetNodeGraph().SetLUT(1, "/home/editor/luts/FilmLook.cube") 应用 LUT;然后对每个片段调用 item.SetCDL(),传入 "Saturation": "1.15" 和 "Offset": "0.01 0.005 0.0"(字符串值)。
指南
- DaVinci Resolve 必须正在运行;脚本会连接到活动实例,无法以无头模式启动 Resolve。对于从应用外部启动的脚本,必须在 Preferences 中将外部脚本设置为 Local,并设置
RESOLVE_SCRIPT_API/RESOLVE_SCRIPT_LIB(第 1 步)。请将“Network”视为安全风险 - 进行更改后调用
pm.SaveProject()(ProjectManager 的方法),以免 Resolve 或脚本崩溃时丢失工作成果 - 设置值均为字符串:
project.SetSetting("timelineFrameRate", "24"),CDL 值则为空格分隔的字符串。检查每个返回的 Bool;大多数调用会返回False或None,而不是抛出异常 - 使用轮询循环和
time.sleep()调用project.GetRenderJobStatus()监控渲染,而不是无限期阻塞 - Fusion 脚本使用归一化值(0.0 到 1.0)表示位置,而不是像素值,因此
Center = {"x": 0.5, "y": 0.9}表示水平居中且靠近底部