見出し画像

【Davinci Resolve API】BMDライブラリについて

どうも、火注ゆかなです。

今回はDavinci Resolve のスクリプトを組む上で使用できるけど、日本語情報が見つからないbmdライブラリについてちょっと紹介します。



BMDライブラリって何?

よくわかりません!

というのは冗談ですが、私もそういうライブラリがあるらしいってことしかよくわかっていません。
色々検索して見ると2015年より昔の投稿なども引っかかります。どうやらBlack Magic Designが提供しているFusionなどの機能で使えるライブラリのようです。

まあ使えるなら由来とかどうでもいいですか!

(2023/12/30追記)
Pythonの方は"C:\ProgramData\Blackmagic Design\DaVinci Resolve\Support\Developer\Scripting\Modules"にあるDaVinciResolveScriptモジュールがbmdライブラリを指すようです。

どう使うのか?

Luaで組む場合は何か宣言する必要もなく、普通に使えます。
Pythonの方もDaVinciResolveの外部から操作しようとしない限りは何もインポートする必要はありません。

外部からの操作についてはこちらの記事で説明してます。

「bmd.関数名(引数)」で使用できますが、wait関数のような一部関数はResolveクラスに紐づけられているようで、頭に「bmd.」を付けなくても実行できたりします。

DavinciResolveの標準モジュールでGUIを組む際にもUI Dispatcherの宣言で使ってますね。覚えている人いるのでしょうか? これです。

ui = fu.UIManager
disp = bmd.UIDispatcher(ui)  -- <-dispatcherの設定で呼び出してる

BMDライブラリで使える関数一覧はコンソールで「dump(bmd)」を実行すると取得できます。

Lua> dump(bmd)
table: 0x01e182c02bd8
	crash = function: 0x01e182c0c1d8
	allocconsole = function: 0x01e182c0c238
	suspend = function: 0x01e182c0c2a0
	noise = function: 0x01e182c0c300
	pinghosts = function: 0x01e182c0c360
	fileexists = function: 0x01e182c0c3c8
	direxists = function: 0x01e182c0c430
	executebg = function: 0x01e182c0c498
	getcurrentdir = function: 0x01e182c0c500
	setcurrentdir = function: 0x01e182c0c568
	getpid = function: 0x01e182c0c5d0
	touserdata = function: 0x01e182c0c630
	wait = function: 0x01e182c0c698
	getuptime = function: 0x01e182c0c6f8
	gettime = function: 0x01e182c0c760
	stripname = function: 0x01e182c0c7c0
	isvalidname = function: 0x01e182c0c828
	fullpath = function: 0x01e182c0c890
	startserver = function: 0x01e182c0c8f8
	getappname = function: 0x01e182c0c960
	getappuuid = function: 0x01e182c0c9c8
	createuuid = function: 0x01e182c0ca30
	getclipboard = function: 0x01e182c0cad0
	setclipboard = function: 0x01e182c0cb38
	tounc = function: 0x01e182c0cba0
	scriptapp = function: 0x01e182c0cc00
	asyncscriptapp = function: 0x01e182c0cc68
	sendnotify = function: 0x01e182c0ccd0
	using = function: 0x01e182c0cd38
	getusing = function: 0x01e182c0cd98
	obtaingloballock = function: 0x01e182c0ce00
	releasegloballock = function: 0x01e182c0ce70
	defragfile = function: 0x01e182c0cee0
	defragsequence = function: 0x01e182c0cf48
	readfile = function: 0x01e182c0cfb0
	writefile = function: 0x01e182c0d018
	readstring = function: 0x01e182c0d080
	writestring = function: 0x01e182c0d0e8
	openfileexternal = function: 0x01e182c0d150
	openurl = function: 0x01e182c0d1c0
	setapptitle = function: 0x01e182c0d220
	translate = function: 0x01e182c0d288
	UIDispatcher = function: 0x01e182c1ef88
	getstateindex = function: 0x01e182c01f60
	nextstate = function: 0x01e182c01f90
	settrcontext = function: 0x01e182c12198
	_VERSION = 18.0.1
	exit = function: 0x01e182c0ca98
	readdir = function: 0x01e182c02c20
	createdir = function: 0x01e182c0c108
	removedir = function: 0x01e182c0c170

また、頭に「bmd.」と付けなくても実行できる関数も「dump(debug.getinfo(Resolve))」で確認できます。
このコマンドから得られる情報には「splitpath(filename)」のように便利な関数も確認できるため、一度見ておくのも良いかもしれません。

-- 実行結果からbmdライブラリとリンクしている部分抜粋

readdir = bmd.readdir
createdir = bmd.createdir
removedir = bmd.removedir
pinghosts = bmd.pinghosts
fileexists = bmd.fileexists
direxists = bmd.direxists
executebg = bmd.executebg
getcurrentdir = bmd.getcurrentdir
setcurrentdir = bmd.setcurrentdir
getpid = bmd.getpid
touserdata = bmd.touserdata
wait = bmd.wait
stripname = bmd.stripname
isvalidname = bmd.isvalidname
fullpath = bmd.fullpath
StartServer = bmd.startserver
GetAppName = bmd.getappname
GetAppUUID = bmd.getappuuid
CreateUUID = bmd.createuuid
exit = bmd.exit
getclipboard = bmd.getclipboard
setclipboard = bmd.setclipboard
ToUNC = bmd.tounc
ScriptApp = bmd.scriptapp
AsyncScriptApp = bmd.asyncscriptapp
SendNotify = bmd.sendnotify
Using = bmd.using
GetUsing = bmd.getusing
SetActiveComp = bmd.using
GetActiveComp = bmd.getusing

function bmd.getstateindex(t, s)        
    for i,v in pairs(t) do    
        if v == s then
        
        end
    end    
end        

function bmd.nextstate(t, s)    
    return t[bmd.getstateindex(t, s) % #t + 1]
end    

function bmd.settrcontext(ctx)    
    bmd.__trcontext = ctx
end    

でもこれだけだと使い方がわかりませんよね。

関数の機能について

We Suck Lessフォーラムの投稿によると、どうやらbmdライブラリはEyeonスクリプトライブラリとリンクしているとのこと。

というわけでEyeonスクリプトについて説明されているWebページを紹介しておきます。Googleの翻訳機能でも全く問題なく読めます。
一部関数については記事が未編集だったり、bmdライブラリにのみ存在する関数については使い方がわからないままですが、ここで半分以上の関数の使い方はわかるでしょう。

https://www.steakunderwater.com/VFXPedia/96.0.243.189/index894b-2.html?title=Eyeon:Script/Reference/Libraries/eyeon

使えなくなっている関数もある

しかし、BMDライブラリの一部関数は使えなくなっている可能性もあります。

例えばexecutebg()という関数があります。
これはLuaでいうos.execute(コマンドプロンプトを呼び出してコマンド実行する)をバックグラウンドで実行する関数で、普通にos.executeを呼び出すのと違ってコマンドプロンプトの画面が表示されないという利点があったようです。

今まさに私が欲しい機能なのですが、Fusion8以降から使えなくなった模様?
試しにos.executeでは実行できたコマンドをいくら引数に渡してもうんともすんとも言いません。無効化されているようです。

どうして……どうして消したの……? ドウ……シテ……

そんな感じで、ライブラリに含まれるからといって必ず使えるとは限らない点に注意してください。



関数一覧

関数と、それらを私が調べたり試したりして得た情報について記述します。
私の知識不足によりよくわからないものもあるので歯抜けなのはご了承ください。
随時更新予定です。期待はしないで。

  • allocconsole

  • asyncscriptapp

  • crash

  • createdir("dirpath") return boolean

    • 引数に渡したパスのディレクトリを作成します。パス名には全角文字も使用可能
      作成に成功した場合はtrueを、同名パスが既に存在するなどの理由により作成に失敗した場合はfalseを返します。
      "c:\\path1\\path2" と指定して、かつ「path1」「path2」フォルダの両方が存在しないような場合、「path1」「path2」 の両方を作成します。

  • createuuid

  • defragfile

  • defragsequence

  • direxists

    • ディレクトリがあるかどうかをbooleanで返却します。

  • executebg("command"[, wait])

    • 第1引数に渡したシェルコマンドをバックグラウンドで実行します。
      第2引数をtrueにすると、コマンドの実行が終了するまで待機します。
      コマンドをターミナルへ送信できたかどうかを返却します。(実行できたかどうかではない)
      Fusion8以降から使用できなくなった模様?

  • exit()

    • 実行するとアプリケーションを終了するとの説明があります。
      (コンソールで実行しても何も起きず)

  • fileexists("filepath")

    • 引数として渡されたパスのファイルがあるかどうかをbooleanで返却します。

  • fullpath("path")

    • カレントディレクトリと引数の文字列を組み合わせたパスを返します。
      "test.txt"を引数に渡した場合、カレントディレクトリがデフォルトのままなら「C:\Program Files\Blackmagic Design\DaVinci Resolve\test.txt」が返されるはずです。

  • getappname

  • getappuuid

  • getclipboard() return String

    • クリップボードに設定されている文字列を返却します。
      ファイルなどや画像など、文字列でない場合はnilを返却します。

  • getcurrentdir() return String

    • カレントディレクトリを返却します。
      カレントディレクトリを変更していない場合、デフォルト値は「C:\Program Files\Blackmagic Design\DaVinci Resolve」になるはずです。

  • getpid

  • getstateindex

  • gettime() return number

    • 特定のタイミングからカウントした時間を数値で返却します。

  • getuptime() return number

    • 特定のタイミングからカウントした時間を数値で返却します。
      gettime()とは微妙に値が異なる模様。

  • getusing

  • isvalidname

  • nextstate

  • noise

  • obtaingloballock

  • openfileexternal("Open", "filepath")

    • 第1引数に"Open"、第2引数にパスを指定すると、指定パスをファイルエクスプローラで開きます。
      ファイル選択ダイアログのような機能はなく、ファイルエクスプローラを開くだけです。

  • openurl("URL")

    • 引数に渡したURLを既定のブラウザで開きます。

  • pinghosts

  • readdir("filepath") return table

    • 指定パスのファイル・フォルダに関する情報を格納したテーブルを返します。
      Eyeonスクリプトライブラリの説明ページではフォルダ内のファイル一覧も取得するような書き方ですが、2023/1/7現在では指定パスのフォルダ自身の情報しか返しません。

  • readfile

  • readstring

  • releasegloballock

  • removedir

  • scriptapp

    • scriptapp('Resolve')とかって実行すると最上位であるResolveオブジェクトを取得できる。Pythonで外部から操作しようとしない限りは特に実行する必要もない。

  • sendnotify

  • setapptitle

  • setclipboard("string")

    • クリップボードに文字列をセットします。

    • Resolveクラスに紐づけられており、「bmd.wait(10)」だけでなく「wait(10)」という記述だけでも使用可能です。

  • setcurrentdir("dirpath")

    • カレントディレクトリを引数のパスへ変更します。
      実行結果(成功したかどうか)をboolean型で返却します。

  • settrcontext

  • startserver

  • stripname("string")

    • すべての空白と英数字以外の文字が削除された、引数文字列のコピーである文字列を返します。
      「_」(アンダーバー)以外の記号も消されるようなので注意が必要。

  • suspend

  • tounc

  • touserdata

  • translate

  • UIDispatcher(UI)

    • GUIの作成に必要なdispatcherを返します。LuaでGUI組む場合は必須。
      引数には「fu.UIManager」を代入した変数を指定してください。

  • using

  • wait(second)

    • 指定した秒数を待機します。
      2.5のような小数点以下の数値も指定可能です。

    • Resolveクラスに紐づけられており、「bmd.wait(10)」だけでなく「wait(10)」という記述だけでも使用可能です。

  • writefile

  • writestring

サポートしていただけるとその分の価値を提供できてるんだなって励みになります。