Python Scripting with DaVinci Resolve Studio 16

by

Hey there! Some links on this page may be affiliate links which means that, if you choose to make a purchase, I may earn a small commission at no extra cost to you. I greatly appreciate your support!

Although DaVinci Resolve scripting capabilities are extremely limited, I found it promising to see that this sort of capability was being developed at BlackMagicDesign.

Learn about Python scripting with DaVinci Resolve Studio 16 in order to automate the repetitive process of reusing your YouTube videos for IGTV.

Why I Want to Script DaVinci Resolve

My goal was to write a Python script that would repurpose a video for YouTube as an Instagram TV video. If you’re not familiar, IGTV is a vertical video platform, so by placing my horizontal YouTube video on a vertical IGTV background template, I can publish the same video to my Instagram audience.

With full DaVinci Resolve Python scripting capabilities, here is ideally what my video scrip would do.

  1. Create a DaVinci Resolve project
  2. Set project settings such as width, height, and frame rate
  3. Import a rendered video file and IGTV background template (another video file) to the media pool
  4. Add the video file to the timeline on a track above the IGTV background template
  5. Dynamically add a text tile to the timeline on the above track
  6. Load render presets and render the video

While my script can accomplish most of these steps, DaVinci Resolve scripting capabilities are limited. So I had to improvise.

  • DaVinci Resolve scripting does not support dynamic text, so I had to add a track with static text. No getting around this.
  • Additionally, Python scripting only allows you to append clips to a single track (Track 1), so my template had to exist on Track 2 or above.

DaVinci Resolve timeline with multiple tracks

Below find out my scripting setup on my Mac as well as the full text of my Python script.

DaVinci Resolve Python Scripting Setup on a Mac

This tutorial assumes that you have Python 3 installed on your Mac with a virtual environment.

The location of DaVinci Resolve developer stuff is located at /Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer. You can also access this by clicking on Help -> Developer Documentation within DaVinci Resolve.

Either change directory to this path in a terminal, or set the following environment variables according to the README.

RESOLVE_SCRIPT_API="/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/"
RESOLVE_SCRIPT_LIB="/Applications/DaVinci Resolve/DaVinci Resolve.app/Contents/Libraries/Fusion/fusionscript.so"
PYTHONPATH="$PYTHONPATH:$RESOLVE_SCRIPT_API/Modules/"

The provided examples in the Scripting/Examples directory are quite helpful, especially the ones highlighted below:

  • 1_sorted_timeline_from_folder.py
  • 2_compositions_from_timeline_clips.py
  • 3_grade_and_render_all_timelines.py
  • 4_display_project_and_folder_tree.py
  • 5_get_project_information.py
  • 6_get_current_media_thumbnail.py
  • python_get_resolve.py

Lastly, I do suggest you read the README.txt as it’s the only official DaVinci Resolve scripting documentation available at this point.

DaVinci Resolve Python Script

This first Python script creates a DaVinci Resolve project, sets settings, and imports the Instagram TV template video file which I designed previously into the media pool. The script also adds the IGTV template clip to the timeline.

from python_get_resolve import GetResolve
import sys

framerate = 30
width = 1080
height = 1920

project_name = 'igtv-template'
igtv_template_path = '/Users/tonyflorida/Movies/igtv/igtv-template.mov'

# Create project and set parameters
resolve = GetResolve()
project_manager = resolve.GetProjectManager()
project = project_manager.CreateProject(project_name)

if not project:
    print("Unable to create a project")
    sys.exit()

project.SetSetting("timelineFrameRate", str(framerate))
project.SetSetting("timelineResolutionWidth", str(width))
project.SetSetting("timelineResolutionHeight", str(height))

# Create mediapool and storage objects
mediapool = project.GetMediaPool()
storage = resolve.GetMediaStorage()

# Add video file to media pool
clips = storage.AddItemsToMediaPool(igtv_template_path)
# Create timeline:
timeline_name = "Timeline 1"
timeline = mediapool.CreateEmptyTimeline(timeline_name)
if not timeline:
    print("Unable to create timeline '" + timeline_name + "'")
    sys.exit()

# Add video file to timeline
mediapool.AppendToTimeline(clips[1])

While this entire script needs only to be executed once and can easily be configured manually through the DaVinci Resolve interface, this is just for demonstration purposes.

After the addition of a title and a performing manual render through the UI, this is essentially why my template IGTV template looks like.

IGTV template
A basic Instagram TV video template

I made this template project 10 minutes long since that’s the IGTV time limit for small creators at this time.

In order to reuse this template, you must export it via File -> Export Project. I saved my igtv-template.drp file to the igtv subdirectory in my Movies folder.

With the template saved, I wrote the following Python script which copies the template and works out of that project instead.

Essentially, this script goes on to:

  • Load the copied template project
  • Add the video file to the timeline
  • Determine the first and last frame of the video file (MarkIn and MarkOut)
  • Set and load render setting
  • Render out the new video file
from python_get_resolve import GetResolve
import sys
import os
import shutil

if len(sys.argv) < 2:
    print("input parameters for scripts are video_path")
    sys.exit()
video_path = sys.argv[1]

template_root = '/Users/tonyflorida/Movies/igtv/'
template_file = os.path.join(template_root, 'igtv-template.drp')

video_name = os.path.basename(video_path)
project_name = 'igtv-' +  os.path.splitext(video_name)[0]
project_file = os.path.join(template_root, project_name + '.drp')

# Make a copy of the project template
shutil.copy2(template_file, project_file)

# Load project
resolve = GetResolve()
project_manager = resolve.GetProjectManager()
project_manager.ImportProject(project_file)
project = project_manager.LoadProject(project_name)
if not project:
    print("Unable to load project")
    sys.exit()

# Add video file to Media Pool
mediapool = project.GetMediaPool()
storage = resolve.GetMediaStorage()
clips = storage.AddItemsToMediaPool(video_path)
mediapool.AppendToTimeline(clips[1])

# Get MarkIn and MarkOut
timeline = project.GetTimelineByIndex(1)
mark_out = timeline.GetItemsInTrack('video', 1)[1].GetEnd()
mark_in = timeline.GetStartFrame()

# Render
target_directory = os.path.dirname(video_path)
render_settings = {"MarkIn":mark_in, "MarkOut":mark_out, "TargetDir":target_directory, "CustomName":project_name}
project.LoadRenderPreset('igtv-preset')
project.SetRenderSettings(render_settings)
project.DeleteAllRenderJobs()
project.AddRenderJob()
project.StartRendering()

Please note that I manually created the render preset called igtv-preset by calling the SaveAsNewRenderPreset(presetName)after manually setting the following in the Deliver tab according to the IGTV Help Center:

  • Format: MP4
  • Resolution: Custom
  • Dimensions: 1080 x 1920
  • Frame rate: 30

I saved my Python script as generate-igtv-video.py and it can be executed similar to below:

python generate-igtv-video.py /Users/tonyflorida/Movies/video.mp4

Don’t Be a Stranger ?

If you have any questions about scripting with DaVinci Resolve, please let me know in the comments below. I’m looking forward to future releases of the DaVinci Resolve scripting API, and would love to talk to others in the community who share a similar interest.

Also, you can check out my IGTV videos here, follow me on YouTube, and check out some of my other Python blog posts.


About The Author

With a strong software engineering background, Tony is determined to help as many people as possible start their online busines. Discover why Tony quit his hedge fund job to pursue this mission. You can send Tony a message here.

7 thoughts on “Python Scripting with DaVinci Resolve Studio 16”

  1. Good day Tony,
    I’m new on Resolve 16 and had some issues with the Media Manager trim function. I would like to move the project trimmed with an offset of 50 frames for future editing. Resolve crash always when the left or right offset is smaller then 50 frames. I have started to write a small script in LUA to test the current clip but I would like to write my one export/trim script in Python. Unfortunately the documentation of the usable Resolve functions is not complete. Per example I need to scan all the clips in the timeline and to copy the trimmed clip including 50 frames (if available). Is this possible with scripting?

    Best regards from Namibia

    –[[
    DaVinci Resolve script:
    copy and trim current timeline.
    –]]

    resolve = Resolve()
    projectManager = resolve:GetProjectManager()
    project = projectManager:GetCurrentProject()
    timeline = project:GetCurrentTimeline()
    timecode = timeline:GetCurrentTimecode()
    clip = timeline:GetCurrentVideoItem()
    clipname = clip:GetName()
    duration = clip:GetDuration()
    clipstart = clip:GetStart()
    clipend = clip:GetEnd()
    clipleftoffset = clip:GetLeftOffset()
    cliprightoffset = clip:GetRightOffset()

    print(“Project Manager: “,projectManager)
    print(“Project: “,project)
    print(“Timeline: “,timeline)
    print(“Timecode “,timecode)
    print(“Clip: “,clip)
    print(“Clipname: “,clipname)
    print(“Clip Duration: “,duration)
    print(“Clip Start: “,clipstart)
    print(“Clip End: “,clipend)
    print(“Clip Left Offset: “,clipleftoffset)
    print(“Clip Right Offset: “,cliprightoffset)

    if (clipleftoffset < 50) then
    print("ATTENTION Left Offset To Small","\n")
    end
    if (cliprightoffset < 50) then
    print("ATTENTION Right Offset To Small","\n")
    end

    Reply
    • The Python scripting capabilities are very limited in DaVinci Resolve 16. I’m not sure if you want to trim individual clips, or you entire timeline. Trimming individual clips isn’t possible as far as I know. In order to trim the beginning or end of your timeline, you can set the render settings for MarkIn and MarkOut like this:
      render_settings = {"MarkIn":mark_in, "MarkOut":mark_out}
      project.SetRenderSettings(render_settings)

      This will select everything in your timeline between mark_in and mark_out.

      In order to set mark_in and mark_out with an offset of 50 frames on either side, you can do something like:

      mark_in = timeline.GetStartFrame() + 50
      mark_out = timeline.GetItemsInTrack('video', 1)[-1].GetEnd() - 50

      Is this kind of along the lines of what you want to accomplish?

      Reply
  2. Hey Tony,
    could you explain in more detail how you managed to set up Resolve to pick up the Python installation in your venv?
    I’m trying something similar on Win7 and conda but each time I’m opening Resolve’s Console I get an error telling me Python is not installed.
    Also trying to run an example gives me segmentation fault ¯\_(ツ)_/¯

    Cheers,
    also Tony 😉

    Reply
    • Hey Tony!
      My suggestion would be to cd to the Examples folder in conda (it’s located in the RESOLVE_SCRIPT_API directory above) and open the python CLI here (i.e. just type python and hit enter). Then just like in all the example python files, test if you can execute from python_get_resolve import GetResolve. Does this work for you, or do you get a segfault here too?
      Tony

      Reply
      • Yeah tried this but unfortunately this gives me a segfault aswell :/
        I have no clue why I get this. I’ll try with a “normal” python installation but that’s not really what I’m after :/

        Reply
        • You also need to have python 2 or 3 selected in the Fusion menu -> Fusion Settings -> Script-> Python Version. Resolve will only use one or the other at a time. Also under Resolve System Preferences-> General, “External Scripting Using” dropdown needs to be either “Local” or “Network.” I’m also having trouble changing the Python install, but I think it has more to do with the way I installed in the first place.

          Reply

Leave a Comment