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.

معلومات المصدر

المستودع
modelstudioai/skills
آخر نشاط في المصدر
١٥ يونيو ٢٠٢٦ في ٠٣:٣٧
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٥٨
التفرعات
٨

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
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).
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub