SuperAPI AI Directory

render-edl

General & other

View repository

Updated 10-15 21:54

About this skill

render-edl

Purpose

Execute an edl.json (Edit Decision List) into a finished master.mp4. The EDL encodes all creator-grammar decisions — clip order, pacing, transitions, audio mix, and captions — produced by generate-edit-decision-list. This atom is the assembly step: it reads the contract and renders it deterministically without any interactive prompts.

Supports both source modes:

  • conform (source.mode = "file") — trims ranges from existing video files.
  • generative (source.mode = "generate") — locates pre-rendered scene clips under <project_dir>/clips/<id>.mp4.

Inputs

  • edl (required) — path to edl.json. Must conform to the EDL schema (schema version 1.0).
  • output (required) — path for the output master.mp4.
  • project_dir (optional) — base directory for resolving relative asset paths. Defaults to meta.project_dir from the EDL; falls back to the directory containing edl.json.
  • crf (optional, default 18) — x264 quality setting; lower = higher quality.

Workflow

  1. Load and validate EDL — parse edl.json, check timeline is non-empty and contiguous (each clip's target_out == next clip's target_in within ±1 frame), confirm exactly one payoff-hold role, and that meta.target_duration is within ±0.5s of the last clip's target_out.
  2. Resolve and trim clips — for each timeline[] entry:
    • source.mode = "file": trim file from in to out with ffmpeg (re-encoded, frame-accurate).
    • source.mode = "generate": locate <project_dir>/clips/<id>.mp4; if missing, FAIL listing every missing asset.
  3. Apply speed — if speed != 1.0, apply setpts=PTS/<speed> (video) + chained atempo (audio).
  4. Apply motion — support zoom-punch (stepped crop/scale to the to zoom factor) and push-in (gradual zoompan from from to to). Null motion is a no-op.
  5. Normalise — scale every clip to 1080x1920 (9:16) or the appropriate resolution for meta.aspect at meta.fps.
  6. Concatenate — hard-cut concat of all processed clips using ffmpeg concat filter. Non-hard-cut transition_in values are treated as hard cuts in v1; a note is written to manifest.json.
  7. Build audio bed — mix audio.music + audio.vo + per-clip SFX (placed at sfx[].at on the master timeline) + apply each audio_beats[] silence-beat by muting music at at for dur seconds. When audio.ducking = "sidechain-20:1", compress music under VO with ffmpeg sidechaincompress.
  8. Burn captions — build an ASS subtitle file from all timeline[].captions[] cues using the preset from caption-style-presets.json. static-sentence holds the full cue; karaoke-pop renders per-word highlights by splitting the cue text into equal-time words. Falls back to grammar.caption_preset when a cue has no per-cue preset.
  9. Mux and deliver — combine video, audio, and subtitle tracks into output (master.mp4). Write manifest.json to the same directory, including a recomputed pacing_curve.

CLI:

python3 skills/atoms/assembly/render-edl/scripts/render_edl.py \
  --edl <edl.json> --output <master.mp4> [--project-dir <dir>] [--crf 18]

Output

  • master.mp4 — finished video at meta.fps, normalised resolution, with audio and burned captions.
  • manifest.json (sibling to master.mp4) — run metadata including:
    • skill_name, run_id, edl_path, output, created_at, duration_seconds
    • clips_rendered — per-clip records: id, source_mode, file (resolved path), duration, status
    • transitions_logged — list of non-hard-cut transition_in values treated as hard cuts
    • pacing_curve — recomputed mean_shot_len, cuts_per_10s, payoff_hold_ratio
    • status — pass | fail | needs human review
    • warnings, errors

Quality Checks

  • master.mp4 exists and is non-zero; ffprobe reports both video and audio streams.
  • Duration of master.mp4 is within ±0.5s of meta.target_duration.
  • Resolution matches the expected value for meta.aspect (1080×1920 for 9:16).
  • All caption cues are present in the ASS file with correct timing.
  • manifest.json exists with status: pass and all clips_rendered paths resolve on disk.
  • pacing_curve.payoff_hold_ratio is between 2.0 and 4.0 (warn if outside range, don't fail).

Failure Modes

  • EDL validation failure — non-contiguous timeline, missing payoff-hold, or target_duration mismatch; script exits with a clear message listing every violation.
  • Missing generate-mode clips — script fails immediately listing every <project_dir>/clips/<id>.mp4 that does not exist. Re-run after generating the missing clips.
  • Missing conform-mode source file — script exits with a clear error naming the file.
  • ffmpeg not installed — install via brew install ffmpeg or apt install ffmpeg.
  • No audio streams — if audio.music, audio.vo, and all SFX are null/absent, the master is produced with a silent audio track; a warning is written to the manifest.
  • Caption preset not found — if the cue's preset does not exist in caption-style-presets.json, the fallback preset platform-default is used and a warning is written.
  • Speed out of range — speed values < 0.1 or > 8.0 are rejected with a clear error.