Communitygithub.com

Moosphan/cinematic-shortfilm

Full production specifications and workflow for cinematic science short films (70-300 seconds)—script/voiceover (Qwen3-TTS VoiceDesign male voice), Remotion + Canvas particle/SVG visual system, code-composed soundtrack, external mixing and 4K delivery, fact-checking and release package. Load when making films like "A Brief History of Humankind: The Self-Portrait of the Universe" or "DESCENT", or when reusing their specifications.

What is cinematic-shortfilm?

This skill provides a complete, battle-tested production standard for creating cinematic, documentary-style science short films (70–300 seconds). It codifies the exact workflows, specifications, and lessons learned from two reference films: a 4K 4'58" space-themed piece and a 2K 1'30" ocean depth piece. The skill enforces a strict pipeline: voiceover generation (using Qwen3-TTS VoiceDesign for male, authoritative Chinese narration) must drive the timeline before any visuals are created. It details Remotion-based compositing with Canvas 2D particle systems and SVG graphics, a code-based music synthesis approach using numpy, and an external multi-step audio post-processing chain (EQ, compression, loudness normalization to -18 to -24 LUFS). It also includes critical rules for factual accuracy, visual clarity (text legibility, color palettes, transition types), and a rendering workflow that avoids common pitfalls like audio preprocessing hangs and particle box boundaries appearing as visible rectangles. The skill is designed for AI agent use on platforms like Claude Code, Cursor, or Codex, guiding users through script, audio, timeline, visual design, music, and final 4K delivery with a comprehensive troubleshooting record.

Works with~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Moosphan/hulk-skills/tree/HEAD/skills/cinematic-shortfilm

Ask in your favorite AI

Open a new chat with this agent skill pre-loaded.

Documentation

Cinematic Science Short Film · Unified Production Standard v1

Sources: "A Brief History of Humankind: The Self-Portrait of the Universe" (4K / 4'58" / 14 Scenes) and "DESCENT" (2K / 1'30" / 90-second vertical profile). The specifications, workflows, style, and pitfalls encountered for both films are all gathered here. Before starting a new film, first read Sections 0 and 1, then read the section relevant to the current project.


0. Hard Rules (Violating any will require a redo)

  1. Audio first, visuals second. Generate voiceover sentence by sentence → measure the duration → derive frame counts for each scene from the duration. Never lay out visuals before matching the audio.
  2. Voiceover and data must be consistent: Numbers, units, and magnitudes appearing in the film must be cross-referenced against a fact sheet line by line; if the voiceover says 98, the visuals cannot show 90. Unit errors (e.g., pressure atm ↔ t/m²) are ten times more serious than color mismatches.
  3. One shot, one piece of information. Each scene allows only one main thesis + a maximum of 3 readings; any additional information goes to the voiceover.
  4. Text must always be readable. Any text must have a background or darkened overlay underneath; layer names ≥ 30px, readings ≥ 13px. Small text opacity must not be less than 0.6.
  5. No hard cuts. Use dissolves / black-frame breathing / continuous motion between scenes; one film must use only one transition language.
  6. Silent rendering. In Remotion, always turn off <Audio> with {false && ...}. Audio is mixed in externally via ffmpeg (long WAV files can stall rendering at audio preprocessing).
  7. Render only after npx tsc --noEmit passes cleanly, otherwise you will render a lot of bad frames and have to redo them.
  8. Three checks before delivery: full length verification, first and last frame verification, and frame-by-frame verification of key transitions (3–6 frames each).

1. Standard Pipeline (In order, no skipping)

script.json ──► VO Generation ──► VO Post-processing ──► Duration Table ──► Timeline
                                   │
                                   └──► Music (numpy)──► Mixing ──► master.m4a
Visuals (Remotion)──► Silent Render ──► ffmpeg mux ──► Delivery

1.1 Script

  • One file per film: script.json, with fields id / act / text / caption.
  • Chinese voiceover ≈ 4.2 characters/second; a 60-second film ≈ 200–230 characters, a 90-second film ≈ 300–340 characters.
  • Write numbers in Chinese reading form (e.g., "three thousand six hundred eighty-eight"), otherwise the TTS may mispronounce them; use Arabic numerals in the visuals.

1.2 Voiceover (Qwen3-TTS VoiceDesign, male documentary voice)

INSTRUCT = ("A deep, calm, authoritative male documentary narrator. Slow, deliberate, cinematic. "
            "Low register, warm, intimate, restrained emotion, close-mic. Consistent, even pacing. Mandarin Chinese.")
generate_audio(text=..., model=model, lang_code="zh", instruct=INSTRUCT,
               temperature=0.65, top_p=0.9, repetition_penalty=1.05,
               output_path="vo_raw", file_prefix=id)
  • Model: mlx-community/Qwen3-TTS-12Hz-1.7B-VoiceDesign-bf16, fixed seed mx.random.seed(11).
  • Immediately after each generation, check duration with ffprobe: if a clip is > 30 seconds or has entire repeated sections, the TTS model has degraded; delete and regenerate (change the seed or raise repetition_penalty to 1.12).
  • ASR double-check: transcribe with mlx_whisper to verify numbers and uncommon characters (e.g., hydrogen→qing, silicon→gui, iron→ti).

1.3 Audio Post-processing (Fixed chain, no variations per clip)

highpass=f=70,
asetrate=24000*0.912341, aresample=48000, atempo=1.096081, atempo=1.055,
equalizer=f=190:t=q:w=1.0:g=1.4, equalizer=f=3300:t=q:w=1.4:g=-1.8, equalizer=f=7200:t=q:w=1.8:g=-1.0,
acompressor=threshold=0.14:ratio=2.2:attack=10:release=200,
loudnorm=I=-20:TP=-3:LRA=7

Then trim leading and trailing silence using a 20ms energy envelope, compress pauses longer than 0.34s down to 0.34s, and apply 12ms/50ms fade in/out at both ends.

1.4 Timeline

  • frames = round(seconds * 24); voiceover offset = scene start + lead (typically 18–24 frames).
  • Each scene: lead + vo + tail, tail 16–90 frames (generous for ending cards).
  • Generate timeline.ts (auto-generated, do not edit manually) with fields { id, from, dur, voAt, voDur }.

1.5 Music (Pure code synthesis, numpy)

  • Structure, don't blanket: write "events" by timecode, not a single pad throughout.
  • Harmony: change every 12–18 seconds, crossfade at boundaries; bass only in sustained tones above 55 Hz.
  • No low-frequency rumble: audiences will describe it as "booming" or "too noisy". Low cutoff at 85–100 Hz; long notes use pure sine waves without adding octave harmonics.
  • Prioritize quietness: music level ≈ voiceover −20 to −27 dB; when voiceover is present, further compress by 40–70% (sidechain ducking).
  • Final mix loudness: documentary −18 to −24 LUFS (not −14, which is for streaming pop music).
  • Tutorial-style "sound design" (e.g., underwater thuds, sonar pings, metallic creaks) only add when the client explicitly requests it; it was rejected once, so it's off by default.

1.6 Visuals (Remotion)

See Section 2.

1.7 Rendering and Muxing

npx tsc --noEmit
npx remotion render Film4K out/silent.mp4 --codec=h264 --crf=18 --concurrency=7
ffmpeg -i out/silent.mp4 -i public/audio/master.m4a \
  -map 0:v -map 1:a -c:v copy -c:a aac -b:a 320k -shortest -movflags +faststart out/final.mp4
  • 4K = 1920×1080 layout + transform: scale(2); 2K = scale(2560/1920). Write only one layout.
  • Partial rework: only re-render the affected frame range → ffmpeg trim/concat three segments → -c:v copy to replace only the audio track; if visuals change, re-encode and concatenate all three segments (about 5–10 minutes).

2. Visual System

2.1 Base Layer

  • Canvas 1920×1080, 24 fps; AbsoluteFill background near-black (#01050A / #010407), never pure black #000.
  • Three-layer structure: Background Gradient → Volumetric Light/Particles → Information Layer (text, depth scale, readings).
  • Uniform finishing: Vignette + static Grain (0.04, must be animate={false}; dynamic grain makes thin lines flicker).

2.2 Fonts

  • Titles/Poetry: Songti SC (serif), letter spacing 0.4–0.6em, large sizes (90–250px).
  • Data/Readings: SF Mono, 8–14px, letter spacing 0.16–0.36em.
  • Descriptions: PingFang SC, 14–19px, opacity 0.55–0.7.

2.3 Color Palette (Each film's own "world color")

Film TypeTop HighlightMidBottomAccent Color
Universe / Time#050506 baseCream #F3E7D0—Amber #E8B06A
Ocean / Depth#1E7C93 water surface#07232E#01050ACyan #4FE0C0

Rule: One film uses only one accent color; exceptions for bioluminescence/hydrothermal vents are limited to two, and each is tied to a specific physical quantity.

2.4 Particle Engine (Canvas 2D)

  • Deterministic random (hash), same result every frame; cloud types: ball / filament / disk / globe-surface / sphere-shell / figure / city / helix / neuron / glyph / single / text / timeline.
  • Two-pass drawing: first large radius, low opacity for glow; then small radius, high opacity for core; globalCompositeOperation = 'lighter'.
  • Point cloud boundaries must be outside the frame: makeCloud('text', n) creates a 3×1.2 box, which after projection results in rectangular edges (the most commonly reported bug by viewers). Use expand(cloud, kx, ky, kz) by 2.4–3.2 times.

2.5 Creatures and Terrain (SVG)

  • All in side view, head facing movement direction; at least 4 anatomical details (e.g., eyes, fins, mouth lines, throat folds, barnacles), otherwise it looks like a texture map.
  • Silhouette + rim light (0.2–0.35 opacity); do not use feTurbulence overlaid on the body (it will look like granite).
  • Terrain: multi-segment polylines + rock layers + debris + sediment, not triangles; mountains must not have a baseline (it would look like a chart).
  • Creature appearance windows tied to depth/time; don't show more than three types simultaneously.

2.6 Information Layer (HUD)

  • Zone nameplate: dark gradient background (0.72→0) + 2px accent color bar on the left + Chinese text 30–35px pure white.
  • Readings: 2–3 per layer, LABEL 8.5px / VALUE 13–14.5px.
  • Scale ruler: tick marks + bold current value; current value must be computed in real-time, not hardcoded (hardcoded values will conflict with pointers).
  • All numbers must include units; separate units with a space (e.g., 1,093 atm).

2.7 Transitions

  • First choice: continuous motion (one continuous shot): depth/time is a continuous quantity, content enters and exits the frame with it.
  • Second choice: short dissolve (4–6 frames, only the new shot fades in, the old shot remains opaque and is covered) — brightness doesn't collapse, HUD doesn't overlap text.
  • Disabled: diagonal wipes, long cross dissolves, vertical push (exposes dark edges), hard cuts after black (unless there's a physical motivation like "entering water").

3. Facts and Data

  • Create a facts.md file: each entry Number / Unit / Source Range / How to Write in the Film.
  • Three most error-prone areas: ① Unit conversion (1 atm ≈ 10.3 t/m² ≈ 1.03 kgf/cm²); ② Confusing "average" with "extreme" (average 3,688 m vs. deepest 10,935 m); ③ Simplifications (90 vs. 98 elements).
  • Use one consistent precise version throughout the film; voiceover and visuals must come from the same source.

4. Deliverables Checklist

deliverables/
  FilmTitle-4K-Voiceover.mp4           # Main version
  FilmTitle-4K-MusicOnly.mp4           # If needed
  Poster-4K.png / Preview-4K.png       # Keyframe composites
  Cover/                        # 1920 PNG + 4K PNG + 1146×717 JPG
  Director's Statement.md              # Structure, audio, revision history
  Publishing Copy-Bilibili.md          # Title/description/tags/pinned comment/cover suggestions
  FactSheet.md

The release package must include: AI-generated content declaration, production division of labor (what the model did, what the human did), and a pinned comment version of "easily misread numbers."


5. Pitfall Log (Sorted by Frequency)

SymptomRoot CauseFix
Rendering hangs at audio preprocessingLong WAV + <Audio>Silent render, external mux
Text blurry over particlesNo background + opacity 0.4–0.5Add background + pure white + increase font size
Visible rectangular shapes in frame (viewers' most common question)Point cloud box boundary enters frameexpand() by 2.4–3.2×
Thin lines / terrain flickersDynamic film grainGrain animate={false}
Whales/fish "swimming backward"Head and tail reversed, eye at tailSide-view reconstruction: head at +x
Terrain looks like a chartPath uses L ... Z with a horizontal baselineLower edge sinks outside frame
Transitions break line of sightWipes/long dissolvesShort dissolve or continuous motion
Music "booming"Continuous low drone at 27–80 HzHigh-pass at 85–100 Hz, remove sub drone
Audio-visual sync issuesVisual beat doesn't match voiceover contentRearrange depth/time curve based on voiceover content
Single TTS clip 600 secondsModel degradation loopDelete and regenerate, repetition_penalty 1.12
4K rework too slowFull film re-renderRe-render only affected frame range + concat

6. Location of the Two Reference Films

  • "A Brief History of Humankind: The Self-Portrait of the Universe": ~/dsh-video-remotion/film/src/scenes/*, 14 scenes, 4K, 4'58".
  • "DESCENT": ~/dsh-video-remotion/film/src/ocean/*, 6 depth zones, 2K, 1'30"; voiceover and music in ~/dsh-video-remotion/ocean/.
  • Both share src/engine/particles.tsx (particles), src/engine/atmos.tsx (Vignette/Grain), and src/theme.ts (fonts/color palette/easing).

Related Skills