mcpField
D
davinci-resolve

davinci-resolve

github.com/terminalskills创意与媒体183172 次安装3 天前更新
代码仓库

关于 davinci-resolve

davinci-resolve 是围绕 DaVinci Resolve Scripting API 的自动化技能,适用于视频编辑和制作流程。它通过 Python 或 Lua 脚本管理项目、时间线、媒体、调色、渲染和 Fusion 合成。

主要功能

  1. 01管理项目与媒体池
  2. 02创建和编辑时间线
  3. 03自动应用 LUT 与调色
  4. 04配置并批量执行渲染
  5. 05脚本化 Fusion 合成
  6. 06导入和导出时间线

适用场景

  1. 01批量渲染项目中的时间线
  2. 02为视频轨道上的片段应用 LUT
  3. 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} 表示水平居中且靠近底部

评论

支持 Markdown