← Все статьи DaVinci Resolve API
DaVinci Resolve APIСреднийRender

Как задать In/Out Range для рендера через DaVinci Resolve Python API

SetInOutPoints, SetRenderRange и перевод кадров в таймкод для Deliver page

Рабочий пример показывает, как превратить диапазон кадров в таймкоды, выставить In/Out Points на Timeline и переключить рендер на In/Out Range.

API

Resolve Scripting API

Язык

Python

Resolve

19–20+

Требуется

Запущенный Resolve

Синтаксис

result = api_method()

Параметры

  • Параметры зависят от конкретного метода Resolve Scripting API и показаны в рабочем примере.

Возвращает

Возвращаемое значение нужно проверять перед следующим шагом автоматизации.

Полный рабочий пример Pythonкод можно использовать как основу скрипта
import os
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, **kwargs):
    try:
        fn = getattr(obj, name, None)
        if callable(fn):
            return fn(*args, **kwargs)
    except Exception:
        return None
    return None


def get_project_and_timeline():
    dvr = import_resolve_module()
    resolve = dvr.scriptapp("Resolve")
    if not resolve:
        raise RuntimeError("DaVinci Resolve API недоступен")

    project_manager = safe_call(resolve, "GetProjectManager")
    project = safe_call(project_manager, "GetCurrentProject") if project_manager else None
    if not project:
        raise RuntimeError("Нет открытого проекта DaVinci Resolve")

    timeline = safe_call(project, "GetCurrentTimeline")
    if not timeline:
        raise RuntimeError("Нет активного Timeline")

    return resolve, project, timeline


резервное получение значения_FPS = 24.0


def frames_to_tc(frame: int, fps: float):
    fps_i = int(round(fps)) or int(резервное получение значения_FPS)
    f = int(frame)
    hh = f // (fps_i * 3600)
    f %= fps_i * 3600
    mm = f // (fps_i * 60)
    f %= fps_i * 60
    ss = f // fps_i
    ff = f % fps_i
    return f"{hh:02d}:{mm:02d}:{ss:02d}:{ff:02d}"


def set_render_range_by_frames(project, timeline, start_frame: int, end_frame: int):
    if end_frame <= start_frame:
        raise ValueError("end_frame должен быть больше start_frame")

    try:
        fps = float(safe_call(project, "GetSetting", "timelineFrameRate") or резервное получение значения_FPS)
    except Exception:
        fps = резервное получение значения_FPS

    start_tc = frames_to_tc(start_frame, fps)
    end_tc = frames_to_tc(end_frame, fps)

    if not safe_call(timeline, "SetInOutPoints", start_tc, end_tc):
        raise RuntimeError("Timeline не принял In/Out Points")

    safe_call(project, "SetRenderRange", "In/Out Range")
    return start_tc, end_tc


resolve, project, timeline = get_project_and_timeline()
start_tc, end_tc = set_render_range_by_frames(project, timeline, 0, 240)
print("Render range:", start_tc, end_tc)

Документация

Что делает пример

Функция получает FPS проекта, переводит стартовый и конечный кадр в таймкод, выставляет In/Out Points на Timeline и сообщает Deliver page, что нужно рендерить In/Out Range.

Почему нужен таймкод

SetInOutPoints в Resolve принимает таймкоды, а не номера кадров. Поэтому при автоматизации диапазонов обычно нужен отдельный конвертер frames to timecode.

Как вернуться к полному рендеру

Для полного экспорта можно вызвать timeline.ClearInOutPoints() и project.SetRenderRange('Entire Timeline'). Это лучше делать явно, чтобы старые In/Out Points не влияли на следующий render job.

Разбор примера

1

Подключение к Resolve

Пример начинает работу с подключения к запущенному DaVinci Resolve через официальный Python-модуль.

2

Проверка проекта

Перед вызовами Media Pool, Timeline или Render Queue код проверяет наличие открытого проекта.

3

Вызов метода API

Основной блок выполняет задачу статьи: как задать in/out range для рендера через davinci resolve python api.

4

Проверка результата

После вызова API результат проверяется, чтобы скрипт не продолжал работу с пустым объектом или не созданной задачей.

Особенности Resolve API

  • end_frame должен быть больше start_frame.
  • FPS должен совпадать с Timeline, иначе диапазон будет смещен.
  • После частичного рендера очищайте In/Out Points перед полным экспортом.
  • Некоторые проекты со стартовым таймкодом требуют дополнительного учета базового кадра.

Частые ошибки

Resolve API недоступен

Причина: Приложение не запущено или Python не видит DaVinciResolveScript.

Решение: Запустите Resolve и проверьте путь к Developer/Scripting/Modules.

Метод вернул None или False

Причина: В Resolve нет нужного проекта, Timeline, клипов, preset или доступа к папке.

Решение: Проверьте входные данные и добавьте явную проверку результата после каждого важного вызова API.

Скрипт работает только на одной машине

Причина: Пути к файлам или папкам Resolve зашиты под конкретную систему.

Решение: Вынесите пути в переменные и добавьте стандартные пути Windows, Linux и macOS.

Следующий шаг

Следующий шаг зависит от задачи: импорт медиа, создание Timeline или запуск рендера.

Связанные статьи API