A semantic video search plugin for DaVinci Resolve that allows you to search through your media pool using natural language queries and automatically add matching clips to your timeline.
- Semantic Video Search: Search your media pool using natural language (e.g., "woman walking", "car driving"), scoped to the current Resolve project
- Video Preview & Trim: Preview search results with a built-in video player and trim in/out points before inserting
- Smart Upload Management: Track which files have been processed and upload only new files. Content-based file hashing ensures videos are identified consistently regardless of file path
- Non-blocking Networking: All HTTP I/O (upload, search, job polling) runs on Qt's event loop via
QNetworkAccessManager— no threads, no UI freezes, fully compatible with Resolve's fuscript.exe - Project-scoped Search: Search results are filtered by the current Resolve project using
GetUniqueId()(Resolve 18.0b3+), so each project's media stays separate - Quota Tracking: Upload responses include vector count and quota info, displayed in the status bar
- Background Job Tracking: Monitor upload and processing jobs with real-time status updates
- Timeline Integration: Add search results directly to your timeline with precise timing
- Python 3.11.12 (3.12+ not supported by Resolve)
- uv (recommended) or pip
- DaVinci Resolve Studio (paid version required for scripting support)
# From repository root
uv syncSet these before running the plugin:
# Required for authentication
export CLIPABIT_AUTH0_DOMAIN="your-tenant.auth0.com"
export CLIPABIT_AUTH0_CLIENT_ID="your_client_id"
export CLIPABIT_AUTH0_AUDIENCE="https://api.clipabit.com"
# Optional runtime mode flags
export CLIPABIT_ENVIRONMENT="dev" # dev (default), staging, prodOn Windows PowerShell:
$env:CLIPABIT_AUTH0_DOMAIN = "your-tenant.auth0.com"
$env:CLIPABIT_AUTH0_CLIENT_ID = "your_client_id"
$env:CLIPABIT_AUTH0_AUDIENCE = "https://api.clipabit.com"
$env:CLIPABIT_ENVIRONMENT = "dev"You can also use a .env file. The plugin auto-loads .env values at startup (without overwriting already-exported variables). It looks in:
- current working directory
- parent directories of the installed module path
- Resolve utility script folder (
Fusion/Scripts/Utility/.env) when running inside Resolve ~/.clipabit/.env
You can force a specific file with CLIPABIT_ENV_FILE=/absolute/path/to/.env.
You can preview the UI without DaVinci Resolve:
# From repository root
uv run python clipabit.pyWhen running outside Resolve, you'll see Resolve API not available. That is expected.
Move both:
- the shim (
clipabit.py) intoFusion/Scripts/Utility/asClipABit.py - the package (
clipabit/) intoFusion/Modules/clipabit
macOS:
FUSION_DIR="$HOME/Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion"
mkdir -p "$FUSION_DIR/Scripts/Utility" "$FUSION_DIR/Modules"
cp "clipabit.py" "$FUSION_DIR/Scripts/Utility/ClipABit.py"
rm -rf "$FUSION_DIR/Modules/clipabit"
cp -R "clipabit" "$FUSION_DIR/Modules/clipabit"Windows (PowerShell):
$fusionDir = Join-Path $env:APPDATA "Blackmagic Design\DaVinci Resolve\Support\Fusion"
New-Item -ItemType Directory -Path "$fusionDir\Scripts\Utility" -Force | Out-Null
New-Item -ItemType Directory -Path "$fusionDir\Modules" -Force | Out-Null
Copy-Item ".\clipabit.py" "$fusionDir\Scripts\Utility\ClipABit.py" -Force
Remove-Item "$fusionDir\Modules\clipabit" -Recurse -Force -ErrorAction SilentlyContinue
Copy-Item ".\clipabit" "$fusionDir\Modules\clipabit" -Recurse -ForceLinux:
FUSION_DIR="$HOME/.local/share/DaVinci Resolve/Fusion"
mkdir -p "$FUSION_DIR/Scripts/Utility" "$FUSION_DIR/Modules"
cp "clipabit.py" "$FUSION_DIR/Scripts/Utility/ClipABit.py"
rm -rf "$FUSION_DIR/Modules/clipabit"
cp -R "clipabit" "$FUSION_DIR/Modules/clipabit"- Open DaVinci Resolve
- Open or create a project
- Navigate to: Workspace → Scripts → Utility → ClipABit
- The plugin window will open
# 1. Make changes in clipabit.py and/or clipabit/
# 2. Run to preview
uv run python clipabit.py
# 3. Close the window (Cmd+Q) and re-run to see new changes
# 4. Sync to Resolve (see install commands above)For automatic sync during development:
# From the repository root
uv run python watch_clipabit.py --source .This watches the plugin source and syncs both:
clipabit.pytoFusion/Scripts/Utility/ClipABit.pyclipabit/toFusion/Modules/clipabit
- Enter a natural language query in the search box (e.g., "person walking", "sunset scene")
- Press Enter to search
- Browse the results in the grid view (thumbnails load asynchronously)
- Click Preview & Trim on any result to open the video preview dialog
- Adjust the trim range with the dual-handle slider, then click Insert to Timeline
- Click the Media Pool button in the header
- Click Select Files to Upload to choose clips from your media pool
- Monitor progress via the i (info) button in the header
| Variable | Required | Default | Notes |
|---|---|---|---|
CLIPABIT_AUTH0_DOMAIN |
Yes (for sign-in) | none | Auth0 tenant domain |
CLIPABIT_AUTH0_CLIENT_ID |
Yes (for sign-in) | none | Auth0 application client ID |
CLIPABIT_AUTH0_AUDIENCE |
Yes (for sign-in) | none | API audience used in token requests |
CLIPABIT_ENVIRONMENT |
No | dev |
dev, staging, prod |
CLIPABIT_SERVER_URL |
No | auto (from environment) | Override base URL for upload/status endpoints |
CLIPABIT_SEARCH_URL |
No | auto (from environment) | Override base URL for search endpoint |
CLIPABIT_DEV_NAME |
No | dev |
Dev server name prefix (dev environment only) |
| Platform | Utility Script Path | Modules Path |
|---|---|---|
| macOS | ~/Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Scripts/Utility/ClipABit.py |
~/Library/Application Support/Blackmagic Design/DaVinci Resolve/Fusion/Modules/clipabit/ |
| Windows | %APPDATA%\Blackmagic Design\DaVinci Resolve\Support\Fusion\Scripts\Utility\ClipABit.py |
%APPDATA%\Blackmagic Design\DaVinci Resolve\Support\Fusion\Modules\clipabit\ |
| Linux | ~/.local/share/DaVinci Resolve/Fusion/Scripts/Utility/ClipABit.py |
~/.local/share/DaVinci Resolve/Fusion/Modules/clipabit/ |
- Pushes to
stagingrun semantic-release automatically. - Tags are created as
vX.Y.Z-staging.N. CHANGELOG.mdandpyproject.tomlare updated.
- Use GitHub Actions workflow Promote staging to main.
- It asks for release type (
patch,minor,major). - It merges
staging→main, then runs semantic-release onmainwith the chosen release type.
- Run Permissions Probe workflow to verify whether
GITHUB_TOKENhas write access. - If it fails, org-level settings likely block write permissions.
- Likely cause: You're using the free version of DaVinci Resolve
- Solution: Scripting requires DaVinci Resolve Studio ($295)
- This is normal when running standalone (outside of Resolve)
- The UI will still work, but media pool features are disabled
- Restart DaVinci Resolve completely
- Confirm both targets exist:
Fusion/Scripts/Utility/ClipABit.pyandFusion/Modules/clipabit/ - Check Preferences → System → External scripting using is set to Local
- Set
CLIPABIT_AUTH0_DOMAIN,CLIPABIT_AUTH0_CLIENT_ID, andCLIPABIT_AUTH0_AUDIENCE - Or create a
.envfile in one of the auto-loaded locations listed above
.
├── clipabit.py # Resolve shim / standalone entry point
├── clipabit/ # Main plugin package (sync to Fusion/Modules/clipabit)
│ ├── api/ # Auth (PKCE login, token storage) and backend config
│ ├── core/ # NetworkClient (QNAM), FileUploader, JobTracker, file utilities
│ ├── ui/ # PyQt6 application UI (main window, video preview, theme)
│ └── assets/ # UI assets (logos, icons)
├── watch_clipabit.py # Development sync watcher (shim + package)
├── scripts/ # Release and auth utility scripts
├── pyproject.toml # Project dependencies
├── uv.lock # Dependency lock file
└── README.md # This file
- PyQt6 Interface: Dark-themed UI with non-blocking networking via
QNetworkAccessManager - No Threads: All HTTP calls (upload, search, job polling) run on Qt's event loop — safe inside Resolve's fuscript.exe which crashes on
QThread.start() - Modal.com Backend: Serverless video processing with per-user Pinecone namespaces
- Pinecone Vector Database: Semantic search with CLIP embeddings, scoped by project via
project_idmetadata filtering - Content-based Identification: Videos are identified by SHA-256 hash of file content (
hashed_identifier), ensuring consistent identification across file moves/renames - Local Storage: Minimal
processed_files.jsontracks uploaded files with filename, filepath, namespace, hashed_identifier, vector_count, and timestamp
- Plugin computes
hashed_identifier(SHA-256 of file content, 8MB chunked reads) - Retrieves
project_idfrom Resolve'sGetUniqueId()(falls back to project name hash) - Sends file +
namespace+hashed_identifier+project_idto backend - Backend assigns namespace based on user identity, stores vectors with
project_idmetadata - Upload response includes
vector_count/vector_quotafor quota display
- Plugin sends query +
namespace+project_idto search endpoint - Backend filters Pinecone results by
project_idso results are scoped to the current Resolve project - Results include video file paths and timestamp ranges for timeline insertion