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

Как рассчитать видимые участки V1 с учетом перекрытий V2

GetItemListInTrack, интервалы клипов и геометрия Timeline по дорожкам Timeline

Показываем технический расчет видимых сегментов клипов V1, если часть основного видео перекрыта клипами на V2.

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 = 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


def subtract_intervals(base_start: int, base_end: int, blockers: list[tuple[int, int]]) -> list[tuple[int, int]]:
    segments = [(base_start, base_end)]
    for block_start, block_end in blockers:
        next_segments = []
        for start, end in segments:
            if block_end <= start or block_start >= end:
                next_segments.append((start, end))
                continue
            if block_start > start:
                next_segments.append((start, min(block_start, end)))
            if block_end < end:
                next_segments.append((max(block_end, start), end))
        segments = next_segments
    return [(start, end) for start, end in segments if end > start]


def visible_v1_segments(timeline) -> list[dict]:
    v1_items = safe_call(timeline, "GetItemListInTrack", "video", 1) or []
    v2_items = safe_call(timeline, "GetItemListInTrack", "video", 2) or []
    blockers = [(int(safe_call(item, "GetStart") or 0), int(safe_call(item, "GetEnd") or 0)) for item in v2_items]

    result = []
    for item in v1_items:
        start = int(safe_call(item, "GetStart") or 0)
        end = int(safe_call(item, "GetEnd") or start)
        for visible_start, visible_end in subtract_intervals(start, end, blockers):
            result.append({
                "clip": safe_call(item, "GetName") or "",
                "visible_start": visible_start,
                "visible_end": visible_end,
                "duration": visible_end - visible_start,
            })
    return result


resolve, project, timeline = get_project_and_timeline()
for segment in visible_v1_segments(timeline):
    print(segment)

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

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

Код берет клипы V1 и V2, считает интервалы перекрытия и возвращает только те участки V1, которые не закрыты клипами V2.

Особенности реализации

Пример использует стандартные возможности Resolve Scripting API и данные текущей Timeline.

Где применять

Расчет полезен для технических отчетов, проверки overlay-монтажа, контроля длительности видимых участков и подготовки вспомогательных workflow.

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

1

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

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

2

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

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

3

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

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

4

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

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

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

  • Пример учитывает только V2 как перекрывающую дорожку.
  • Для V3 и выше добавьте их интервалы в blockers.
  • GetStart и GetEnd работают в кадрах.
  • Если нужны секунды, разделите кадры на FPS Timeline.

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

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

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

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

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

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

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

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

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

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

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

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

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