← Все статьи DaVinci Resolve API
DaVinci Resolve APIПродвинутыйRender

Полный пайплайн рендера DaVinci Resolve через Python API

Project, Timeline, очистка очереди, настройки MOV H.265, AddRenderJob, StartRendering и проверка файла

Финальный пример объединяет стандартные вызовы Resolve API в один рабочий сценарий: подготовить рендер, создать job, запустить его, дождаться завершения и вернуть путь к файлу.

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


from datetime import datetime


def render_current_timeline(output_dir: Path):
    resolve, project, timeline = get_project_and_timeline()
    output_dir.mkdir(parents=True, exist_ok=True)

    project_name = (safe_call(project, "GetName") or "Project").strip().replace(" ", "_")
    timeline_name = (safe_call(timeline, "GetName") or "Timeline").strip().replace(" ", "_")
    base_name = f"{project_name}_{timeline_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}"

    safe_call(project, "StopRendering")
    safe_call(timeline, "ClearInOutPoints")
    safe_call(project, "SetRenderRange", "Entire Timeline")
    safe_call(project, "SetRenderSettings", {
        "TargetDir": str(output_dir),
        "CustomName": base_name,
        "ExportVideo": True,
        "ExportAudio": True,
        "IndividualClips": False,
        "UniqueFilenames": True,
        "Format": "mov",
        "AudioCodec": "AAC",
        "AudioBitrate": 320000,
        "AudioSampleRate": 48000,
    })

    for codec in ["H.265", "H265", "HEVC"]:
        if safe_call(project, "SetRenderSettings", {"VideoCodec": codec}):
            break

    job_id = safe_call(project, "AddRenderJob")
    if not job_id:
        raise RuntimeError("AddRenderJob не создал задание")

    if not safe_call(project, "StartRendering", [job_id]):
        if not safe_call(project, "StartRendering", job_id):
            raise RuntimeError("StartRendering не запустил render job")

    while safe_call(project, "IsRenderingInProgress"):
        time.sleep(1.0)

    status = safe_call(project, "GetRenderJobStatus", job_id) or {}
    files = sorted(
        [path for path in output_dir.glob(f"{base_name}*") if path.is_file()],
        key=lambda path: path.stat().st_mtime,
        reverse=True,
    )
    return {
        "job_id": str(job_id),
        "status": status,
        "output_path": str(files[0]) if files else "",
    }


result = render_current_timeline(Path.home() / "Resolve_API_Render")
print(result)

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

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

Это цельный минимальный пайплайн финального рендера: получить активный проект и Timeline, остановить возможный старый рендер, сбросить In/Out, настроить экспорт, создать Render Job, запустить его и дождаться результата.

Что показывает пример

В коде используются только стандартные вызовы Resolve Scripting API: загрузка пресета, настройка Render Settings, создание Render Job и запуск экспорта.

Как развивать дальше

На основе этого шаблона можно добавить выбор диапазона, загрузку пользовательского пресета, настройку разрешения по исходникам V1 и более подробный прогресс для интерфейса.

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

1

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

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

2

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

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

3

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

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

4

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

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

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

  • Перед использованием проверьте доступность нужного кодека на вашей системе.
  • Если StartRendering со списком job id не сработал, пример пробует запуск по одному id.
  • Файл ищется по base name, потому что Resolve может добавить расширение или суффикс.
  • Для production-использования добавьте обработку старой очереди через clear_render_queue.

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

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

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

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

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

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

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

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

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

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

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

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

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