2DaVinci Resolve client wrapper.
4Provides a clean interface to the DaVinci Resolve API with proper error handling
9from typing
import Any, Dict, List, Optional, Union
11from .utils.platform
import setup_resolve_environment, check_resolve_running
14logger = logging.getLogger(__name__)
18 """Base exception for DaVinci Resolve related errors."""
23 """Raised when DaVinci Resolve is not running."""
28 """Raised when connection to DaVinci Resolve fails."""
34 A clean interface to the DaVinci Resolve API.
36 This class handles the connection to DaVinci Resolve and provides
37 organized methods for interacting with projects, timelines, media, etc.
47 """Connect to DaVinci Resolve."""
49 if not check_resolve_running():
51 "DaVinci Resolve is not running. Please start DaVinci Resolve first."
55 if not setup_resolve_environment():
57 "Failed to set up DaVinci Resolve environment variables."
62 import DaVinciResolveScript
as dvr_script
63 self.
_resolve = dvr_script.scriptapp(
"Resolve")
67 "Failed to get Resolve object. Check that DaVinci Resolve is running."
79 logger.info(f
"Connected to {self.get_version()}")
81 except ImportError
as e:
83 f
"Failed to import DaVinciResolveScript: {e}. "
84 "Check environment variables and DaVinci Resolve installation."
86 except Exception
as e:
90 """Disconnect from DaVinci Resolve."""
95 logger.info(
"Disconnected from DaVinci Resolve")
98 """Check if connected to DaVinci Resolve."""
102 """Ensure we're connected to Resolve."""
107 """Ensure we have a current project."""
121 """Get DaVinci Resolve version."""
124 return f
"{self._resolve.GetProductName()} {self._resolve.GetVersionString()}"
128 """Get the current page (Edit, Color, Fusion, etc.)."""
131 return self.
_resolve.GetCurrentPage()
135 """Switch to a specific page."""
138 valid_pages = [
'media',
'cut',
'edit',
'fusion',
'color',
'fairlight',
'deliver']
139 if page.lower()
not in valid_pages:
140 raise ValueError(f
"Invalid page. Must be one of: {', '.join(valid_pages)}")
143 return bool(self.
_resolve.OpenPage(page.lower()))
148 """List all projects in the current database."""
153 return [p
for p
in projects
if p]
157 """Get the name of the currently open project."""
160 return project.GetName()
161 except DaVinciResolveError:
165 """Open a project by name."""
173 if name
not in projects:
174 raise ValueError(f
"Project '{name}' not found. Available: {', '.join(projects)}")
179 logger.info(f
"Opened project: {name}")
184 """Create a new project."""
193 raise ValueError(f
"Project '{name}' already exists")
198 logger.info(f
"Created project: {name}")
204 """List all timelines in the current project."""
207 timeline_count = project.GetTimelineCount()
210 for i
in range(1, timeline_count + 1):
211 timeline = project.GetTimelineByIndex(i)
213 timelines.append(timeline.GetName())
218 """Get the name of the current timeline."""
221 current_timeline = project.GetCurrentTimeline()
222 return current_timeline.GetName()
if current_timeline
else None
223 except DaVinciResolveError:
227 """Create a new timeline."""
230 media_pool = project.GetMediaPool()
234 timeline = media_pool.CreateEmptyTimeline(name)
236 logger.info(f
"Created timeline: {name}")
242 """Switch to a timeline by name."""
246 timeline_count = project.GetTimelineCount()
247 for i
in range(1, timeline_count + 1):
248 timeline = project.GetTimelineByIndex(i)
249 if timeline
and timeline.GetName() == name:
250 result = project.SetCurrentTimeline(timeline)
252 logger.info(f
"Switched to timeline: {name}")
255 raise ValueError(f
"Timeline '{name}' not found")
259 """List all clips in the media pool root folder."""
262 media_pool = project.GetMediaPool()
266 root_folder = media_pool.GetRootFolder()
270 clips = root_folder.GetClipList()
277 "name": clip.GetName(),
278 "duration": clip.GetDuration(),
279 "fps": clip.GetClipProperty(
"FPS")
or "Unknown"
285 """Import a media file into the media pool."""
288 media_pool = project.GetMediaPool()
293 imported_clips = media_pool.ImportMedia([file_path])
296 logger.info(f
"Imported media: {file_path}")
Optional[str] get_current_timeline_name(self)
None _ensure_connected(self)
bool open_project(self, str name)
List[Dict[str, Any]] list_media_clips(self)
Optional[str] get_current_project_name(self)
str get_current_page(self)
bool create_timeline(self, str name)
Optional[Any] _current_project
Optional[Any] _project_manager
bool import_media(self, str file_path)
List[str] list_projects(self)
bool create_project(self, str name)
Any _ensure_project(self)
bool switch_timeline(self, str name)
bool switch_page(self, str page)
List[str] list_timelines(self)