constantworkflow

batch-render-export

Batch Render Export for DaVinci Resolve: Rendering Multiple Spot Lengths in One Command

When a client requests the same video cut down to 30s, 15s, 6s, 5s, and 4s versions for different broadcast slots, manually queueing each render wastes 10-15 seconds that could be spent moving to the next task. This script eliminates the multi-select workflow by automatically finding all sequences in my project and rendering them with a single keystroke.

The Problem

I maintain a strict project organization philosophy: the only sequences in my timeline bin are final deliverables that need to be rendered. I don't keep "best takes" sequences or rough assemblies—those clips get extracted to a dedicated bin and the sequence gets deleted. This means every timeline in my seq bin is a finished spot (30s, 15s, 6s, 5s, 4s) waiting for export.

The manual batch render process in DaVinci Resolve 20 was already fairly efficient:

  1. Click into the sequence bin
  2. Cmd+A to select all timelines
  3. Right-click one sequence → hover over "Add to Render Queue" → click preset
  4. Dialog appears for save location, queues all timelines
  5. Tab to Deliver page (Shift+8)
  6. Manually select all queued renders
  7. Click "Start Render"

Total time: 10-15 seconds. But the real cost wasn't the seconds—it was the context switching. I couldn't move to the next edit, respond to a Slack message, or check email until I'd completed all seven steps. For broadcast projects with AirCo, QuikTrip, or Galaxy Home Recreation where multiple spot lengths are standard, this friction happened every single time I finalized a project.

The Solution

This script uses the DaVinci Resolve API to bypass the UI entirely. It scans the seq bin for all timelines (or all project timelines if no seq bin exists), queues each with the TV export preset, and starts rendering—all in the background.

The workflow is now: Cmd+Space to open Raycast, type "batch render," hit Enter. Done. I can immediately tab away to the next task while all exports process in parallel.

Technical Implementation

The script handles three layers of complexity that would cause manual failures:

1. Seq Bin Filtering

Instead of blindly rendering every timeline in the project (including nested sequences, test comps, or archived versions), the script looks for a bin named seq in the media pool root. If found, it only processes timelines stored there. If the seq bin doesn't exist, it falls back to rendering all timelines—a safety net for non-standard project structures.

seq_bin = None
for folder in subfolders:
    if folder.GetName() == 'seq':
        seq_bin = folder
        break

target_timeline_names = []
if seq_bin:
    clips = seq_bin.GetClipList()
    for clip in clips:
        if clip.GetClipProperty('Type') == 'Timeline':
            target_timeline_names.append(clip.GetName())

This filtering ensures I never accidentally render work-in-progress sequences or internal references.

2. NAS Lag Retry Logic

When rendering to network storage (my typical 9-to-5 setup at QuikTrip), the Deliver page needs time to communicate with the NAS before the render queue becomes active. Without accounting for this, the script would attempt to add jobs while the network was still initializing, resulting in silent failures where timelines appeared in the queue but wouldn't render.

The retry loop solves this by attempting to add each render job up to 5 times with 1-second intervals:

max_retries = 5
attempt = 0
job_id = None

while attempt < max_retries:
    job_id = project.AddRenderJob()
    if job_id:
        break
    time.sleep(1)
    attempt += 1

If the network or Resolve's internal database is slow to respond, the script waits rather than failing. This same buffer prevents issues when working locally, where the Edit-to-Deliver page transition still requires a brief initialization period.

3. Queue Clearing Before Batch Add

The script calls project.DeleteAllRenderJobs() before adding new jobs to ensure the queue is clean. This prevents duplicate renders if I accidentally trigger the script twice or if previous jobs were left incomplete.

4. Batch Job Collection

Unlike the single-timeline render script (which adds one job and immediately starts), this script collects all job IDs in a list before calling project.StartRendering(job_ids). This ensures all timelines are queued before any rendering begins, preventing race conditions where Resolve might finish one job before others are added.

job_ids = []
for i in range(1, timeline_count + 1):
    timeline = project.GetTimelineByIndex(i)
    # Filter by seq bin membership
    if target_timeline_names is not None:
        if name not in target_timeline_names:
            continue
    # Load preset, add job, collect ID
    job_id = project.AddRenderJob()
    if job_id:
        job_ids.append(job_id)

project.StartRendering(job_ids)

Time Savings

Manual process: 10-15 seconds of active clicking and menu navigation per batch render.

Automated process: 2 seconds to trigger via Raycast, then immediate context switch.

For projects with multiple spot lengths (which happens weekly with broadcast clients), this saves 8-13 seconds per batch. But the real value is eliminating the "babysitting" phase. I no longer have to watch Resolve queue each timeline—I can immediately return to editing the next project, responding to client feedback, or setting up the next shoot.

At a conservative estimate of 10 batch renders per week (broadcast projects with 4-5 spot lengths), this saves 80-130 seconds of active time weekly (1.3-2.1 minutes). The headache reduction alone justifies the automation. No more "Did all the timelines get added?" or "Why is one missing from the queue?"

Implementation Notes

This script requires:

Use Case Comparison

Single Render Script (already documented): Used 100+ times per week for individual exports. Quick one-off renders for social media, client reviews, or single deliverables.

Batch Render Script (this one): Used weekly for broadcast projects requiring multiple spot lengths. When AirCo needs the same content as 30s, 15s, 6s, 5s, and 4s versions, this script handles all exports in one command.

The seq bin filtering is critical for my workflow. Because I only keep final deliverable sequences (and delete "best takes" assemblies after extracting clips), every timeline in the seq bin is guaranteed to be a finished spot. This script leverages that organizational discipline to automate the batch export without accidentally rendering work-in-progress content.

Error Handling

The script includes macOS notification alerts for failure states:

If a render fails to queue after 5 retry attempts, the script logs the failure and continues processing remaining timelines rather than halting the entire batch.

Why This Matters

This script doesn't just save seconds—it removes mental overhead. When I finish editing five spot lengths for a broadcast client, I don't have to context-switch into "render mode." I trigger the script, immediately move to the next project, and the exports happen in the background. The same notification system from my single-render workflow alerts me when all jobs complete.

For anyone working in commercial production where multiple spot lengths are standard deliverables, this automation pays for itself the first time you avoid manually selecting and queueing five timelines while a client is waiting on a call.