render-notification-watcher
Render Notification Watcher: Tab Away While Rendering
DaVinci Resolve doesn't notify you when renders complete—you have to watch the progress bar or periodically check if the render finished. This script solves that by monitoring render jobs in the background and playing a custom sound when any render completes (Render Page, Quick Export, or Render in Place), allowing you to tab away to Slack, email, or other tasks while rendering happens in the background.
The Problem
I've automated the render trigger workflow extensively (Quick Export, Render TV Export, Batch Render)—one keystroke starts the render. But after triggering the render, I'm stuck waiting and watching the progress bar to know when it's done.
For short renders (15-30 second social spots), this isn't a big issue. But for longer renders (5-10 minute timelines, complex Fusion comps, high-bitrate ProRes exports), waiting 2-5 minutes while staring at a progress bar is wasted time.
I could tab away to Slack, start prepping the next timeline, or grab coffee. But if I tab away, I have no way of knowing when the render finishes without manually checking back. I end up:
- Tabbing to Slack to respond to messages
- Forgetting about the render for 3-4 minutes
- Tabbing back to Resolve to find the render finished 2 minutes ago
- Wasting 2 minutes I could have spent on the next task
Or worse:
- Staying in Resolve, watching the progress bar
- Not responding to Slack messages or starting the next task
- Waiting 3-5 minutes for the render to complete
- Feeling unproductive because I'm just waiting
Adobe After Effects solves this with a built-in render completion chime—when a render finishes, it plays a sound. You can tab away, work in Photoshop or Premiere, and when you hear the chime, you know to return to After Effects. It's a simple feature, but it fundamentally changes the render workflow from "wait and watch" to "tab away and multitask."
DaVinci Resolve doesn't have this. No sound, no notification, no alert when renders complete.
The Solution
render_notify.py is a background watcher script that monitors DaVinci Resolve's render jobs and plays a custom sound when any render completes. It handles:
- Render Page jobs (standard deliverables rendered via the Deliver page)
- Quick Export (fast preview renders to Downloads)
- Render in Place (Fusion/VST effect baking on the Edit page)
The workflow is now:
- Trigger a render (Quick Export, Render TV Export, etc.)
- Launch
render_notify.pyin a terminal (runs in the background) - Tab away to Slack, email, prep the next timeline, grab coffee
- Hear the custom sound when the render completes
- Tab back to Resolve and proceed with the next task
Total wasted time: 0 seconds. I can multitask during renders instead of watching progress bars.
Why This Matters More Than You'd Think
This script doesn't save time in the traditional sense—the render still takes 3-5 minutes. But it unlocks multitasking during that 3-5 minute window.
Before this script:
- Trigger render → wait and watch progress bar → render completes → start next task
- Productivity during render: 0%
After this script:
- Trigger render → tab to Slack/email/prep → hear chime → tab back to Resolve
- Productivity during render: 80-90%
At 5 renders per day (conservative for a busy production week), each taking 3-5 minutes, this unlocks 15-25 minutes of productive time daily that was previously spent watching progress bars.
But more importantly, it removes the mental overhead of "should I stay in Resolve or risk missing when the render finishes?" I just tab away, knowing the chime will alert me.
Technical Implementation
The script uses DaVinci Resolve's Python API to poll render job status every second and plays a sound file when a job completes.
1. Monitoring Render Page Jobs
The script tracks Render Page jobs (standard deliverables) by querying the job list:
jobs = project.GetRenderJobList()
if jobs:
for job in jobs:
job_id = job.get("JobId", "")
job_status = job.get("JobStatus", "")
timeline_name = job.get("TimelineName", "Unknown")
if job_status == "Complete":
job_key = f"{job_id}_{job_status}"
if job_key not in completed_jobs:
print(f"✓ Render Page Job Complete: {timeline_name}")
play_sound()
completed_jobs.add(job_key)
How this works:
GetRenderJobList()returns all jobs in the Render Page queue- Each job has a
JobId,JobStatus, andTimelineName - When a job's status changes to
"Complete", play the sound - Track completed jobs in a set to avoid playing the sound multiple times for the same job
Why track job_key instead of just job_id?
Jobs can have multiple status transitions (Queued → Rendering → Complete). By tracking job_id_Complete, the script ensures it only plays the sound once when the job reaches Complete, not every polling cycle afterward.
2. Monitoring Quick Export and Render in Place
Quick Export and Render in Place don't appear in the Render Page job list—they're handled differently by Resolve's API. To detect these, the script monitors the global IsRenderingInProgress() flag:
is_rendering = project.IsRenderingInProgress()
# Detect transition from rendering to not rendering
if previous_render_status is True and is_rendering is False:
print("✓ Render Complete (Quick Export or Render in Place detected)")
play_sound()
previous_render_status = is_rendering
How this works:
IsRenderingInProgress()returnsTrueif any render is active (Render Page, Quick Export, or Render in Place)- Track the previous polling cycle's status
- When
previous_render_status == Trueandis_rendering == False, a render just finished - Play the sound
Why this works for Quick Export:
When I trigger Quick Export via Raycast (using my Quick Export script), Resolve starts a background render. IsRenderingInProgress() becomes True. When the render finishes, it flips to False. The watcher script detects this transition and plays the sound.
This approach catches Quick Export and Render in Place jobs that don't show up in GetRenderJobList().
3. Playing the Custom Sound
The sound playback is handled by macOS's afplay command:
def play_sound():
sound_file = "/System/Library/Sounds/Glass.aiff"
subprocess.run(["afplay", sound_file])
afplay (Audio File Play) is a built-in macOS utility that plays audio files. The script defaults to the system "Glass" sound, but I can customize it by changing sound_file:
sound_file = "/Users/assistant2/custom_chime.mp3"
Why custom sounds matter:
Adobe After Effects has a built-in render chime, but it's locked to one sound. If you're working in After Effects and Premiere simultaneously, you hear the same chime for both and have to check which app finished rendering.
With this script, I can use a different sound per app or workflow:
- DaVinci Resolve: "Glass.aiff" (higher pitch)
- After Effects: Default AE chime (lower pitch)
- Fusion Studio: Custom "done.mp3"
When I hear the sound, I immediately know which app finished rendering without checking.
4. Polling Interval: 1 Second
The script checks render status every 1 second:
while True:
# Check render jobs and status
# ...
time.sleep(1)
Why 1 second instead of 5-10 seconds?
Faster polling means lower latency between render completion and sound notification. If I poll every 10 seconds and a render finishes 1 second after the last check, I wait 9 more seconds before hearing the chime.
At 1-second polling, the maximum delay is 1 second—essentially instant feedback.
Does 1-second polling impact performance?
No. The API calls (GetRenderJobList(), IsRenderingInProgress()) are lightweight—they query Resolve's internal state, not disk or network. Polling every second consumes negligible CPU on a modern Mac.
5. Continuous Monitoring Until Stopped
The script runs in an infinite loop (while True) until you manually stop it with Ctrl+C:
try:
while True:
# Monitor render jobs
time.sleep(1)
except KeyboardInterrupt:
print("\nMonitoring stopped")
This means the script stays active across multiple renders. I launch it once at the start of the workday, minimize the terminal, and it monitors every render until I stop it.
Use Cases
Primary: Background Monitoring During Long Renders
When rendering complex timelines (5-10 minute videos, Fusion-heavy comps, high-bitrate ProRes exports), I launch this script in a terminal and tab away to:
- Respond to Slack messages
- Answer emails
- Prep the next timeline for editing
- Grab coffee
The chime alerts me when the render finishes, and I tab back to Resolve to start the next task.
Secondary: Batch Rendering Overnight
When I queue 10-20 renders on the Render Page before leaving for the day, I launch this script and leave it running overnight. The next morning, I check the terminal output to see which jobs completed and which failed (the script prints job names and statuses).
This is less critical since I'm not at the computer overnight, but the terminal log provides a quick summary of "what happened while I was gone."
Why Not Just Use macOS Notifications?
I've experimented with macOS native notifications (osascript -e 'display notification "Render complete"'), but sounds are more effective for interrupting focus.
When I'm deep in Slack or email, I don't notice a silent notification banner in the corner of my screen. But a chime pulls me back to Resolve immediately.
Additionally, After Effects uses a chime (not a visual notification), so this script mimics that familiar workflow.
Comparison to After Effects Render Chime
After Effects has a built-in render chime that plays when compositions finish rendering. It's a small feature, but it fundamentally changes the render workflow:
| Feature | After Effects | DaVinci Resolve (Before Script) | DaVinci Resolve (With Script) |
|---|---|---|---|
| Render Notification | Built-in chime | None | Custom sound via script |
| Tab Away During Render | Yes (chime alerts you) | No (must watch progress bar) | Yes (chime alerts you) |
| Custom Sound | No (locked to AE chime) | N/A | Yes (any .aiff, .mp3, .wav) |
| Multi-App Rendering | Fixed sound per app | N/A | Custom sound per workflow |
The script brings DaVinci Resolve's render workflow up to par with After Effects while adding the customization AE lacks.
Time Savings (Unlocked Productivity)
Manual process (watching progress bar):
- Trigger render → stay in Resolve → watch progress bar → render completes (3-5 minutes) → start next task
- Productive time during render: 0%
Automated process (tab away with chime):
- Trigger render → launch watcher script → tab to Slack/email → hear chime → tab back (3-5 minutes)
- Productive time during render: 80-90%
Savings per render: 2.4-4.5 minutes of unlocked productivity (80-90% of a 3-5 minute render).
I render 5-10 times per day (Quick Exports, client deliverables, batch renders). At 5 renders per day averaging 4 minutes each, this unlocks 12-18 minutes of productive time daily or 60-90 minutes (1-1.5 hours) weekly.
But the real value is removing context paralysis: "Should I stay in Resolve or risk missing when the render finishes?" With the chime, I can confidently tab away and multitask.
Implementation Notes
This script requires:
- DaVinci Resolve (tested on Resolve 18/19)
- DaVinci Resolve Python API (included with Resolve installation)
- Python 3.x (pre-installed on macOS)
- Terminal (to run the script in the background)
Running the Script
To launch the watcher script:
- Open Terminal
- Run the script:
python3 /path/to/render_notify.py
- The script prints:
"Monitoring render jobs... Press Ctrl+C to stop monitoring" - Minimize the terminal and tab away—renders are now monitored
To stop monitoring, return to the terminal and press Ctrl+C.
Customizing the Sound
To use a custom sound file, edit line 26:
sound_file = "/System/Library/Sounds/Glass.aiff"
Replace with any .aiff, .mp3, or .wav file:
sound_file = "/Users/assistant2/custom_chime.mp3"
macOS ships with several system sounds in /System/Library/Sounds/:
Glass.aiff(sharp, crystalline chime)Hero.aiff(uplifting, triumphant)Ping.aiff(subtle notification)Submarine.aiff(deep sonar ping)
Try different sounds to find one that's distinct and noticeable without being jarring.
Auto-Launching at System Startup
To run the script automatically when you boot your Mac, create a launchd plist:
- Create
~/Library/LaunchAgents/com.user.render-notify.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.user.render-notify</string>
<key>ProgramArguments</key>
<array>
<string>/usr/bin/python3</string>
<string>/path/to/render_notify.py</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
- Load the agent:
launchctl load ~/Library/LaunchAgents/com.user.render-notify.plist
The script now runs automatically at login and monitors renders all day.
Why This Matters
This script doesn't reduce render time—a 5-minute render still takes 5 minutes. But it unlocks multitasking during that 5-minute window, turning "wasted waiting time" into productive work time.
For anyone rendering frequently (social content, client deliverables, Fusion comps), the ability to tab away and work on other tasks while rendering transforms the workflow. Instead of "render or work" (either/or), it's now "render and work" (both).
The custom sound is a small but critical detail. After Effects has a chime, but you can't customize it. If you're jumping between After Effects and DaVinci Resolve (common in motion graphics workflows), hearing the same chime for both apps forces you to check which one finished. With custom sounds, you know immediately which app to return to.
This script shows the power of filling gaps in software UX. DaVinci Resolve is an incredible NLE, but it lacks render notifications—a feature After Effects has had for years. The Python API is powerful enough to add this missing feature in ~90 lines of code. The script doesn't replace render automation—it complements it by handling the "what happens after I trigger the render" workflow.