Skip to content

Releases: sandraschi/demo-vid-mcp

demo-vid-mcp v0.3.0

Choose a tag to compare

@sandraschi sandraschi released this 03 Sep 19:21

Fleet Intro Video Pipeline v0.3.0

  • Subtitles & Closed Captions: Automatically generates WebVTT and SRT sidecars with native player subtitle track support.
  • Visual Cursor Highlights: Playwright cursor click-ripples on every button and action.
  • Aspect Ratio & Resolution Presets: Support for 16:9 desktop landscape and 9:16 vertical mobile reels in 720p / 1080p.
  • Automated Poster Extraction: Frame capture generating poster thumbnail images for instant video preview.
  • Background Audio Bed: Ambient music bed support with voiceover ducking.
  • Persistent Job Queue: File-backed background queue with live polling, queue scheduling, and restart recovery.
  • Dead Port Resilience: Graceful skipping and clear UI warning callouts for backend port 11134 and Ollama 11434.

2026-09-04 update — installer replaced (was completely broken)

The installer originally attached to this release never produced a working app. In order,
found and fixed:

  1. Backend crashed on launch (ModuleNotFoundError: No module named 'fastapi') — the
    PyInstaller entry point used a string-based uvicorn.run("module:app", ...) reference
    that PyInstaller's static analyzer couldn't trace, so FastAPI/Starlette were never
    bundled.
  2. The app killed itself ~1.5s after every launchfree_port()'s cleanup logic did
    Stop-Process -Name 'demo-vid-mcp-native' to clear stale processes, but that command
    runs from inside the very process it's trying to clean up after, so on every fresh
    launch it matched and killed itself (Windows process-name matching has no "not me").
  3. Even past that, the window froze on launch (Windows showed it as
    "Demo Vid MCP (Not Responding)") — the backend-startup logic ran directly on the
    thread responsible for pumping the window's message loop, blocking the UI for the
    whole time it took to spawn.

All three verified fixed by directly instrumenting the installed app (process lifetime,
Windows responsiveness state, and window class via pywinauto) rather than assuming a
green CI run meant it worked.

2026-09-04 update 2 — the app ran, but core features didn't work

Found by actually using the running app, not just checking it stayed open:

  1. The whole webapp couldn't reach its own backend. Every page used
    fetch("/api/...") with a relative path. In dev mode Vite's proxy makes that work;
    in the packaged app the frontend is served from tauri://localhost, so a
    relative fetch never reached http://127.0.0.1:11134 at all — this is why
    Settings/Chat showed "No provider detected" even with Ollama and LM Studio running.
    Fixed with an apiUrl() helper applied to every fetch and every video/poster/subtitle
    element across all 11 pages.
  2. Video generation failedplaywright-capture.js was never bundled into the
    installer, and its path-resolution logic assumed a dev-repo layout that doesn't
    exist inside the frozen backend. Bundled the script, added robust multi-candidate
    path resolution, and a NODE_PATH fallback so a global Playwright install is still
    discoverable from the installed resources/ folder.
  3. Auto-drafted scripts navigated to fabricated URLs and 404'd — page routes were
    guessed by lowercasing the component filename (ApiDocsPage.tsx/apidocs)
    instead of reading the target's real router config (/swagger, in one real case
    hit). Now parses the actual <Route path="X"> table from the target's App.tsx.
  4. Real intro title cards + explanatory narrationtext_overlay (and most of the
    Choreography editor's other step types) was accepted by validation but never
    actually rendered by the capture script. Implemented it for real, and auto-drafted
    scripts now open on a title card and narrate what each page does (from the
    target's README "Webapp" table) instead of "The dashboard page."

2026-09-04 update 3 — recording worked, composition crashed

  1. FFmpeg crashed compositing the final MP4 (FFmpeg exit 3221225477 — that's
    0xC0000005, STATUS_ACCESS_VIOLATION, a genuine crash, not a normal error exit).
    The drawtext filter burning the title into the video had no fontfile= set, so it
    fell back to fontconfig's default-font lookup — Windows has no fonts.conf, and any
    fontconfig-enabled FFmpeg build (the Gyan full_build from winget install ffmpeg,
    which this repo's own ONBOARDING.md recommends) crashes outright on that lookup
    instead of erroring cleanly. Fixed by passing an explicit fontfile= pointing at a
    real Windows system font (Segoe UI, falling back to Arial), bypassing fontconfig
    entirely; composes without the title overlay (not crashing) if neither font is found.
  2. Composed videos showed 0:00 duration in the player — no -movflags +faststart,
    so FFmpeg wrote the moov atom (container metadata, including duration) at the end
    of the file; browsers can't report duration or seek until that's read. Fixed.

Verified end-to-end for real, not just in isolation: recorded and composed an actual
demo video for arxiv-mcp through the full pipeline — real webapp footage, title
overlay burned in, poster frame and WebVTT/SRT subtitles all produced from a genuine,
seekable .mp4. See BUILD_LOG.md in the repo for full root-cause detail on every item
above.

2026-09-04 update 4 — videos too short, no way to prioritize important pages

User feedback after watching a generated video: 15s total was too short, and important
pages (arxiv-mcp's search and depot) got the same one-liner treatment as everything
else — no way to tell the auto-drafter "linger here."

  1. Per-page detail levels. Every page can now be classified Skip / Show / Detail —
    keyword heuristics by default (search/depot/dashboard/chat/generate → Detail;
    logs/swagger/settings → Skip), overridable per page via a new Skip/Show/Detail
    checklist on the Generate page. Detail pages get 6-8s of dwell time and substantive
    narration instead of a bare "The X page," even for repos whose README has no
    ## Webapp purpose table to draw from.
  2. duration_target now reflects actual contentsum(step wait times) + 5s
    with a 30s floor, replacing a step-count guess that capped out around 15s for
    typical repos.
  3. Found in passing while wiring page selection through the background queue:
    enqueue() stored aspect_ratio/resolution on the job but the queue worker never
    passed them to the generator — the Generate page's aspect-ratio/resolution
    selectors were silent no-ops for anything sent to the background queue. Fixed
    alongside.

Verified end-to-end in the rebuilt installer: reinstalled, confirmed a healthy
single backend+native process pair, hit the new page-listing endpoint directly against
the packaged backend, then drove the actual Tauri window (screenshot-verified via
pywinauto, since the packaged webview is tauri://localhost and not reachable from a
normal browser) — selected arxiv-mcp on the Generate page, saw the Skip/Show/Detail
checklist render with the correct defaults, and confirmed a drafted script came back
with duration_target: 55 (up from ~15s).

2026-09-04 update 5 — longer scripts immediately hit a stale hard timeout

Clicking "Generate Now" on the update-4 build failed with "Playwright capture timed out after 45s" - the very first real-world use of the new detail-level feature.

  1. recorder.py's capture subprocess had a flat 45s timeout left over from when
    scripts totaled ~15s of wait time. Once detail-level pages started producing 50s+
    of narrated content, the capture was still legitimately running (browser launch +
    real page navigation + the narrated wait time itself) when the timeout killed it.
    _capture_timeout() now scales with the script's own content
    (sum(wait times) + 60s buffer), extracted as a small pure function with direct
    unit tests.

Verified with a real, non-mocked generation through the exact POST /api/generate
endpoint the Generate page's "Generate Now" button calls, against the rebuilt and
reinstalled packaged app: recording completed in 54.5s (previously would have hit the
old 45s cap and failed exactly as reported), composition succeeded, and the final
.mp4 in the app's own data/videos/arxiv-mcp/ came back at 52.2s duration - up
from the original ~15s, with the search/depot/chat/dashboard pages actually narrated in
detail rather than skimmed past.

(The voiceover stage still reports "speech-mcp not configured" in this test run -
that's expected and non-fatal, not a bug: no SPEECH_MCP_URL is set, so the pipeline
falls back to a silent video with timed subtitles rather than failing the whole
generation. Set SPEECH_MCP_URL in the app's .env to enable narrated voiceover.)

2026-09-04 update 6 — voiceover was silently broken from day one

.env was never actually loaded, anywhere, ever — despite every fleet-service URL
(SPEECH_MCP_URL etc.) being read via os.getenv(), and the app's own error message
saying "Set SPEECH_MCP_URL in .env", nothing in the codebase called load_dotenv().
A correctly filled-in .env (present the whole time, SPEECH_MCP_URL included) was
simply never read, so voiceover always failed with "speech-mcp not configured" even
with speech-mcp healthy and running. The packaged app's resources/ compounded this by
only ever getting .env.example copied in, never a real .env.

  1. config.py now loads .env before its dataclass field defaults are evaluated,
    trying the dev repo root, then the packaged app's install dir, then its resources/
    folder. build.ps1 seeds a real resources/.env from .env.example on build
    (skipped if one already exists, so a customized .env survives upgrades), and it's
    now included in the NSIS bundle.

Verified with a real generation through the exact endpoint the Generate page's
button calls, against ...

Read more

Demo Vid MCP v0.1.0

Choose a tag to compare

@sandraschi sandraschi released this 17 Aug 13:13

Demo Vid MCP - automated demo video generation pipeline: topic to narrated video. Stable release (was v0.1.0-beta). Webapp on 11134/11135.

v0.1.0-beta

v0.1.0-beta Pre-release
Pre-release

Choose a tag to compare

@sandraschi sandraschi released this 29 Jul 18:25

Beta release of the fleet demo video pipeline.

6 MCP tools: generate, list, refine, script_draft, script_validate, help

Webapp (10 pages):

  • Dashboard: dynamic KPIs, backend/speech-mcp health, pipeline overview
  • Depot: categorized gallery with repo filter, URL params, inline player, rebuild, delete, insert into repo README
  • Generate: category+repo selectors, Draft Script button, script editor
  • Choreography: visual script builder — 11 step types, global toggles, YAML preview
  • Chat: SOTA — personalities, localStorage history, example prompts, export/clear, LLM integration
  • Settings: LLM provider probe (Ollama/LM Studio), model selection, backend health
  • Help: 6 horizontal tabs (overview, architecture, tools, config, fleet, troubleshooting)
  • Logs: ring-buffer viewer with level filter and search
  • Scripts, Queue

Pipeline:

  • Playwright headless Chromium recording
  • speech-mcp TTS voiceover via GET /api/v1/tts/wav (WAV bytes)
  • FFmpeg composition with title card + audio mix
  • Auto-start target webapp backend + frontend (zombie-kill stale processes)
  • Content-aware recording (blank page / HTTP error detection)
  • Parallel voiceover + recording
  • Dynamic port registry — 136 repos auto-detected from WEBAPP_PORTS.md

14 REST API endpoints, CI, pre-commit, justfile, MCPB packaging.