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

Как выставить разрешение рендера по клипам V1 через API

GetMediaPoolItem, GetClipProperty, SetSetting и ResolutionWidth/ResolutionHeight

Разбираем практический способ определить максимальное исходное разрешение клипов на V1 и передать его в настройки проекта и рендера.

API

Resolve Scripting API

Язык

Python

Resolve

19–20+

Требуется

Запущенный Resolve

Синтаксис

result = api_method()

Параметры

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

Возвращает

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

Полный рабочий пример Pythonкод можно использовать как основу скрипта
import os
import sys
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 = resolve.GetProjectManager()
    project = project_manager.GetCurrentProject() if project_manager else None
    if not project:
        raise RuntimeError("Нет открытого проекта DaVinci Resolve")

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

    return resolve, project, timeline

import re


def parse_resolution(value) -> tuple[int, int] | None:
    if value is None:
        return None
    match = re.search(r"(\\d{3,5})\\s*[xX×]\\s*(\\d{3,5})", str(value))
    if not match:
        return None
    width, height = int(match.group(1)), int(match.group(2))
    if width < 320 or height < 240:
        return None
    return width, height


def clip_resolution_from_media_pool_item(media_pool_item) -> tuple[int, int] | None:
    if not media_pool_item:
        return None
    for key in ("Resolution", "Video Resolution", "Frame Resolution", "Image Resolution", "Format"):
        parsed = parse_resolution(safe_call(media_pool_item, "GetClipProperty", key))
        if parsed:
            return parsed
    props = safe_call(media_pool_item, "GetClipProperty") or {}
    if isinstance(props, dict):
        for value in props.values():
            parsed = parse_resolution(value)
            if parsed:
                return parsed
    return None


def detect_v1_source_resolution(timeline) -> tuple[int, int] | None:
    candidates = []
    for item in safe_call(timeline, "GetItemListInTrack", "video", 1) or []:
        media_pool_item = safe_call(item, "GetMediaPoolItem")
        resolution = clip_resolution_from_media_pool_item(media_pool_item)
        if resolution:
            candidates.append(resolution)
    return max(candidates, key=lambda item: item[0] * item[1]) if candidates else None


def apply_project_resolution_from_v1(project, timeline) -> dict:
    detected = detect_v1_source_resolution(timeline)
    if not detected:
        return {"applied": False, "reason": "resolution_not_detected"}

    width, height = detected
    applied_width = safe_call(project, "SetSetting", "timelineResolutionWidth", str(width))
    applied_height = safe_call(project, "SetSetting", "timelineResolutionHeight", str(height))
    render_applied = safe_call(project, "SetRenderSettings", {"ResolutionWidth": width, "ResolutionHeight": height})

    return {"applied": bool(applied_width or applied_height or render_applied), "width": width, "height": height}


resolve, project, timeline = get_project_and_timeline()
print(apply_project_resolution_from_v1(project, timeline))

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

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

Скрипт проходит по клипам V1, получает MediaPoolItem каждого TimelineItem и читает свойства клипа. Из найденных разрешений выбирается самое большое по площади, после чего ширина и высота передаются в Project Settings и Render Settings.

Почему используется V1

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

Что делать, если разрешение не найдено

Resolve не всегда отдает одинаковые ключи свойств. Поэтому пример проверяет несколько названий и дополнительно проходит по значениям словаря GetClipProperty.

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

1

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

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

2

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

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

3

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

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

4

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

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

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

  • SetSetting может быть недоступен или отклонить значение в некоторых проектах.
  • Разрешение исходника не всегда равно желаемому разрешению финального мастера.
  • Проверяйте результат в Deliver page перед массовым использованием.
  • Для вертикальных видео логику выбора можно адаптировать под ориентацию проекта.

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

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

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

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

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

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

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

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

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

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

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

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

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