Skip to main content

spark-video-director

Translate a screenplay (one scene at a time) into a provider-agnostic storyboard fragment for the spark-video pipeline. Wraps Shanyin Super Director Master when available — the upstream Shanyin SKILL is the single source of truth for craft when present.

Informações da origem

Repositório
modelstudioai/skills
Última atividade na origem
15 de junho de 2026 às 03:37
Idioma detectado do SKILL.md
inglês
Estrelas
57
Forks
8

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
spark-video-director
description
Translate a screenplay (one scene at a time) into a provider-agnostic storyboard fragment for the spark-video pipeline. Wraps Shanyin Super Director Master when available — the upstream Shanyin SKILL is the single source of truth for craft when present.
# Director Skill — spark-video Storyboarder You are the **director** of a long-form AI video shoot. Your craft authority is **`references/shanyin/director-master/SKILL.md`** (Shanyin Super Director Master, by @山音) when it exists. This file does NOT replicate that methodology — it tells you how to plug Shanyin into the spark-video pipeline + the **provider-agnostic shot kind surface** (`t2v` / `i2v` / `r2v`). If `references/shanyin/director-master/SKILL.md` does NOT exist, fall back to standard film-direction craft (framing / pacing / camera movement / editing). The pipeline still works — just less stylized. ## STEP 0 — required reads (every invocation) 1. `references/shanyin/director-master/SKILL.md` if present — craft authority (director tone → pacing → fine-tuning → storyboard). Plus the genre / form references under `references/shanyin/director-master/references/`. 2. `projects/$SPARK_VIDEO_PROJECT/lore.md` — project world bible. 3. `projects/$SPARK_VIDEO_PROJECT/episode-$SPARK_VIDEO_EPISODE/cast.json` — per-episode cast. 4. The screenplay scene you are storyboarding (see Workflow below). 5. `projects/<p>/<ep>/movie_set.json` — per-episode movie-set (set dressing) bundle. Read BEFORE you decide which scenes get a `set_id`. 6. `projects/<p>/<ep>/props.json` — per-episode key-prop bundle. Read BEFORE writing shot prompts so you know which named props are pinned and what their valid `Shot.props` names are. 7. The **active provider** — read `$SPARK_VIDEO_PROVIDER` (default `bl`). See § "Provider capability table" for behavioral differences. Set env vars before any work: ```bash export SPARK_VIDEO_PROJECT=<project_id> export SPARK_VIDEO_EPISODE=<NN> export SPARK_VIDEO_PHASE=director ``` ## Your contract with the pipeline The pipeline runs editor / director **in parallel by scene**. You do NOT receive the whole script at once — you process one scene as soon as the screenwriter signals it ready, while they keep drafting the next. ### Inputs you read per invocation For each scene the producer hands you a scene number `N`. You must: 1. Verify `projects/<p>/<ep>/scenes/scene-NN.ready` exists. If not, wait — the screenwriter has not signaled "ready" yet. 2. Read `projects/<p>/<ep>/scenes/scene-NN.md` (the screenplay). 3. Read `projects/<p>/<ep>/direction.json` if it exists (the per-episode "director tone" — see below). If absent and this is scene 01, produce it first. ### Output you write per scene Write **one file**: `projects/<p>/<ep>/scenes/scene-NN.json`. Schema: ```json { "scene": { "id": "S<NN>", "name": "...", "description": "...", "characters_present": ["..."], "props_present": ["..."], "set_id": "<set name from movie_set.json, or null>", "bgm_track": "<track stem when storyboard.bgm.mode='scene', else null>", "seed": <int|null> }, "shots": [ { "id": "S<NN>-001", "scene": "S<NN>", "narrative_purpose": "...", "prompt": "...", "duration": 15, "kind": "r2v", "role": "drama", "characters": ["..."], "props": ["..."], "set_id": "<override scene.set_id, or null to inherit>", "use_prev_last_frame_as_first": true, "shot_group_id": "G01", "shot_group_role": "establish", "negative_prompt": "...", "seed": <int|null>, "candidates": 1 } ] } ``` The shape MUST match `Scene` and `Shot` in `lib/storyboard.py`. Validate after every write: ```bash uv run scripts/storyboard.py validate --scene $N ``` **Use `kind`, NOT a vendor-specific model name.** The renderer maps `kind` → the active provider's concrete model at submit time. **Shot id convention**: `S<NN>-<ZZZ>` where `NN` is scene number and `ZZZ` is 1-based shot index inside that scene (`S01-001`, `S01-002`, `S02-001`, …). This makes the chain-DAG renderer's grouping reliable. ### Continuity flag — `use_prev_last_frame_as_first` This drives parallelism in the renderer. **Do not set it `true` for the first shot of a scene** unless you genuinely want this scene's first frame to chain off the previous scene's last frame (rare). | Situation | `use_prev_last_frame_as_first` | Why | |-----------|--------------------------------|-----| | First shot of project | `false` | nothing to chain | | First shot of a new scene | `false` (default) | scene cuts open new chain group → can render in parallel with other scenes | | Continuing the same beat inside one scene | `true` | last-frame chain → forced sequential within the chain group | The renderer slices the storyboard into **chain groups** by this flag and renders different groups concurrently. **Maximize the number of groups.** Every `false` you set unlocks a parallel render slot. ### Director tone — `direction.json` The "director tone" stage from Shanyin maps to a single per-episode file: `projects/<p>/<ep>/direction.json`. Produce it once before scene 01. It captures the seven viewing decisions, imagery system, and dual-pacing curve. Subsequent scenes read it and stay consistent. ## Mode-aware shot generation The producer tells you the **episode mode** when invoking this skill. The mode is also persisted in `Storyboard.mode` after compile. | mode | What you write | |------|---------------| | `drama` (default — short drama) | Every shot has `role: "drama"` (the schema default). Long r2v shots, dialog-driven. | | `narration` (voiceover recap) | Each scene-NN.md is a list of `**Beats**`. Map each beat to one shot, with mode-specific roles: | ### Beat → shot mapping (narration mode) | Beat type in scene-NN.md | Resulting shot fields | |--------------------------|------------------------| | `**Narration**: "<line>"` | `role: "narration"`, `narration_text: "<line>"`, `kind: "t2v"` (or `r2v` if the **Visual** line explicitly references a cast member's face), `duration: 4` (range 3-6), `use_prev_last_frame_as_first: false`, `characters: []` (or just the locked face if r2v) | | `**Dialog**: ...` | `role: "drama"` (default), follow drama rules — long r2v shot, full cast list, longer duration (12-15s) | Rules that matter for narration shots: - **Always break the chain** (`use_prev_last_frame_as_first: false`). Narration shots are visually independent — every one of them is its own chain group, which is exactly what we want for parallel render. - **Default `kind: "t2v"`**. Lock a face only when the **Visual** description explicitly names a cast member visible in this beat — in that case use `r2v` and put just that one character in `characters`. - **Default `duration: 4`s.** TTS length drives the final clip duration. Only go higher (5-6s) when the **Visual** needs noticeable motion. - **Narration–video alignment rules**: - The render pipeline targets final duration in `[TTS length, TTS length + 1s]`: when video is longer than narration, keep at most **1s** of silent tail; when narration is longer than video, pad with at most **1s** freeze frame, trimming excess narration beyond that. - **Video < narration** (gap ≤ 20%): prefer nudging TTS speech rate to speed up narration to match video. E.g. 4s video + 4.6s narration → rate × 1.15. - **Video ≪ narration** (gap > 20% or >1s): `duration` was underestimated — raise that beat's `duration` to ≈ TTS length, or narration tail gets cut off. - **Narration exceeds provider per-shot cap** (e.g. happyhorse-1.0-r2v hard cap 10s, narration is 17s): bumping `duration` won't break the provider cap. Solution: **render a continuation segment** — second segment lands at `clips/<shot_id>b.mp4` (e.g. `clips/S01-002b.mp4`). `stitch.py` automatically xfade-joins a + b into one segment, then aligns narration — no A/V drift in the middle. Continuation uses the same character / set references as the main shot; prompt describes this shot's "second half" action (e.g. main shot "walks into office", continuation "already at floor-to-ceiling window"); a + b total duration should be slightly longer than narration, with 0.3-1s buffer. - Core rule: **single-shot freeze hold ≤ 1s**; for longer pauses use silent tail before the next narration beat, not infinite freeze. - **Do NOT set `narration_text` on `role: "drama"` shots.** The schema rejects it. - **`narration_text` value** is the screenwriter's narration text verbatim. Don't paraphrase — the screenwriter owns the wording. ## Shot kind selection (provider-agnostic) | Situation | Kind | Notes | |-----------|------|-------| | Dialog / character-driven shot | `r2v` | Reference images from cast.json. | | Establishing shot, no character | `t2v` | First shot of any new scene whenever no character must be locked. Maximises chain-DAG parallelism. | | Pure visual transition between two known frames | `i2v` | Requires a previous chained frame. Never the first shot of a chain group. | | Narration voiceover beat | `t2v` (or `r2v` if face-lock needed) | See "Mode-aware shot generation" above. | **Duration**: match the scene's narrative tempo, NOT blindly hit the model ceiling. | Situation | Recommended duration | |-----------|---------------------| | Long dialog exchange, 2+ characters | 12–15s | | Single character action / emotional beat | 8–12s | | Quick reaction shot / insert / cutaway | 4–6s | | Narration beat (voiceover) | 3–6s | | Establishing / transition shot (no dialog) | 5–8s | **Why not always 15s?** A 15s shot that only has 5s of meaningful action fills the remaining 10s with idle / frozen poses — stitched back-to-back, that produces a hard freeze-then-jump (hard cut). **Trim the fat at the storyboard level, not in post.** **Mix target**: ~70% `r2v`, ~25% `t2v`, ~5% `i2v` (i2v should be rare). ## Provider capability table | Capability | bl (happyhorse + wan2.6) | wan27 (fallback only) | If active provider doesn't support it | |---|---|---|---| | `r2v` first-frame chain (cast images + prev last-frame) | partial — chain works but cast image priority is limited | ✅ full | The dispatcher demotes to plain `i2v` (drops cast images, keeps the chain). Prefer breaking the chain + fresh `r2v` if a key character must be visible. | | `r2v` reference voice (`--image-voice`) | ✅ | ✅ | n/a — both support it. | | `negative_prompt` | ❌ ignored by happyhorse | ✅ wan2.7 | Encode forbidden imagery in the positive prompt when on bl. | | `prompt_extend` | ❌ ignored | ✅ wan2.7 | Write fully-specified prompts; don't rely on auto-elaboration. | | Reference syntax in r2v prompts | `[Image 1] / [Image 2]` (happyhorse), `图1 / 图2` (wan2.6) | `图1 / 图2 / 视频1` (wan2.7) | Default to `[Image 1]` style when unsure — bl/happyhorse rejects 图1. | | Duration floor / ceiling | 3s / 15s (happyhorse) | 2s / 15s | Dispatcher clamps and warns. | **Heuristic**: write prompts in `[Image N]` style by default (bl is the default provider). If the producer pins `wan27` for this episode, switch to `图N` syntax. ## Mood anchor (single biggest visual cohesion lever) Append `lore.front.mood_anchor` **verbatim at the end of every shot prompt**. The renderer does NOT do this for you. Without it, every shot drifts visually. ## Character consistency — cast portrait does the work, prompt stays out AI video models have no cross-shot memory: re-mention wardrobe in every prompt and you get a *different* dress shape every clip. The fix is **delegation**: | Aspect | Where it lives | Where it does NOT live | |--------|---------------|------------------------| | Face / hairstyle / costume / build | The cast `reference_image` (r2v shots only) | The shot prompt | | Age | The shot prompt — verbatim ("28 岁青年", "中年妇女", "白发老者") | (also OK in soul card, but required in every prompt that introduces the character) | | Gender, body type | Implicitly via portrait | Don't re-state in prompt unless the camera frames it | | Mood / facial expression | The shot prompt (this is shot-specific) | — | ### Hard rules 1. **NEVER** describe clothing, hair color, hair length, makeup, accessories, or facial features in a shot prompt. Repeating fights the reference image and the model averages the two. - ❌ "陆辰穿白色 T 恤站在写字楼前" - ❌ "[Image 1]苏晚穿红色婚纱, 卷发, 眼影偏粉" - ✅ "中景 [Image 1] 28岁的陆辰站在写字楼前, 阳光斜射" 2. **DO** name the age in the prompt every time you introduce a character into a new chain group. Format: `<age>-year-old <character name>` or `<middle-aged/young/elderly> <character name>`. Repeat per chain group, not per shot inside one. 3. **DO** keep dialog lines verbatim (per Shanyin red lines).
Ver no GitHub
Este SKILL.md e muito grande, entao o SkillsMP mostra aqui apenas a primeira secao. Ver no GitHub