Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from bundle
Build or revise a reusable FFmpeg timeline for short-form video editing. Use when the user wants an agent-editable API for trimming clips, cropping, fitting to
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/video_timeline_editor/domain/model.py
1from __future__ import annotations23from dataclasses import dataclass, field4from pathlib import Path5from typing import Any678@dataclass(frozen=True)9class MediaInfo:10duration: float11has_audio: bool121314@dataclass(frozen=True)15class CropBox:16x: float17y: float18width: float19height: float202122@dataclass(frozen=True)23class FitSpec:24mode: str = "contain"25anchor: str = "center"26background: str | None = "black"272829@dataclass(frozen=True)30class TransformSpec:31hflip: bool = False32vflip: bool = False33zoom: float = 1.034video_pts: float = 1.035audio_tempo: float = 1.036eq: dict[str, float] = field(default_factory=dict)373839@dataclass(frozen=True)40class OverlaySpec:41text: str42style: str = "default"43start: float | None = None44end: float | None = None45options: dict[str, Any] = field(default_factory=dict)464748@dataclass(frozen=True)49class CaptionTrack:50transcript: str | Path51style: str = "karaoke"52mode: str = "karaoke"53trim: str = "word"54max_words_per_cue: int = 455source_offset: float = 0.056replacements: dict[str, str] = field(default_factory=dict)57skip_tokens: tuple[str, ...] = ()585960@dataclass(frozen=True)61class Project:62width: int63height: int64fps: int65background: str66output: str | Path67work_dir: str | Path68open_after: bool = False69overlay_styles: dict[str, dict[str, Any]] = field(default_factory=dict)70caption_styles: dict[str, dict[str, Any]] = field(default_factory=dict)717273@dataclass(frozen=True)74class Clip:75id: str76source: str | Path77label: str78src_in: float | None = None79src_out: float | None = None80trim_start: float = 0.081trim_end: float = 0.082speed: float = 1.083fit: FitSpec = field(default_factory=FitSpec)84crop: CropBox | None = None85transform: TransformSpec = field(default_factory=TransformSpec)86overlays: tuple[OverlaySpec, ...] = ()87captions: CaptionTrack | None = None88muted: bool = False89volume: float = 1.0909192@dataclass(frozen=True)93class WordToken:94text: str95start: float96end: float979899@dataclass(frozen=True)100class ClipTiming:101nominal_in: float102nominal_out: float103actual_in: float104actual_out: float105video_time_scale: float106audio_time_scale: float107output_duration: float108word_aligned: bool = False109110111@dataclass(frozen=True)112class ClipAnalysis:113clip: Clip114source_path: Path115media: MediaInfo116timing: ClipTiming117caption_words: tuple[WordToken, ...] = ()118119