| name | demo-video |
| description | Produce a narrated demo/walkthrough video from ordered screenshots plus Deepgram TTS narration, montaged with ffmpeg. Use when the user asks to "make a demo video", "record a walkthrough", "produce a submission video", "narrate screenshots", or capture an app end-to-end (every screen/action) into an MP4 with voiceover. Covers Android (adb screencap), web (headless browser), and HTML slide frames for architecture / submission / closing sections. |
demo-video — narrated walkthrough videos
Turn an ordered set of frames (screenshots / rendered slides) + a matching
narration script into a single narrated MP4. Each scene is a still image held
for exactly the length of its spoken narration, then all scenes are concatenated.
Voiceover is generated with Deepgram Aura-2 TTS.
This codifies the proven st6-weekly-commit demo pipeline (one NN.mp3 per
NN-*.png, ffmpeg still-clip-per-scene → concat), swapping in Deepgram TTS.
The model
A demo is a list of scenes, each { id, frame.png, narration }:
id is a zero-padded ordinal: 01, 02, … It sets the play order.
- Frame file is named
NN-anything.png (e.g. 03-enroll-screen.png).
- Narration is one short paragraph; Aura-2 reads it. Frame is shown for that long.
Three frame sources, freely mixed in one demo:
- App screens (Android) —
scripts/capture_android.sh <NN-name> runs
adb exec-out screencap into the frames dir. Drive the UI between captures
(tap/start service/grant perms) so you capture every screen and action.
- App screens (web) — point a headless browser (the
browse/agent-browser
skill, or Playwright) at the running app and screenshot each state into the
frames dir with the same NN-name.png convention.
- Slides (architecture / submission / closing) — author one HTML file per
slide (or one file with
?slide=N), open it in a headless browser at a fixed
viewport (1280×720 or 1920×1080), and screenshot to NN-name.png. Use slides
for the architecture walkthrough, submission/requirements mapping, and closing
remarks. assets/slide.html is a ready template (title + bullets + footer).
Keep ALL frames the same resolution (the montage assumes it). 1280×720 is a good
default; Android screencaps are phone-portrait, so either letterbox them or run a
phone-shaped demo — don't mix aspect ratios in one video.
Pipeline (do these in order)
-
Plan scenes. Write demo/scenes.json: an array of
{ "id": "01", "name": "intro", "narration": "..." }. Order = play order.
Sections to cover for a submission demo: app screenshots of every screen/action
→ architecture walkthrough → submission details → closing remarks.
-
Produce frames named NN-name.png into demo/frames/ using the sources
above. One frame per scene id. Verify every id has a frame.
-
Generate narration (needs DEEPGRAM_API_KEY in env):
python scripts/gen_tts_deepgram.py demo/scenes.json demo/audio
Writes demo/audio/NN.mp3 per scene (Aura-2, default voice
aura-2-arcas-en — a warm male voice; override with DEMO_TTS_VOICE).
-
Montage (needs ffmpeg — ffmpeg-static is fine):
FF=/path/to/ffmpeg.exe bash scripts/build_demo.sh demo/frames demo/audio demo/walkthrough.mp4
Pairs NN-*.png with NN.mp3, makes a still clip per scene (+0.4s tail),
concatenates to the output MP4 (H.264 / AAC, 30fps, yuv420p — broadly playable).
-
Verify: the script prints the final duration + streams. Spot-check the MP4.
Capturing an Android app end-to-end
ADB=$ANDROID_SDK/platform-tools/adb.exe
EMU=$ANDROID_SDK/emulator/emulator.exe
"$EMU" -avd <avd> -no-snapshot-save -no-boot-anim -gpu swiftshader_indirect &
"$ADB" wait-for-device
until [ "$("$ADB" shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')" = 1 ]; do sleep 2; done
"$ADB" install -r -g app-debug.apk
"$ADB" shell am start -n <pkg>/<activity>
bash scripts/capture_android.sh 01-launch
Tips:
-g on install pre-grants dangerous permissions (mic, location) so you skip the
permission dialogs — or screenshot the dialogs deliberately if they're part of
the story.
- Use
adb shell input tap X Y / adb shell am start-foregroundservice to drive
actions you want to show. Capture before AND after each action.
- If a real spoken transcript can't be produced headlessly, capture the live UI
states (enrollment, listening, status) and pair a separate scene that proves the
cloud path with a real API call / test output. Be honest in narration.
Narration style (for Aura-2)
- Spell tricky tokens phonetically: "R T K", "A P I", "S three", "Auth Zero".
- Keep each line one breath-paragraph; 1–3 sentences. Aura-2 caps ~2000 chars/req.
- Neutral, confident, present tense. Name what's on screen, then why it matters.
Files
scripts/gen_tts_deepgram.py — scenes.json → NN.mp3 via Deepgram Aura-2.
scripts/build_demo.sh — frames + audio → narrated MP4 (ffmpeg montage).
scripts/capture_android.sh — adb screencap one frame into the frames dir.
assets/slide.html — title/bullets/footer slide template (open with ? params).