Recent Posts
Script for Clip Colors based on Properties
- Get link
- X
- Other Apps
Problem: Identifying clips with different properties, based on Resolution, Frame Rate & Clip Name on the same Timeline.
Solution: Create a script that changes the clip color based on these properties.
The first hurdle in solving this problem is to learn the scripting language LUA, Oh! Wait, I know how to copy and paste. Therefore I can search the internet and find my solution. I did find 100’s of solutions for Adobe After Effects but only 1 for Blackmagic’s DaVinci Resolve. I would need to adapt the code for my use case but it was close enough.
I opened up the DaVinci Resolve documentation, luckily this is easy to find as it is located within Resolve itself. Help > Documentation > Developer > Scripting
Overview
--------
As with Blackmagic Design Fusion scripts, user scripts written in Lua and Python programming languages are supported. By default, scripts can be invoked from the Console window in the Fusion page, or via the command line. This permission can be changed in Resolve Preferences, to be only from Console, or to be invoked from the local network. Please be aware of the security implications when allowing scripting access from outside of the Resolve application.
So the first paragraph in the developer documentation tells me that if I do not set Resolve to use scripting I will not get off the ground.
DaVinci Resolve > Preferences > System > general
Prerequisites
-------------
DaVinci Resolve scripting requires one of the following to be installed (for all users):
Lua 5.1
Python 2.7 64-bit
Python 3.6 64-bit
I quickly discovered that resolve uses LAUJiT a variant of LUA by default so I don’t need to install LUA or Python on my computer and the code I discovered was LUA, which is lucky as I have no idea about Python. Python also requires a correct file path to resolve which according to the internet the Blackmagic documentation is incorrect and requires a lot of meddling. I wasn’t for meddling.
Using a script
--------------
DaVinci Resolve needs to be running for a script to be invoked.
For a Resolve script to be executed from an external folder, the script needs to know the API location.
You may need to set these environment variables to allow for your Python installation to pick up the appropriate dependencies as shown below:
Mac OS X:
RESOLVESCRIPTAPI="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting"
RESOLVESCRIPTLIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
PYTHONPATH="$PYTHONPATH:$RESOLVESCRIPTAPI/Modules/"
Windows:
RESOLVESCRIPTAPI="%PROGRAMDATA%\Blackmagic Design\DaVinci Resolve\Support\Developer\Scripting"
RESOLVESCRIPTLIB="C:\Program Files\Blackmagic Design\DaVinci Resolve\fusionscript.dll"
PYTHONPATH="%PYTHONPATH%;%RESOLVESCRIPTAPI%\Modules\
Linux:
RESOLVESCRIPTAPI="/opt/resolve/Developer/Scripting"
RESOLVESCRIPTLIB="/opt/resolve/libs/Fusion/fusionscript.so"
PYTHONPATH="$PYTHONPATH:$RESOLVESCRIPTAPI/Modules/"
(Note: For standard ISO Linux installations, the path above may need to be modified to refer to /home/resolve instead of /opt/resolve)
So Python is out and LUA is the choice of code, which is handy as anyone who has written an expression in the inspector on any tool knows LUA. However, I wasn’t going to start off with print(”Hello World”) I was going to dive right in
I have discovered that when building an asset for resolve, be it a title, transition, fuse, and now a script, the best place to create it is inside the folder which resolve uses. This is particularly important when building assets with media as you can use a relative path, therefore if you send the asset to someone it works right out of the box. Paths are a subject for a different article.
I wanted my new script to work on the edit page as this is the page that I spend most of my time in, therefore the path was:- C:\Users\user\AppData\Roaming\Blackmagic Design\DaVinci Resolve\Support\Fusion\Scripts\Edit
To build the script all I need is notepad, however as I am a web developer I have always used VSCode as it is easy to use and powerful.
As with Fusion scripts, Resolve scripts can also be invoked via the menu and the Console
On startup, DaVinci Resolve scans the subfolders in the directories and enumerates the scripts found in the Workspace application menu under Scripts.
Place your script under Utility to be listed on all pages, under Comp or Tool to be available on the Fusion page, or under folders for individual pages (Edit, Color or Deliver). Scripts under Deliver are additionally listed under render jobs.
Placing your script here and invoking it from the menu is the easiest way to use scripts.
Mac OS X:
- All users: /Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Scripts
- Specific user: /Users/<UserName>/Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Scripts
Windows:
- All users: %PROGRAMDATA%\Blackmagic Design\DaVinci Resolve\Fusion\Scripts
- Specific user: %APPDATA%\Roaming\Blackmagic Design\DaVinci Resolve\Support\Fusion\Scripts
Linux:
- All users: /opt/resolve/Fusion/Scripts (or /home/resolve/Fusion/Scripts/ depending on installation)
- Specific user: $HOME/.local/share/DaVinciResolve/Fusion/Scripts
I was happy to discover the various locations on where to place a script and why, this valuable piece of information will come in handy in any future scripting ventures.
Time to dive in and get scripting, I am not going to tell you that I know everything that I am adding, but will attempt to explain the bits I do know.
resolve = Resolve()
#This is required to write a script for resolve
pm = resolve:GetProjectManager()
# Returns the project manager object for the currently open database.
proj = pm:GetCurrentProject()
# Returns the currently loaded Resolve project.
tl = proj:GetCurrentTimeline()
# Returns the currently loaded timeline.
numtracks = tl:GetTrackCount("video")
# Returns the number of tracks for the given track type ("audio", "video" or "subtitle").
The above code gets the information that we want to work with and now we need to cycle through each clip on each track and change its color based on some properties.
for i = 1, numtracks do
The start of our loop to read each clip
items = tl:GetItemsInTrack("video", i)
# Returns a list of timeline items on that track (based on trackType and index).
1 <= index <= GetTrackCount(trackType).
for key, item in pairs(items) do
Not something I understand completely but I think it is creating a LUA table
mediaitem = item:GetMediaPoolItem()
# Returns the media pool item corresponding to the timeline item if one exists.
This surprised me as although it is looking at a clip on the timeline it needs to get the clip properties from the mediapool.
if (mediaitem ~= nil) then
Checks to see if there is actually media in the mediapool
md = mediaitem:GetClipProperty()
Creates the variable md which will hold the ClipProperties
if (md ~= nil) then
If there is media in the mediapool do what is next
item:ClearClipColor()
# Clears the item color
This didn’t cross my mind that you would have to clear what is already there.
We are now at the meat of the code and I am going to place examples here as there is no need to explain the whole code (which is at the end of this article)
if (md["Resolution"] == "1920x1080") then
item:SetClipColor("Green")
end
If the Resolution is 1920x1080 set the clip colour to Green, both the resolution and clip colour can be set as what you require.
if (md["File Name"] == "Subscribe.mp4") then
item:SetClipColor("Violet")
End
This code matches a File Name
if (md["FPS"] == "23.976") then
item:SetClipColor("Orange")
End
This code matches the Frame Rate
That was it I loaded the script by restarting DaVinci Resolve and added 2 tracks of random stock video and ran the script. Yes, I was surprised that it worked.
The Result
Here is the full code for you to play with.
- resolve = Resolve()
- pm = resolve:GetProjectManager()
- proj = pm:GetCurrentProject()
- tl = proj:GetCurrentTimeline()
- numtracks = tl:GetTrackCount("video")
- for i = 1, numtracks do
- items = tl:GetItemsInTrack("video", i)
- for key, item in pairs(items) do
- mediaitem = item:GetMediaPoolItem()
- if (mediaitem ~= nil) then
- md = mediaitem:GetClipProperty()
- if (md ~= nil) then
- item:ClearClipColor()
- if (md["Resolution"] == "1920x1080") then
- item:SetClipColor("Green")
- end
- if (md["Resolution"] == "4096x2160") then
- item:SetClipColor("Tan")
- end
- if (md["Resolution"] == "3840x2160") then
- item:SetClipColor("Chocolate")
- end
- if (md["Resolution"] == "1280x720") then
- item:SetClipColor("Teal")
- end
- if (md["File Name"] == "Subscribe.mp4") then
- item:SetClipColor("Violet")
- end
- if (md["FPS"] == "23.976") then
- item:SetClipColor("Orange")
- end
- if (md["FPS"] == "24.000") then
- item:SetClipColor("Yellow")
- end
- if (md["FPS"] == "29.97") then
- item:SetClipColor("Olive")
- end
- if (md["FPS"] == "30.000") then
- item:SetClipColor("Violet")
- end
- if (md["FPS"] == "50.000") then
- item:SetClipColor("Navy")
- end
- if (md["FPS"] == "60.000") then
- item:SetClipColor("Pink")
- end
- end
- end
- end
- end
- -- MediaPoolItem:GetClipProperty
- Get link
- X
- Other Apps
Comments
Post a Comment