Davinci Resolve: マクロプログラミング
マクロのフォーマット
拡張子 .setting
テキスト形式
言語不明(LuaでもPythonでもない)
エディタ内ではファイル名で表示される(*.settingの*部分)
一応日本語のファイル名でも動作する(使用不可な文字があるかは不明)
基本
最小のプログラム
以下で、なんの機能も持たないグループ「Group1」が一つ生成される
code:text
{
Tools = {
Group1 = GroupOperator {}
}
}
基本フォーマット
まず全体を中カッコでくくる。
最上位の中括弧の内容は最低限Toolsが存在する。これがノードを定義するようだ
中括弧の内容は以下のパターン。
<変数名> = <関数?> { <パラメータ名>=<値>, ... }
変数、関数名はアルファベットの場合先頭が大文字、日本語の場合は大カッコとダブルクオーテーションでくくるのがパターンのようだ
※ただしordered()だけ例外。
ordered()はToolsとInputsのどちらかに登場する。名前的から推測するに{}の内容の項目を並べ替えよ(アルファベット順?)という意味のように思えるが、そうであれば一つだけしか中身がない場合は書く必要がないと思う。なお無くても動く模様
また、パラメータを複数行並べる場合はカンマ,区切りが必須。文末の余計なカンマは許容されるようだ。よって式の終わりにはとりあえずカンマを付けておけば良い。
code:txt
{
Tools = ordered() {
UseFrameFormatSettings = Input { Value = 1, },
Center = Input { Value = { 0.5, 0.5 }, },
},
}
GroupOperator
このノード以下のToolsをグループとして扱う。
普通にマクロを作るとMacroOperatorができるが、これはそのノード以下のToolsを外部から隠蔽する。すなわちMacroOperatorで作ってしまうとエディタ上でその中身が触れなくなる。念のためGroupOperatorで作っておくと、ミスがあったときに修正や改造がしやすくなる(もっとも、今回はテキストエディタだけで完結させるのが目標なためそのような心配は無いといえばないのだが)。
Inputs: 入力パラメータの定義。
InstanceInputでノードの内容に関連づけする。
そのままパネルに並ぶパラメータの内容になる。
Input1,Input2…のように連番で記述する。記述した番号順にパネルに上から並ぶ。(これはordered()の効果かもしれない。他の名前だと順不同?)
Outputs: 出力先の定義
出力ピンがどこのノードから繋がっているか。
InstanceOutputで定義する。
MainOutput1がメインの出力ピンになるようだ。
Tools: グループ内のノード(Tools)
ViewInfo: エディタ上のノードの表示位置。省略するとおそらく中央に置かれる(複数ある場合は重なる)。Fusionエディタ上で編集する予定があるならノードの配置も見やすいように考えなければならないが、今回はテキストエディタで全て編集する前提なので以降のViewInfoはすべて省略する。
code:txt
GroupOperator {
Inputs = ordered() { //<-- 入力ピンの定義
Input1 = InstanceInput {...}, //<-- InputXの順番がパラメータの並び順になるようだ
Input2 = InstanceInput {...},
...
},
Outputs = { //<-- 出力ピンの定義
MainOutput1 = InstanceOutput {...},
}
}
InstanceInput
入力パラメータとノードの入力を関連づける。それぞれダブルクオーテーションで囲うこと。
SourceOP: 関連づけるノード名
Source: 関連ノードのパラメータ名
Name: 表示上のラベル。日本語OK
code:txt
Input1 = InstanceInput {
SourceOp = "MainText",
Source = "Center",
Name = "センター",
}
Input
定数や変数をノードにわたす
Value: 値。数値、文字列、オブジェクトなど様々
code:txt
Width = Input { Value = 1920, }
InstanceOutput
出力を他のノードの出力と関連づける。それぞれダブルクオーテーションで囲うこと。
SourceOp: 関連づけるノード名
Source: 関連づける出力名。基本的には"Output"
code:txt
MainOutput1 = InstanceOutput {
SourceOp = "MainText",
Source = "Output",
}
サンプル
TextPlusを配置してそのセンター位置をパネルからいじれるようにしただけのマクロ
MediaOutはないので自分でつなぐ必要あり
code:txt
{
Tools = Ordered() {
Group1 = GroupOperator {
Inputs = Ordered() {
Input1 = InstanceInput {
SourceOp = "MainText",
Source = "Center",
Name = "センター",
},
Outputs = {
MainOutput1 = InstanceOutput {
SourceOp = "MainText",
Source = "Output",
},
},
},
Tools = ordered() {
MainText = TextPlus {
Inputs = {
UseFrameFormatSettings = Input { Value = 1, },
Center = Input { Value = { 0.5, 0.5 }, },
StyledText = Input { Value = "サンプルテキスト", },
Font = Input { Value = "Noto Sans JP", },
Size = Input { Value = 0.1, },
},
}
}
}
}
}
自動解像度について
Davinci Resolveでは基本的に画面フレームに対する割合によって座標を決定する。例えばCenter = Input { Value = { 0.1, 0.8 } }であれば画面に対して左から10%、上から80%の位置を指す。これによりフレームサイズが変わっても対応できる。
いくつかのノードではWidth,Heightでフレームサイズを指定できるものがあるが、代わりにUseFrameFormatSettings = Input { Value = 1, },を設定しておくと「自動解像度」が有効になり、Width,Heightを指定する必要がなくなる。
ノードのパラメータ名を調べる方法
ノードをひとつ置き、右クリ>マクロ>マクロの作成 でそのノードで使用できるパラメータの一覧と日本語ラベル名を表示できる。パラメータ名がわかったら保存せず閉じれば良い
動きをつける
まずカーブを定義する。
["カーブ名"](もしくはSpline1などの英数字変数名)= BezierSpline {}
英数字で名前をつけても勝手にラベル名(日本語環境なら日本語名)に変換されるっぽい
SplineカーブはToolsの中に格納する。
BezieSpline
SplineColor: エディタ上の表示色。省略すると緑等の適当な色になる。本稿では省略する。
KeyFrames: キーフレームのリスト
[<フレーム番号>] = { <フレーム情報> }
キーフレーム情報:{ <値>, <ハンドル情報>, Flags=<補完方法> }
ハンドル情報:<右ハンドル=RH/左ハンドル=LH> = { <ハンドルが伸びる先のX位置(絶対フレーム)>, <ハンドルが伸びる先のY位置(絶対値)>}
ハンドルの長さは標準で10。つまり「フレーム3、値1、右(真横)に10伸びるハンドル」のキーフレーム情報は[3] = { 1, RH = { 13, 1 } }になる。
計算が必要なことに注意。真横なら問題ないが斜めの場合は計算が複雑になる
ハンドルの長さを0にするとリニア(直線)になる
ただし経験上、ハンドルを省略するとエディタでいじったときに落ちやすい。LHかRHのどちらかでも設定しておいがほうが無難。
保管方法:
指定なし:スムース
始点から終点にかけてなめらかに変化する(ハンドルの長さと角度による)
StepIn = true: ステップイン(終点のみ指定)
終点フレームに来た瞬間に値が飛ぶ
StepOut = true: ステップアウト(終点のみ指定)
始点フレームに来た瞬間に値が飛ぶ(終点指定なのが謎)
Loop = true: ループ(始点終点両方指定)
始点から終点にかけての動きを繰り返す(終点に到達した瞬間始点の値に飛ぶ)
Loop = true, Pingpong = true: ピンポン(始点終点両方指定)
始点から終点にかけての動きを繰り返す(終点に到達したら始点の値にむけてなめらかに動き、それを繰り返す)
例
code:txt
0 = { 0, RH = { 6, 0 } }, 30 = { 0.1, LH = { 24, 0.1 }, Flags = { StepIn = true } }, カーブをパラメータに適用
Inputで以下を指定
SourceOp= "<カーブ名>"(ダブルクォーテーションを忘れずに)
Source = "Value"
code:txt
Tools = {
MainText = TextPlus {
Inputs = {
...
Size = Input {
SourceOp = "Spline1",
Source = "Value",
},
},
},
Spline1 = BezierSpline {
KeyFrames = {
0 = { 0, RH = { 10, 0 } }, 30 = { 0.1, LH = { 20, 0.1 } } }
}
}
サンプル
文字が大きくなったり小さくなったりを延々繰り返すマクロ
code:txt
{
Tools = ordered() {
Group1 = GroupOperator {
Outputs = {
MainOutput1 = InstanceOutput {
SourceOp = "MainText",
Source = "Output",
},
},
Tools = ordered() {
MainText = TextPlus {
Inputs = {
UseFrameFormatSettings = Input { Value = 1, },
StyledText = Input { Value = "サンプルテキスト", },
Font = Input { Value = "Noto Sans JP", },
Size = Input {
SourceOp = "Spline1",
Source = "Value",
},
},
},
Spline1 = BezierSpline {
KeyFrames = {
0 = { 0, RH = { 10, 0 }, Flags = {Loop = true, Pingpong = true} }, 10 = { 0.1, LH = { 0, 0.1 }, Flags = {Loop = true, Pingpong = true} }, },
},
},
},
},
}
エクスプレッション
Input { Value = <値>, Expression = "式" }
式が間違っていたり、Valueとの整合性が取れなかった場合どうなるのか不明(多分更新時にエラー吐くんだろう)
code:txt
Inputs = {
Width = Input { Value = 0.1, },
Height = Input {
Expression = "Width*(16/9)", ※正方形。画面が16:9でその比率で値を指定しているので。
},
},
ノードリファレンス
クリーニング共通(消せるパラメータ)
NameSet: 消して良い。
CtrlWZoom: 消して良い。
TextPlusでEnabledがない数字付きパラメータ。Green2など。
シェーディングのパラメータ。Enabled*=1を指定して初めて有効になる。
なのでEnabledがない項目は有効になってないパラメータを記憶しているだけなのでゴミ。
ただし、Enabled1だけは省略されていても有効なので、Red1などの1がついてるパラメータは消してはいけない。
まとめると、
Red1, Name1,Thickness1など1がついているパラメータは消さない。
Red2,Name3,Thickness5など2以降のパラメータは、Enabled<数字>があれば残す、なければ消して良い。
UseFrameFormatSettings: 消してはいけない。
UseFrameFormatSettings=1があればWidth, Heightは消せるものもある
SplineColor: 消して良い
0.6666666などのやたら細かい数値: 小数点以下3位くらいまでは残してあとは消してもそんなに影響ない。0.666など。
背景(Background)
基本的に図形はマスクなので、背景に繋がないと色が出ない
パラメータ
Inputs
EffectMask: 切り抜く図形ノードを指定。指定しないと全画面になるはず。
TopLeftRed/Green/Blue/Alpha: 色指定。1を100%とした小数指定。TopLeftというのはグラデーションが左上から始まるからで、グラデ指定する場合はBottomLeftも指定するんだろう(多分)。単色の場合はTopLeftのみで良い
code:txt
BoxColor = Background {
Inputs = {
EffectMask = Input {
SourceOp = "Box",
Source = "Mask",
},
TopLeftRed = Input { Value = 0.478, },
TopLeftGreen = Input { Value = 0.843, },
TopLeftBlue = Input { Value = 0.149, },
},
}
四角マスク(RectangleMask)
パラメータ
Inputs
UseFrameFormatSettings: 自動解像度。オン(=1)推奨。=1
Center: 中心位置。
Width: 幅 = 0.5
Height: 高さ = 0.5
code:txt
Box = RectangleMask {
Inputs = {
UseFrameFormatSettings = Input { Value = 1, },
Center = Input { Value = { 0.5, 0.5 } },
Width = Input { Value = 0.015, },
Height = Input { Value = 0.13, },
},
},
マージ(Merge)
パラメータ
NameSet: 不明。= true
Inputs
Foreground: 前景
Background: 後景
EffectMask: マスク
Operator:オペレーター、合成方法
オーバー: 通常の重ね合わせ。後景の上に前景が重なる。デフォルト
イン: 後景で前景を切り抜く。
ヘルドアウト: 後景部分が穴になる。
ATOP: 後景の上に前景が乗った上で後景の形に切り抜かれる。
排他的論理和: 重なっている部分が穴になる。
コンジョイント: ?
ディスジョイント: ?
マスク: 前景で後景を切り抜く。
ステンシル: 前景部分が穴になる。
下: 前景の上に後景が重なる。
ApplyMode: 運用モード。通常/スクリーン/ディゾルブ/比較(暗)/乗算...
Gain:ゲイン。運用モードの適用率。(運用モードによって効果が違う)
BlendClone: ブレンド。前景の透明度
code:txt
AllMerge = Merge {
Inputs = {
Background = Input {
SourceOp = "SubTitle",
Source = "Output",
},
Foreground = Input {
SourceOp = "MainTitle",
Source = "Output",
},
},
},
エクスプレッションメモ
本題と外れるがエクスプレッションに使える便利なパラメータ。
フレームサイズを知る
comp:GetPrefs('Comp.FrameFormat.Width')
comp:GetPrefs('Comp.FrameFormat.Height')
ノードの出力サイズを知る
<ノード名>.Output.DataWindow.right-<ノード名>.Output.DataWindow.left
<ノード名>.Output.DataWindow.bottom-<ノード名>.Output.DataWindow.top