Skip to content

JinLee794/Showrunner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Showrunner

Your AI crew's cinematographer. Send a storyboard JSON, get back an MP4 with spring-based motion, animated charts, and professional pacing.

MCP stdio for local dev  ·  MCP HTTP for Azure  ·  same tools, same storyboard

📖 Browse the Scene Catalog — animated GIF previews, data schemas, and sample JSON for every scene type


Showrunner showcase video
▶ Click for full video

No Remotion. No subscription. No framework lock-in. Just Playwright frames, GSAP timelines, D3 charts, and ffmpeg encoding.

How It Works

AI Agent ──▶ storyboard JSON ──▶ Showrunner MCP Server
                                        │
                                   Zod validate
                                   ├── invalid → errors array
                                   └── valid ──▶ Assemble page per scene
                                                  ├── Theme CSS
                                                  ├── Scene HTML (Handlebars)
                                                  ├── GSAP bundle
                                                  └── D3 bundle
                                                         │
                                               Playwright (headless Chromium)
                                                         │
                                                    Scene type?
                                               ┌─────────┴─────────┐
                                          chart scenes        other scenes
                                          D3 builds SVG     Static HTML layout
                                               └─────────┬─────────┘
                                                  GSAP timeline (paused)
                                                         │
                                                  seek(0..1) per frame
                                                  Frame capture loop
                                                         │
                                                    ffmpeg encode
                                                         │
                                                   Output target
                                               ┌─────────┴─────────┐
                                             local              Azure
                                           File path          Blob URL

Each scene template builds a paused GSAP timeline. Chart scenes (chart-bar, chart-line, chart-donut) use D3 to construct SVG elements (scales, axes, paths, arcs) then hand off to GSAP for animation. The renderer scrubs .progress(0..1) for every frame, screenshots, and encodes. Deterministic — same input always produces the same frames.

Prerequisites

  • Node.js ≥ 20
  • ffmpeg on PATH
  • Playwright Chromium (auto-installed on first run)

Install

This package is published to GitHub Packages. Configure npm to use it:

# One-time setup: tell npm where to find @jinlee794 packages
echo "@jinlee794:registry=https://npm.pkg.github.com" >> ~/.npmrc

# Authenticate (use a GitHub PAT with read:packages scope)
npm login --registry=https://npm.pkg.github.com

# Install globally
npm install -g @jinlee794/showrunner-mcp

# Or run directly via npx
npx @jinlee794/showrunner-mcp --help

Quick Start

Use via npx (recommended)

# Render a storyboard to MP4
npx @jinlee794/showrunner-mcp render storyboard.json

# Render with options
npx @jinlee794/showrunner-mcp render storyboard.json --quality high --output output/final.mp4

# Render to GIF
npx @jinlee794/showrunner-mcp render storyboard.json --gif

# Validate a storyboard without rendering
npx @jinlee794/showrunner-mcp validate storyboard.json

# List available scene types
npx @jinlee794/showrunner-mcp scenes

Use from source

# Clone and install
git clone https://github.com/JinLee794/Showrunner.git
cd Showrunner
npm install

# Build
npm run build

# Render the demo storyboard
npx showrunner render fixtures/demo-storyboard.json

Showrunner MCP Server

stdio (local dev)

npx @jinlee794/showrunner-mcp

Agent config (VS Code / Claude Desktop / any MCP client):

{
  "mcpServers": {
    "showrunner": {
      "command": "npx",
      "args": ["-y", "@jinlee794/showrunner-mcp"],
      "env": {
        "npm_config_@jinlee794:registry": "https://npm.pkg.github.com"
      }
    }
  }
}

HTTP (remote / Azure)

TRANSPORT=http PORT=8080 npx @jinlee794/showrunner-mcp

Agent config:

{
  "mcpServers": {
    "showrunner": {
      "url": "https://<your-host>/mcp",
      "transport": "http"
    }
  }
}

Tools

Tool Description Returns
render_video Render a full storyboard to MP4 (with optional muxed voice-over + VTT transcript) { path, duration, frames, fileSize, transcriptPath?, narration? }
render_gif Render a storyboard to animated GIF with speed/size control { path, duration, frames, fileSize }
render_scene Render a single scene to MP4/GIF { path }
preview_storyboard Generate interactive HTML preview (no Playwright/ffmpeg) { path }
validate_storyboard Dry-run validation with error reporting { valid, errors?, summary? }
list_scene_types Dynamically list available scene types + themes from the current install { sceneTypes: Array<{ type, description, dataSchema }>, themes: string[] }
synthesize_narration Azure Speech TTS → MP3 + VTT/SRT transcript (no video) { audioPath, transcriptPath, durationSec, scenes[] }

Scene Types

See the full Scene Catalog → for animated GIF previews, detailed data schemas, and copy-paste sample JSON for every scene type.

Type Description
title-card Full-screen branded intro with logo, title, subtitle
section-header Transition slide between sections
pipeline-funnel Horizontal bars with staggered spring animation + count-up values
milestone-timeline Vertical timeline with status dots and owner labels
risk-callout Cards with severity stripes and context text
action-items Numbered checklist with priority indicators
deal-team Avatar grid with role labels
kpi-scorecard 2×2 / 3×2 KPI cards with count-up and trend arrows
chart-bar Animated bar chart with staggered spring
chart-line SVG path draw-on line chart
chart-donut Clockwise-fill donut with center count-up
table Animated row-by-row table
quote-highlight Quote with word-by-word reveal and sentiment accent
comparison Side-by-side comparison with alternating slide-in
closing Branded outro with tagline and CTA
code-terminal Typing terminal with prompt/output/success lines
image-card Full-bleed image with caption overlay and Ken Burns effects
bullet-list Animated bullet list with icons, sub-text, and highlights
stat-counter Big count-up numbers with progress bars and change indicators
text-reveal Cinematic text with typewriter, word-reveal, and highlight effects

Storyboard Schema

{
  "title": "Q2 Pipeline Review",
  "theme": "corporate-dark",
  "fps": 30,
  "resolution": [1920, 1080],
  "scenes": [
    {
      "type": "title-card",
      "duration": 4,
      "transition": "fade",
      "data": {
        "title": "Q2 Pipeline Review",
        "subtitle": "Enterprise Accounts",
        "date": "April 2026"
      }
    },
    {
      "type": "kpi-scorecard",
      "duration": 6,
      "transition": "fade",
      "data": {
        "kpis": [
          { "label": "Pipeline", "value": 28400000, "unit": "$", "trend": "up", "animateCount": true },
          { "label": "Win Rate", "value": 34, "unit": "%", "trend": "up", "animateCount": true }
        ]
      }
    },
    {
      "type": "closing",
      "duration": 3,
      "transition": "fade",
      "data": { "tagline": "Generated by AI" }
    }
  ]
}

See fixtures/sample-storyboard.json and fixtures/demo-storyboard.json for full examples.

Voice-over & Transcripts (Azure Speech)

Announcement: Azure Speech Narration Is Live

Showrunner now ships with first-class speech support. You can add narration directly in storyboard JSON, render MP4 with baked-in voice-over, and automatically generate synced transcript files.

  • Azure Speech neural voices (per-scene text or raw SSML)
  • Automatic scene timing extension when narration runs longer
  • Transcript sidecars in vtt, srt, or both
  • Works in CLI and MCP tools (render_video and synthesize_narration)

This is opt-in and environment-authenticated by design: credentials stay in local/server environment variables, never in storyboard payloads.

Opt-in narration. Add a voiceover field to any scene and (optionally) a top-level narration config; Showrunner synthesizes per-scene audio with Azure Speech, concatenates it onto the video timeline, muxes it into the MP4, and writes a synced .vtt transcript sidecar (word-boundary accurate).

Auth is passthrough. The MCP server only reads credentials from its local process environment — never from the storyboard JSON. This keeps keys out of agent context and lets you bring either a subscription key or a short-lived Entra/STS bearer token.

# Option A: subscription key
export AZURE_SPEECH_REGION=eastus
export AZURE_SPEECH_KEY=<your-key>

# Option B: Entra / STS bearer token (10-minute lifetime — refresh on your side)
export AZURE_SPEECH_REGION=eastus
export AZURE_SPEECH_TOKEN=<your-token>

# Optional — custom endpoint (sovereign / private cloud)
export AZURE_SPEECH_ENDPOINT=https://<region>.tts.speech.microsoft.com/

# Install the optional SDK (only needed when narration is enabled)
npm install microsoft-cognitiveservices-speech-sdk

Storyboard schema additions

{
  "title": "Q2 Pipeline Review",
  "narration": {
    "voice": "en-US-JennyNeural",
    "language": "en-US",
    "style": "newscast",
    "autoExtendScenes": true,
    "gapMs": 150,
    "transcriptFormat": "vtt"
  },
  "scenes": [
    {
      "type": "title-card",
      "duration": 4,
      "data": { "title": "Q2 Pipeline Review" },
      "voiceover": {
        "text": "Here's your Q2 pipeline review — enterprise accounts edition.",
        "style": "cheerful",
        "rate": "+5%"
      }
    },
    {
      "type": "closing",
      "duration": 3,
      "data": { "tagline": "Generated by AI" },
      "voiceover": {
        "ssml": "<speak version=\"1.0\" xml:lang=\"en-US\" xmlns:mstts=\"https://www.w3.org/2001/mstts\"><voice name=\"en-US-GuyNeural\"><mstts:express-as style=\"calm\">Thanks for watching.</mstts:express-as></voice></speak>"
      }
    }
  ]
}
Field Purpose
narration.voice Default Azure Neural voice (e.g. en-US-JennyNeural, en-US-AriaNeural)
narration.language BCP-47 locale used when wrapping plain text in SSML
narration.style Default expressive style (newscast, cheerful, chat, …)
narration.autoExtendScenes When narration is longer than scene.duration, extend the scene automatically (default true)
narration.gapMs Silence padding between scenes (default 150)
narration.transcriptFormat vtt (default), srt, both, or none
narration.region / narration.endpoint Override env AZURE_SPEECH_REGION / AZURE_SPEECH_ENDPOINT
scene.voiceover.text Plain text — auto-wrapped in SSML
scene.voiceover.ssml Raw SSML — used verbatim, overrides all other voiceover fields
scene.voiceover.voice / style / styleDegree / rate / pitch Per-scene overrides

CLI

# Render video with baked-in voice-over + transcript sidecar
AZURE_SPEECH_REGION=eastus AZURE_SPEECH_KEY=... \
  npx showrunner render storyboard.json --output out/brief.mp4
# → out/brief.mp4  +  out/brief.vtt

MCP

tool: synthesize_narration
args: { "storyboard": { ... }, "audioOutputPath": "/tmp/brief.mp3" }
→ { audioPath, transcriptPath, durationSec, voice, scenes: [{ sceneStartMs, wordCount, ... }] }

Call synthesize_narration first to preview/validate voices, or just call render_video on a storyboard that has voiceover fields — narration is added automatically.

Themes

Theme Description
corporate-dark Dark navy, white text, gold accent (default)
corporate-light White background, dark text, blue accent
minimal Near-white, subtle grays
microsoft Microsoft brand guidelines
custom Uses branding overrides from storyboard

Transitions

Applied between consecutive scenes with a 0.5s overlap:

Type Effect
cut Hard cut, no overlap
fade Cross-fade (default)
slide-left Outgoing slides left, incoming slides from right
slide-up Outgoing slides up, incoming slides from below
zoom Outgoing zooms + fades, incoming scales in

Render Quality

Quality Frame format CRF Best for
high PNG 18 Final output
medium JPEG 90% 23 Default / preview
fast JPEG 70% 28 Iteration

Technology Stack

Layer Technology Role
Data visualization D3.js v7 SVG chart construction — scales, axes, bars, arcs, line paths
Animation GSAP v3 Timeline-based motion — springs, staggers, easing, count-up
Templating Handlebars Scene HTML generation from storyboard data
Browser Playwright Headless Chromium for deterministic frame capture
Encoding ffmpeg H.264 MP4 and GIF output
Validation Zod Storyboard schema validation
Server MCP SDK stdio + HTTP tool server for AI agents

Animation System

GSAP (GreenSock) drives all motion. Each scene template builds a paused gsap.timeline() with springs, staggers, easing, and count-up animations. The renderer calls window.__seek(progress) per frame — fully deterministic, no requestAnimationFrame, no timing jitter.

Key GSAP features used: stagger, back.out / elastic.out / power3.out easing, snap: { textContent: 1 } for count-up, nested timeline composition.

D3 + GSAP: How Charts Work

Chart scenes use a two-library pattern — D3 for construction, GSAP for animation:

Renderer ──▶ Playwright Page: setContent(base.html + scene.html)
                 │                  (Page loads GSAP + D3 bundles)
                 │
                 ├──▶ D3: Parse embedded JSON data block
                 │    D3: Build scales (scaleLinear, scaleBand, scaleOrdinal)
                 │    D3: Generate geometry (rects, arcs, line paths)
                 │    D3: Append SVG elements to DOM
                 │         (D3 is done — no further re-renders)
                 │
                 ├──▶ GSAP: __buildTimeline() returns paused gsap.timeline()
                 │    GSAP: Target D3-generated SVG elements
                 │          (scaleY, strokeDashoffset, opacity, textContent snap)
                 │
                 └──▶ Loop: every frame (30 fps × duration)
                        Renderer → Page: window.__seek(progress)
                        Page → GSAP: timeline.progress(n)
                        GSAP → Page: Update SVG attributes
                        Renderer: Screenshot to frame buffer
                                    │
                              Pipe frames to ffmpeg

This separation keeps D3 doing what it's best at (data → geometry mapping) and GSAP doing what it's best at (timeline-scrubbed animation), with no runtime conflicts.

Chart type D3 handles GSAP animates
chart-bar x/y scales, axis ticks, bar rects Staggered scaleY grow + value count-up
chart-line Line generator, area fill, x/y axes strokeDashoffset draw-on + dot pop-in
chart-donut Arc generator, pie layout, slices Clockwise stroke draw + center count-up

Project Structure

src/
├── server.ts ──▶ tools/ ──▶ renderer/
│                               ├── index.ts
│                               ├── frame-capture.ts ──▶ browser-pool.ts
│                               ├── encoder.ts
│                               ├── transitions.ts
│                               └── preview.ts
├── motion/
│   ├── gsap-bundle.ts
│   ├── d3-bundle.ts
│   └── presets.ts
├── templates/
│   ├── base.html ──▶ scenes/ (21 templates)
│   └── themes/
└── schema/
    └── storyboard.ts (Zod)
Flat file tree
src/
├── server.ts                # Showrunner MCP server — stdio + HTTP transports
├── tools/                   # MCP tool handlers
├── renderer/
│   ├── index.ts             # Main render pipeline
│   ├── frame-capture.ts     # Playwright frame loop
│   ├── encoder.ts           # ffmpeg encoding
│   ├── transitions.ts       # Scene transition compositing
│   ├── browser-pool.ts      # Warm browser management
│   └── preview.ts           # HTML preview generator
├── output/
│   ├── local.ts             # File path output
│   └── blob.ts              # Azure Blob Storage output
├── motion/
│   ├── gsap-bundle.ts       # GSAP core for page injection
│   ├── d3-bundle.ts         # D3.js for page injection (chart scenes)
│   └── presets.ts           # Reusable animation presets
├── templates/
│   ├── base.html            # Common layout with theme + GSAP + D3 injection
│   └── scenes/              # Per-scene-type HTML templates
├── themes/                  # CSS custom property theme files
├── schema/
│   └── storyboard.ts        # Zod schemas
└── types/
    └── index.ts

Scripts

npm run build    # tsc + copy templates/themes to dist/
npm run dev      # tsc --watch
npm start        # node dist/server.js
npm test         # vitest

Publishing

Packages are published automatically to GitHub Packages via GitHub Actions when you push a version tag.

# 1. Bump version (updates package.json and creates a git tag)
npm version patch   # or minor / major

# 2. Push the commit and tag — CI publishes to GitHub Packages and creates a GitHub Release
git push --follow-tags

No extra secrets needed — the workflow uses the built-in GITHUB_TOKEN.

License

MIT


Built with 🎬 by the Showrunner crew

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors