Releases: sandraschi/demo-vid-mcp
Release list
demo-vid-mcp v0.3.0
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:
- Backend crashed on launch (
ModuleNotFoundError: No module named 'fastapi') — the
PyInstaller entry point used a string-baseduvicorn.run("module:app", ...)reference
that PyInstaller's static analyzer couldn't trace, so FastAPI/Starlette were never
bundled. - The app killed itself ~1.5s after every launch —
free_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"). - 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:
- 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 fromtauri://localhost, so a
relative fetch never reachedhttp://127.0.0.1:11134at all — this is why
Settings/Chat showed "No provider detected" even with Ollama and LM Studio running.
Fixed with anapiUrl()helper applied to every fetch and every video/poster/subtitle
element across all 11 pages. - Video generation failed —
playwright-capture.jswas 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 aNODE_PATHfallback so a global Playwright install is still
discoverable from the installedresources/folder. - 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'sApp.tsx. - Real intro title cards + explanatory narration —
text_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
- FFmpeg crashed compositing the final MP4 (
FFmpeg exit 3221225477— that's
0xC0000005,STATUS_ACCESS_VIOLATION, a genuine crash, not a normal error exit).
Thedrawtextfilter burning the title into the video had nofontfile=set, so it
fell back to fontconfig's default-font lookup — Windows has nofonts.conf, and any
fontconfig-enabled FFmpeg build (the Gyan full_build fromwinget install ffmpeg,
which this repo's own ONBOARDING.md recommends) crashes outright on that lookup
instead of erroring cleanly. Fixed by passing an explicitfontfile=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. - Composed videos showed 0:00 duration in the player — no
-movflags +faststart,
so FFmpeg wrote themoovatom (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."
- 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
## Webapppurpose table to draw from. duration_targetnow reflects actual content —sum(step wait times) + 5s
with a 30s floor, replacing a step-count guess that capped out around 15s for
typical repos.- Found in passing while wiring page selection through the background queue:
enqueue()storedaspect_ratio/resolutionon 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.
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) + 60sbuffer), 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.
config.pynow loads.envbefore its dataclass field defaults are evaluated,
trying the dev repo root, then the packaged app's install dir, then itsresources/
folder.build.ps1seeds a realresources/.envfrom.env.exampleon build
(skipped if one already exists, so a customized.envsurvives 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 ...
Demo Vid MCP v0.1.0
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
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.