Как разрезать клип в DaVinci Resolve через Python
SetCurrentTimecode, поиск клипа под кадром и split через горячую клавишу Resolve
Показываем практический способ разрезания клипа: найти элементы Timeline, которые пересекают нужный кадр, поставить playhead и выполнить штатный split в интерфейсе Resolve.
API
Resolve Scripting API
Язык
Python
Resolve
19–20+
Требуется
Запущенный Resolve
Синтаксис
result = api_method()Параметры
- • Параметры зависят от конкретного метода Resolve Scripting API и показаны в рабочем примере.
Возвращает
Возвращаемое значение нужно проверять перед следующим шагом автоматизации.
import os
import subprocess
import sys
import time
from pathlib import Path
def import_resolve_module():
try:
import DaVinciResolveScript as dvr
return dvr
except ImportError:
search_paths = [
os.environ.get("RESOLVE_SCRIPT_API", ""),
os.environ.get("RESOLVE_MODULES", ""),
r"C:\\ProgramData\\Blackmagic Design\\DaVinci Resolve\\Support\\Developer\\Scripting\\Modules",
"/opt/resolve/Developer/Scripting/Modules",
"/opt/BlackmagicDesign/DaVinciResolve/Developer/Scripting/Modules",
"/Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules",
str(Path.home() / "Library/Application Support/Blackmagic Design/DaVinci Resolve/Developer/Scripting/Modules"),
]
for path in search_paths:
if path and os.path.isdir(path) and path not in sys.path:
sys.path.append(path)
import DaVinciResolveScript as dvr
return dvr
def safe_call(obj, name, *args):
try:
fn = getattr(obj, name, None)
if callable(fn):
return fn(*args)
except Exception:
return None
return None
def frames_to_tc(frame: int, fps: float) -> str:
fps_i = max(1, int(round(fps)))
total = int(round(frame))
ff = total % fps_i
seconds = total // fps_i
hh = seconds // 3600
mm = (seconds % 3600) // 60
ss = seconds % 60
return f"{hh:02d}:{mm:02d}:{ss:02d}:{ff:02d}"
def get_timeline_fps(project, timeline) -> float:
value = safe_call(timeline, "GetSetting", "timelineFrameRate") or safe_call(project, "GetSetting", "timelineFrameRate")
try:
return float(value)
except Exception:
return 24.0
def iter_timeline_items(timeline):
for media_type in ("video", "audio"):
track_count = int(safe_call(timeline, "GetTrackCount", media_type) or 0)
for track_index in range(1, track_count + 1):
for item in safe_call(timeline, "GetItemListInTrack", media_type, track_index) or []:
yield item
def set_playhead(timeline, frame: int, fps: float) -> bool:
timecode = frames_to_tc(frame, fps)
if safe_call(timeline, "SetCurrentTimecode", timecode):
return True
if safe_call(timeline, "SetCurrentFrame", int(frame)):
return True
return False
def focus_resolve_window() -> bool:
if sys.platform.startswith("win"):
command = "$ws=New-Object -ComObject WScript.Shell; $null=$ws.AppActivate('DaVinci Resolve')"
subprocess.call(["powershell", "-NoProfile", "-Command", command], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
time.sleep(0.2)
return True
if sys.platform.startswith("linux"):
for needle in ("DaVinci Resolve", "resolve", "Blackmagic Design"):
for args in (("--name", needle), ("--class", needle)):
try:
output = subprocess.check_output(["xdotool", "search", *args], text=True).strip()
ids = [line for line in output.splitlines() if line.strip()]
if ids:
subprocess.call(["xdotool", "windowactivate", "--sync", ids[-1]], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
time.sleep(0.2)
return True
except Exception:
pass
raise RuntimeError("Окно DaVinci Resolve не найдено")
return True
def send_split_hotkey() -> bool:
focus_resolve_window()
if sys.platform.startswith("win"):
try:
import pyautogui
pyautogui.hotkey("ctrl", "b")
except Exception:
command = "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.SendKeys]::SendWait('^b')"
subprocess.call(["powershell", "-NoProfile", "-Command", command], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
time.sleep(0.15)
return True
if sys.platform.startswith("linux"):
subprocess.call(["xdotool", "key", "ctrl+b"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
time.sleep(0.15)
return True
raise RuntimeError("Split hotkey не реализован для этой платформы")
def split_at_frame(timeline, fps: float, frame: int) -> bool:
touching = []
for item in iter_timeline_items(timeline):
start = safe_call(item, "GetStart")
end = safe_call(item, "GetEnd")
if start is not None and end is not None and int(start) < frame < int(end):
touching.append(item)
if not touching:
return True
if not set_playhead(timeline, frame, fps):
return False
return send_split_hotkey()
dvr = import_resolve_module()
resolve = dvr.scriptapp("Resolve")
project = resolve.GetProjectManager().GetCurrentProject()
timeline = project.GetCurrentTimeline()
fps = get_timeline_fps(project, timeline)
if not split_at_frame(timeline, fps, frame=240):
raise RuntimeError("Не удалось разрезать клип")
print("Split completed")
Документация
Что делает пример
DaVinci Resolve Scripting API не во всех версиях дает прямой метод SplitClip. Поэтому практический bridge-подход использует доступный API для установки playhead, а сам разрез выполняет штатной командой интерфейса через Ctrl+B.
Почему сначала ищем клип под кадром
Если в заданном кадре нет клипа, split не нужен. Проверка диапазона защищает Timeline от лишних действий и позволяет спокойно запускать скрипт на списке кадров.
Ограничения подхода
Этот пример зависит от фокуса окна Resolve и системной отправки hotkey. На Linux нужен xdotool, на Windows используется pyautogui или PowerShell SendKeys.
Разбор примера
Подключение к Resolve
Пример начинает работу с подключения к запущенному DaVinci Resolve через официальный Python-модуль.
Проверка проекта
Перед вызовами Media Pool, Timeline или Render Queue код проверяет наличие открытого проекта.
Вызов метода API
Основной блок выполняет задачу статьи: как разрезать клип в davinci resolve через python.
Проверка результата
После вызова API результат проверяется, чтобы скрипт не продолжал работу с пустым объектом или не созданной задачей.
Особенности Resolve API
- Перед массовой нарезкой сделайте копию Timeline.
- На Linux установите xdotool, если используете этот способ.
- Горячая клавиша должна соответствовать команде Split Clip в Resolve.
- Это практический способ из автоматизации, а не отдельный официальный метод SplitClip.
Частые ошибки
Resolve API недоступен
Причина: Приложение не запущено или Python не видит DaVinciResolveScript.
Решение: Запустите Resolve и проверьте путь к Developer/Scripting/Modules.
Метод вернул None или False
Причина: В Resolve нет нужного проекта, Timeline, клипов, preset или доступа к папке.
Решение: Проверьте входные данные и добавьте явную проверку результата после каждого важного вызова API.
Скрипт работает только на одной машине
Причина: Пути к файлам или папкам Resolve зашиты под конкретную систему.
Решение: Вынесите пути в переменные и добавьте стандартные пути Windows, Linux и macOS.
Следующий шаг
Следующий шаг зависит от задачи: импорт медиа, создание Timeline или запуск рендера.
Связанные статьи API
Timeline
Как переместить playhead в DaVinci Resolve через Python API
Разбираем рабочий способ поставить playhead на конкретный кадр: сначала через SetCurrentTimecode, затем через SetCurrentFrame, если метод доступен в текущей версии Resolve.
Timeline
Как разблокировать дорожки Timeline через DaVinci Resolve Python API
Показываем рабочий служебный скрипт: пройти по всем видео- и аудиодорожкам активного Timeline, снять блокировку и включить дорожки перед дальнейшими операциями.
Timeline
Как удалить клипы с Timeline через DaVinci Resolve Python API
Показываем техническую часть удаления клипов: как найти элементы на активном Timeline и передать нужные TimelineItem в DeleteClips.

