- 人工智能
- AI 应用
- 语音
- 音频
- 本地部署
- 桌面应用
【免费下载链接】auto-subs
On-device subtitle generation that connects directly to DaVinci Resolve, Premiere, and After Effects.
MacroOperator是 DaVinci Resolve(Fusion 页面)中把一组工具封装成可复用节点的核心机制,其载体是 Lua 风格表格的.setting文件。本篇以 AutoSubs 仓库随附的 Fusion 宏开发参考文档(macro-authoring.md)为骨架,结合仓库内真实落地的字幕宏 autosubs-macro.setting,系统讲解.setting文件的双控制层模型、五个高频踩坑点、CustomData 逻辑嵌入模式以及新增对外控件的完整清单。读完你可以独立编写、调试并维护自己的 Fusion 宏,也能快速看懂 AutoSubs 字幕宏的内部结构。
一、先建立认知:.setting文件到底是什么
.setting文件本质是一种Lua 风格的表格(table)序列化格式,同时允许在[[ ... ]]脚本块内嵌入真正的 Lua 代码。它描述的是一个完整的 Fusion 工具树:外层是一个MacroOperator,内部可以包含若干 Tool(如 Text+、关键帧拉伸器、BezierSpline 等)以及宏自身的控制层。
在 AutoSubs 仓库中,MacroOperator的落地实例位于 autosubs-macro.setting,其顶层结构如下:
Tools = ordered() { AutoSubs = MacroOperator { CustomData = { ... }, -- 长括号 Lua 字符串:动画、高亮、换行等全部逻辑 Tools = ordered() { Template = MacroOperator/工具, -- 内部承载 UserControls 的源工具 Follower1 = StyledTextFollower, -- 字幕文本跟随器 AnimationKeyframeStretcher = KeyStretcherMod, -- 动画关键帧时间映射 OrderKeyframeStretcher = KeyStretcherMod, -- 出场顺序时间映射 }, UserControls = ordered() { ... }, -- 内部工具的控件定义层 Inputs = ordered() { InstanceInput ... }, -- 宏 Inspector 的发布层 } }其中CustomData里保存的GetInputValues、SetAnimations、AnimationRegistry等都是以长括号字符串存储、运行时用loadstring执行的 Lua 函数(见.setting文件 53–83 行与 353–430 行),这正是下文第五节要讲的"数据化逻辑"模式。
宏的构建范围并不限于某一款应用,任何需要
MacroOperator的场景(转场、生成器、标题、特效模板)都适用同一套规则;若涉及更底层的 Resolve/Fusion 脚本 API,可查阅仓库内随附的 fusion-manual/00-index.md 与 resolve-api.txt。
二、开发工具:让 .setting 获得语法高亮
.setting文件在多数编辑器里几乎得不到任何高亮,因为它是一种"表格 + 内嵌 Lua"的混合格式。Fusion Setting Highlighter这个 VS Code 扩展专门解决了这一问题:它为 Fusion 对象(宏、工具、修饰符)提供完整的语法高亮,并在[[ ]]脚本块内提供完整的 Lua 高亮支持,能显著降低手写和排查.setting的难度。
安装方式为各平台的一键安装脚本(脚本地址由扩展作者发布在其项目主页上):
# macOS / Linux:通过管道执行安装脚本 curl -fsSL <fusion-setting-highlighter-install-script-url> | sh# Windows(PowerShell) irm <fusion-setting-highlighter-install-script-url> | iex安装完成后,在 VS Code 中打开任意.setting文件即可看到结构化高亮:外层表格字段、内嵌 Lua、字符串与注释一目了然。AutoSubs 仓库的.agentsskill 也在 SKILL.md 中明确推荐了这一工具链,用于"构建或编辑 Fusion 宏(.setting)"的开发流程。
三、核心模型:两个必须保持同步的控制层
一个MacroOperator的.setting里存在两个独立的控制层,它们必须保持同步,这是理解整个宏体系的第一性原理:
| 层 | 位置 | 职责 |
|---|---|---|
| 第一层 | Tools.<Tool>.UserControls | 定义在内部工具上的真实控件(类型、默认值、回调、取值范围) |
| 第二层 | MacroOperator.Inputs = { InstanceInput ... } | 真正暴露在宏 Inspector里的控件条目,负责 UI 呈现 |
第一层是"源定义",第二层是"发布映射"。两者通过InstanceInput的SourceOp/Source字段建立指向关系。在 autosubs-macro.setting 中,这一模型体现得非常典型:内部Template工具的UserControls块(约 1083 行起)定义了Text、FadeEnabled、PopInEnabled、SlideUpEnabled、AnimationLength、AnimationMode等源控件;而宏的Inputs块(约 1929 行起)则用一排InstanceInput将这些控件逐一发布到 Inspector,并分配Page(页面分组):
-- 第一层:内部工具上的源控件定义(UserControls) FadeEnabled = { LINKS_Name = "Fade", LINKID_DataType = "Number", INPID_InputControl = "CheckboxControl", INP_Integer = true, INP_Default = 1, -- 默认开启淡入淡出 INP_Passive = true, INP_External = false, CBC_TriState = false, }, -- 第二层:宏 Inspector 的发布映射(MacroOperator.Inputs) FadeEnabled = InstanceInput { SourceOp = "Template", -- 指向内部源工具 Source = "FadeEnabled", -- 指向该工具上的源控件 Page = "Text", -- 在 Inspector 中归入 Text 页 Default = 1, },InstanceInput还可以在发布层覆盖默认值与取值范围,例如TextSize在发布时指定Default = 0.08(Text+ 的默认字号)、WrapBoxWidth给出MinAllowed = 0.05、MaxAllowed = 2的滑块范围——这些发布层属性只影响 Inspector 呈现,不改变源控件定义。注意:实例名(InstanceInput 的键名)与源控件名在大多数场景下保持 1:1 对应,但不强制,一个源控件也可以被多个InstanceInput指向。
四、五个高频踩坑点(金科玉律)
参考文档用五个条目总结了实战中几乎必然遇到的坑,每一条都值得在动手前默读一遍。
4.1 只定义 UserControl 不会让它出现在宏 Inspector 中
控件在UserControls里定义之后,可以存在但保持"隐形"——必须同时把它发布到MacroOperator.Inputs,才会出现在宏的 Inspector 里。文档给出了标准两步写法:
-- 内部工具上(UserControls): MyColorRed = { INPID_InputControl = "ColorControl", IC_ControlID = 0, IC_ControlGroup = 21, } -- 单独地,在 MacroOperator.Inputs 中发布: MyPublishedColorRed = InstanceInput { SourceOp = "Template", Source = "MyColorRed", Page = "Style", }从源码结构看,AutoSubs 的Text控件正是这一模式的完整范例:它先在UserControls里定义了带INPS_ExecuteOnChange回调和TEC_Lines = 5、TEC_Wrap = false等属性的TextEditControl,再在Inputs层以同名InstanceInput发布并归入Text页(见.setting1097–1123 行与 1939–1943 行)。
4.2 隐藏控件:删除 InstanceInput,而非依赖IC_Visible = false
在宏 UI 中,InstanceInput上的IC_Visible = false并不可靠,很可能被忽略。可靠的做法是:需要隐藏某个控件时,直接把它的InstanceInput从MacroOperator.Inputs中整体删除,它就会从 Inspector 消失。同理,Page字段也可用于把不常用的控件归入折叠/隐藏页面来管理 Inspector 的整洁度(AutoSubs 的Controls、Settings页即用CT_Visible = false在内部按需显隐)。
4.3 不要复用原生通道名作为自定义控件 ID
自定义 ID 如果撞上内置通道名——典型如 TextPlus 自带的Red1/Green1/Blue1——会与内置通道产生冲突,行为不可靠。正确的做法是使用唯一 ID(如FillRed/FillGreen/FillBlue),并在INPS_ExecuteOnChange回调中把自定义控件的值映射回真实通道:
local r = tool:GetInput("FillRed") local g = tool:GetInput("FillGreen") local b = tool:GetInput("FillBlue") tool:SetInput("Red1", r) tool:SetInput("Green1", g) tool:SetInput("Blue1", b)AutoSubs 的高亮/描边/阴影颜色控件(HighlightColorRed、OutlineColorRed、ShadowColorRed等)正是采用这种唯一命名策略,并通过UpdateHighlight、UpdateOutlineColor、UpdateShadowColor等按钮型控件触发映射逻辑(见.setting2069 行起与 2130 行起)。
4.4 行为脚本放在 UserControl 上,而不是 InstanceInput 上
InstanceInput只负责"发布 UI",行为逻辑(INPS_ExecuteOnChange、BTNCS_Execute等回调)必须归属于内部工具上的源控件。AutoSubs 的Text控件在UserControls层写了INPS_ExecuteOnChange(把文本同步到StyledText与CharacterLevelStyling1,并触发UpdateTextContent逻辑),按钮型控件ModifyWordTiming的BTNCS_Execute则实现了"进入标记编辑模式 / 保存并应用"的双态切换(见.setting1107–1122 行与 1162–1175 行)——这些都是回调挂在源控件上的典型例证。
4.5 修改后旧实例可能不刷新 Inspector 布局
修改了已发布的输入(Inputs)或UserControls之后,宏实例的 Inspector 布局是按实例缓存的:旧实例可能仍然显示旧布局。处理办法是先重载合成(comp),若仍显示陈旧布局,则删除旧节点、重新拖入一个全新的宏节点实例。这一经验在 SKILL.md 的 Tips 中也再次强调:"After changing a macro's published controls, reload the comp or drop a fresh node instance — the Inspector layout is cached per instance."
五、在 CustomData 中嵌入逻辑:loadstring + 注册表模式
宏的行为逻辑可以以Lua 长括号字符串([[ ... ]])的形式存放在宏的CustomData字段中,运行时通过loadstring执行。一个通用且可复用的设计是:命名操作注册表 + 循环编排器——新行为作为"数据"追加进注册表,编排代码无需任何改动。
AutoSubs 把这个模式发挥到了极致,其完整的"数据驱动动画"架构记录在 animation-system.md,并在.setting文件 349–430 行落地:
Animations表:每个动画一对命名函数(ApplyX/ResetX),统一接收ctx上下文(含follower、animStretcher、animSpline、animInEnd、animOutStart、mode、level);AnimationRegistry注册表:有序描述符列表,如{ controlKey = "PopInEnabled", usesFade = true, applyKey = "ApplyPopIn", resetKey = "ResetPopIn" },只声明"哪个开关启用哪个动画",不含任何硬编码分支;SetAnimations编排器:每次调用先重置所有已注册动画,再判断启用了哪些动画与是否需要淡入基底,最后逐个应用。新增动画时编排器零改动——这正是注册表模式的要义。
-- SetAnimations(节选,出自 autosubs-macro.setting) return function(comp, tool) local anims = tool:GetData("Animations") local registry = loadstring(tool:GetData("AnimationRegistry"))() -- ...读取 AnimationLength / AnimationMode / AnimationLevel 等输入... -- 先重置全部已注册动画 for _, anim in ipairs(registry) do loadstring(anims[anim.resetKey])()(ctx) end -- 再逐个应用已启用的动画 for _, anim in ipairs(enabled) do loadstring(anims[anim.applyKey])()(ctx) end -- 最后统一设置关键帧拉伸器的时间窗口 animStretcher:SetInput("StretchStart", ctx.animInEnd) animStretcher:SetInput("StretchEnd", ctx.animOutStart) end值得注意的两点实现细节(均可在.setting372–428 行核对):
- 归一化时间坐标:动画关键帧统一工作在 0–100 的归一化区间,由
KeyStretcherMod(AnimationKeyframeStretcher)映射到真实时间轴帧;帧数由math.round(animationLength * fps)计算,其中fps取自comp:GetPrefs("Comp.FrameFormat.Rate")(缺省 30),默认时长滑杆为0.2秒; - 出场顺序 spline:
OrderKeyframeStretcher用阶跃关键帧(Flags = { StepIn = true })在animOutStart - 1处设为高延迟值(6,即"Manual Curve"),在animOutStart处归零(Automatic,整行同步动画),实现"整行一起出场而非逐字出场"。
配合CustomData中的GetInputValues/SetInputValues(.setting53–83 行)与InputKeys白名单(18–52 行),预设(preset)系统可以安全地批量读写宏的全部对外状态——SetInputValues只写入白名单内的键,并在写入后依次触发SetAnimations、UpdateHighlight、UpdateWrap,保证控件变更即时反映到画面。
六、新增一个对外控件的完整清单
无论是给 AutoSubs 宏加一个新开关,还是给自己写的宏加参数,都遵循下面四步(文档原文 + 仓库实践):
- 在内部工具上添加
UserControl定义:给出控件类型(INPID_InputControl)、默认值(INP_Default)、数据类型(LINKID_DataType)、取值范围(INP_MinAllowed/INP_MaxAllowed)、回调(INPS_ExecuteOnChange/BTNCS_Execute)等完整属性; - 在
MacroOperator.Inputs中将其发布为InstanceInput,并用Page指定归属页面;如需要,可在发布层覆盖Default与取值范围; - 如果预设会捕获该控件的值,把控件键注册到预设清单所在的位置——在 AutoSubs 中即把键名追加到
CustomData.InputKeys(见.setting18–52 行),这样GetInputValues/SetInputValues才能读写它; - 重载合成,或使用全新的宏节点实例,确认 Inspector 中出现了新控件。
AutoSubs 的 animation-system.md 还补充了第 3、4 步的实操提示:步骤 1–2 是纯文本编辑(直接改autosubs-macro.setting),步骤 3–4 需要在 Fusion 页面打开宏完成。新增动画开关时需同时改动四处:Animations表加ApplyX/ResetX字符串、AnimationRegistry加描述符、InputKeys加键名、UserControls加复选框控件(可参照SlideUpEnabled的模板,INPID_InputControl = "CheckboxControl"、INP_Integer = true)。
七、AutoSubs 实战落地:从参考文档到生产宏
参考文档的规则在 AutoSubs 里全部得到了生产级验证,可以对照学习:
- 双层控制与页面编排:
Inputs层按Text/Style/Controls/Settings多个页面组织几十个InstanceInput(如Text、Font、TextSize、WrapEnabled、AnimationLevel、AnimationMode、FadeEnabled、PopInEnabled、SlideUpEnabled、AnimationLength、HighlightColorRed、FillColorRed、OutlineThickness、ShadowColorRed等),覆盖字幕文本、动画、高亮、填充、描边、阴影全部维度(见.setting1929–2218 行); - 自定义 ID 命名:颜色类控件一律使用
HighlightColorRed/Green/Blue、FillColorRed/Green/Blue、OutlineColorRed/Green/Blue、ShadowColorRed/Green/Blue等唯一命名,绕开 TextPlus 原生通道冲突; - 回调归属:所有
INPS_ExecuteOnChange与BTNCS_Execute均挂在内部Template工具的UserControls上,InstanceInput只做发布; - CustomData 数据化:动画、高亮、换行、字数时间戳(
WordTiming)缩放等全部逻辑以长括号字符串存储、loadstring执行,并配有注释明确的"如何新增动画"引导(349–352 行); - 发布/更新工作流:宏通过 caption-styles.md 描述的方式导入 Fusion 页面,并经 maintainer-template-release.md 描述的
setup-resolve+ "AutoSubs - Update Caption Template" 脚本流程随应用版本发布。
八、延伸阅读
- macro-authoring.md:本篇的原始参考文档
- animation.md:Fusion 关键帧、手柄、缓动与属性连接
- animation-system.md:AutoSubs 宏内动画系统的应用级文档(注册表模式的完整工作示例)
- fusion-templates.md:转场 / 生成器 / 标题 / 特效模板的宏化与模板路径
- autosubs-macro.setting:本文全部模式的生产级落地实例
- SKILL.md:DaVinci Resolve & Fusion 脚本与宏开发的完整技能索引与使用指引
- 人工智能
- AI 应用
- 语音
- 音频
- 本地部署
- 桌面应用
【免费下载链接】auto-subs
On-device subtitle generation that connects directly to DaVinci Resolve, Premiere, and After Effects.
相关推荐
DaVinci Resolve 与 Fusion 自动化开发实战指南:脚本编写、Fusion 宏(.setting)与关键帧动画
DaVinci Resolve 与 Fusion 自动化开发实战指南:脚本编写、Fusion 宏(.setting)与关键帧动画 导读 本指南以本仓库 .age
人工智能AI 应用语音音频本地部署桌面应用AutoSubs 与 DaVinci Resolve 脚本开发:Fusion IOClass 文件 I/O 方法完整指南
AutoSubs 与 DaVinci Resolve 脚本开发:Fusion IOClass 文件 I/O 方法完整指南 导读 IOClass 是 Fusion
人工智能AI 应用语音音频本地部署桌面应用AutoSubs 实战:DaVinci Resolve Fusion 关键帧动画与 BezierSpline 技术指南
AutoSubs 实战:DaVinci Resolve Fusion 关键帧动画与 BezierSpline 技术指南 本篇技术指南以仓库内 Fusion An
人工智能AI 应用语音音频本地部署桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考