space-demo-video
$
npx mdskill add huggingface/space-demo-kit/space-demo-videoCreates polished social demo videos
- Solves demo video creation problem
- Depends on space-demo-kit renderer
- Decides via template selection rules
- Delivers MP4 video files silently
SKILL.md
.github/skills/space-demo-videoView on GitHub ↗
---
name: space-demo-video
description: "Create a polished social demo video (MP4, 4:3, ~10s) for any Hugging Face Space with the space-demo-kit renderer. Use whenever the user asks for a demo, promo, showcase, or social video of a HF Space or model. Covers template selection (i2v, t2v, edit, avatar, a2a, gallery, vqa), manifest schema, live asset capture, rendering, verification, and delivery."
---
# Space Demo Video (space-demo-kit)
The kit renders a Gradio-style "app window" video: a hero intro where the input opens
near full-frame with the prompt typing in large text (readable at mobile feed size),
a morph into the app layout with the Space's real header (emoji, author/name, likes,
hardware), a Generate press, a progress sweep, and the real output filling the output
panel edge-to-edge. Text auto-fits its panels (short answers render huge, long ones stay
readable). Branding is extracted from the Space page automatically. Output: 1440x1080
(4:3), 30 fps, ~12–17 s, H.264, silent unless the task itself involves audio.
Kit location on this machine: `/root/code/space-demo-kit`
Render command (the ONLY way to produce the video):
```bash
cd /root/code/space-demo-kit && python3 render.py manifests/<name>.json
# -> out/<name>/<name>.mp4 + out/<name>/<name>-contact.jpg
```
## Golden rules
1. **Never design video frames by hand.** No PIL cards, no ffmpeg drawtext/overlay design,
no custom HTML. The kit owns 100% of the design; you only supply facts and assets via a
manifest JSON.
2. **Real outputs.** Generate the output by calling the live Space (`gradio_client`) with a
real input. Only mock when live inference is impossible (quota, broken Space), and then
label it honestly in the manifest `meta` field (e.g. `"mock demo assets"`) and tell the user.
3. **Real branding.** Pull `emoji`, `colorFrom`, `colorTo`, `likes`, and hardware from
`https://huggingface.co/api/spaces/<id>` (`cardData` + `runtime.hardware.current`).
If the user gives a MODEL id, resolve its demo Space first (model page / `spaces` field of
`https://huggingface.co/api/models/<id>`).
4. **Prompts under 160 chars.** The renderer truncates displayed prompts around 150 chars;
pick or write inputs that fit.
5. **Verify before delivering**: `ffprobe` the MP4 (duration, 1440x1080) and look at the
contact sheet (no overflowing text, output visible). Then send the MP4 to the user as media.
6. **One look only.** Never put a `"style"` key in a manifest — the app-window template is the
only production design and the renderer ignores styles. Anything under `experiments/` is a
rejected prototype: never use it as an example or reference.
## Asset quality bar (hard requirements)
- **Inputs must be real content**: a real photograph, illustration, or clip at least 512 px on
the short side. NEVER an emoji, icon, favicon, logo, or clipart — tiny images upscale into
blurry blobs and ruin the video. Verify every asset with `file` + dimensions before using it.
- **Best input source**: the Space's own example assets (the `examples` in its Gradio config,
or files in the Space repo via `https://huggingface.co/api/spaces/<id>/tree/main`). They are
known to work with the model.
- **Before/after coherence (`edit`, `a2a`)**: the output MUST actually be derived from the
input. Never pair two unrelated assets — an incoherent before/after is worse than no video.
If live inference fails: retry via `gradio_client` (not hand-built HTTP calls), try another
example input, and if it still fails, report the failure to the user and STOP. Do not
fabricate the pair.
## Template selection
| template | Space task | required manifest fields |
|---|---|---|
| `i2v` | image → video | `input_image`, `prompt`, `video` (generated clip) |
| `t2v` | text → video | `prompt`, `video` |
| `edit` | image + instruction → image | `input_image`, `prompt`, `before_image`, `after_image` |
| `avatar` | portrait + audio → talking video | `input_image`, `audio`, `video` (audio can be the generated mp4 itself) |
| `a2a` | audio → audio | `audio_in`, `audio_out` |
| `gallery` | one input → several images | `input_image`, `prompt`, `outputs` (list of `{path, label}`, 4 items) |
| `vqa` | video/image + question → text | `video`, `prompt`, `answer` |
Text-to-image Spaces use `t2v`: turn the generated image into a short static clip first
(`ffmpeg -loop 1 -i out.webp -t 6 -r 30 -pix_fmt yuv420p static.mp4`) and pass it as `video`
(see `manifests/z-image-turbo-demo.json`). There is no `t2i` template.
## Manifest schema
Common fields (all templates):
```json
{
"name": "my-demo", // output folder + file name
"template": "edit",
"space": {
"id": "owner/space-name",
"emoji": "🧬", // from cardData
"colorFrom": "blue", // from cardData
"colorTo": "gray", // from cardData
"likes": 27, // from the API
"hardware": "zero-a10g" // runtime.hardware.current
},
"meta": "live output · zero-a10g", // small honest footer note; use "mock demo assets" for mocks
"button": "Generate", // optional; e.g. "Enhance", "Animate"
"input_label": "source image", // optional label overrides
"prompt_label": "edit instruction",
"output_label": "edited image",
"audio_gain": 2.0, // optional; default 2.0 (with limiter)
"hero": false // optional; set false to skip the full-frame intro
}
```
Plus the template-specific fields from the table. All asset paths are absolute paths on
this machine. Store working assets under `/root/code/<project-dir>/` as usual.
## Workflow
1. `curl -s https://huggingface.co/api/spaces/<id>` → metadata for `space{}` fields.
2. Pick the template from the table. If the Space's task fits none of them, say so and pick
the closest; do NOT invent a new design.
3. Capture assets: choose a good input (the Space's own example assets are ideal), run the
live Space with `gradio_client`, download the real output. Verify the output file with
`ffprobe`/`file` before rendering.
4. Write `manifests/<name>.json` in the kit.
5. Render (command above). First run downloads fonts/emoji (needs network) and, for video
inputs, extracts frames. A render takes roughly 3–5 minutes — do not assume it hung.
6. Verify MP4 + contact sheet, then deliver the MP4 to the user as a media message.
## Codex dispatch (OpenClaw — mandatory)
Demo-video requests are heavy (live inference + a ~2 min render). Do NOT run inference or
rendering inline in the main session — it blocks you for many minutes. ALWAYS dispatch a
codex session per the codex-monitor skill (setsid, `</dev/null`, CODEX_HOME pinned) and let
the CODEX_FINISHED wake drive verification + delivery. Include in the codex prompt:
"Read /root/code/space-demo-kit/skills/space-demo-video/SKILL.md and follow it exactly.
Use the kit's render.py for ALL visuals; do not design any frame yourself."
## Gotchas
- Long Space ids auto-shrink in the footer; long repo names get ellipsized in the header — fine.
- The renderer needs Playwright + Chromium (already installed system-wide here).
- Audio templates (`avatar`, `a2a`) mux the real audio automatically, delayed to the moment
playback starts on screen, at 2x gain with a limiter.
- `gallery` wants exactly 4 outputs for the 2x2 grid.
- `vqa` answers auto-fit the output panel: keep them 30–60 words so the type stays large.
- Do not edit `templates/app-window.html` or `render.py` for a one-off video. If a Space
genuinely needs a new mode, report that instead of hacking around the kit.