Devrel Video logo

Devrel Video

Community
aaitor
devrel-video

Produce a silent DevRel-style product walkthrough video from a web URL. Playwright records the live flow, HyperFrames composes title/frame/chapters/CTA, FFmpeg masters. Use when asked to record, make, or update a product demo, feature walkthrough, catalog tour, or promo video from a web product.

Overview

Publisheraaitor
Repositoryskill-video-studio
Skill namedevrel-video
Stars
214
Forks
6
Bundled files
23
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • 23 bundled files

    Scripts, templates, and references the model can read while it works. Files are read-only and never executed.

  • Open source

    Published by aaitor on GitHub. Read the source before you install it.

Installation

Install the Devrel Video AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/aaitor/skill-video-studio/tree/main/.claude/skills/devrel-video
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/aaitor/skill-video-studio.git /tmp/skill-video-studio
mkdir -p .claude/skills
cp -r /tmp/skill-video-studio/.claude/skills/devrel-video .claude/skills/devrel-video
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Devrel Video in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Devrel Video on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Devrel Video is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

DevRel Video Studio — /devrel-video

A thin orchestrator. It does not reimplement capture or composition — it drives:

  • playwright-cli (page.screencast) for live interaction capture,
  • HyperFrames for composition + deterministic MP4 render,
  • FFmpeg / ffprobe for convert, master, and QA.

Read references/production-notes.md first for environment gotchas (sandbox flags, init flags, CDN vendoring, determinism) and the production steps for music, narration, avatar, subtitles, and multi-environment (terminal ⇄ browser) (all supported — steps 5.4–5.8; the template and manifest carry seams for each).

For studio installation and prerequisites, see the repository-root docs/installation.md. The quick repository demo in examples/README.md demonstrates intake only; use the production workflow below for actual videos.

When to use

  • "record / make / produce a walkthrough, demo, catalog tour, or promo of <web product / URL>"
  • "update / re-render an existing devrel-video project"

Inputs — gather, never guess

  • URL (+ start command if the product is local).
  • Flow: the 2–4 beats to show (e.g. browse → filter → open a detail).
  • Brand: reuse brands/<name>/, or extract from the URL (step 3).
  • Output: format(s) + duration target. Default: silent 16:9, ~25–40 s.
  • Environments (optional) — a demo can switch between the browser and Claude Code (terminal). Name the order in the prompt ("prompt in Claude Code → the catalog in the browser → back to Claude Code") → environments: in brief.yaml. Terminal beats are captured with VHS (step 5.8); a pure-browser video is the default.
  • Audio / avatar (optional, all prompt-selectable) — set any of these straight from the prompt, and write them into brief.yaml:
    • voice: the narration voice — male leo/dan/zac, female leah/tara/jess/mia/zoe (match the presenter; offer samples if unsure). "…narrated with voice dan" → narration: dan. Regenerating with a different voice makes a new variant (see 5.4).
    • music on/off, subtitles languages, avatar at intro/CTA (+ its private avatar_plate path).
  • Approved claims: numbers/names allowed on screen — pull from the captured page, never invent (guide §7/§8).

Workflow

1 · Intake → projects/<slug>/brief.yaml

Copy templates/brief.example.yaml. Confirm the audience, the one message, the CTA, and the beats.

2 · Explore (before recording)

Open the URL headless; snapshot + screenshot. Confirm: no login wall, no PII / keys / wallets on screen, and stable selectors for each beat. Prefer exact a[href="…"] and getByRole locators; always add a fallback selector so one missing element can't abort the capture.

3 · Brand → brands/<name>/

scripts/brand-extract.sh <url> <name> → tokens.json (real palette + fonts) + logo.svg. Use these in the composition. Never invent a palette. Reuse an existing brands/<name>/ if you already have one for the product (brands/acme/ is the default placeholder brand).

4 · Capture → projects/<slug>/capture.mp4

Copy templates/hero-script.js → capture.js; edit the beats (eased scrollTo, real locators, deliberate pauses, all-forward navigation so page.screencast survives route changes). Then: scripts/capture.sh projects/<slug>/capture.js "<start-url>" → records capture.webm, converts to capture.mp4. Contact-sheet it; re-record on layout shift, PII, or a mis-click.

5 · Compose → projects/<slug>/index.html

Copy templates/composition.html to projects/<slug>/index.html and fill it from the brief + tokens (skip hyperframes init: it refuses a folder that already holds the capture, and the render only needs index.html): title card (real claims) → footage in a browser frame → chapter lower-thirds synced to the capture beats (+ the title-card offset) → CTA. Give every animated element a stable id (GSAP and lint both require it).

5.4 · Narration (optional — drives the timeline)

For a narrated cut the voice sets the timing. Write ~1 line per beat (clean text: no parens/version numbers, em-dash → comma). Synth each with Orpheus in a voice that matches the presenter — male leo/dan/zac, female leah/tara/jess/mia/zoe (offer samples if unsure): scripts/tts.sh "<line>" vo1.wav <voice> (set ORPHEUS_URL/ORPHEUS_KEY — see scripts/_env.sh; reference TTS is orpheus-tts). Then adapt projects/<slug>/narrate.py (copy the template — footage length, beat times, SPOKEN lines, captions) — it measures the lines, computes scene/chapter times, and writes voice.wav, re-timed captions.<lang>.srt, and timing.json. Apply that timing to the composition with scripts/retime.py projects/<slug> (idempotent — rewrites every data-start/data-duration + GSAP position by id, so total tracks the voice), then mix (next step), render. Swapping the voice later is one command: scripts/variant.sh projects/<slug> <voice> runs the whole chain — re-TTS → narrate → retime → mix → re-lip-sync the avatar bubbles (if any) → render → renders/out-<voice>.mp4 (add --no-avatar to skip the GPU step). narrated-devrel mode.

5.5 · Music (optional)

Local, license-clean bed — no auth, no model: python3 .claude/skills/devrel-video/scripts/gen-bgm.py bed.wav && ffmpeg -i bed.wav -b:a 192k projects/<slug>/bgm.mp3, then add the <audio id="bgm" class="clip" src="bgm.mp3" … data-track-index="9" data-volume="0.85"> seam to the composition (lower the volume under narration). For a produced track: /media-use resolve --type bgm (HeyGen catalog — needs heygen sign-in) or --local-only (MusicGen), dropped into the same seam. With narration, don't stack two audio clips — pre-mix: scripts/mix-audio.sh bgm.wav voice.wav narration-mix.mp3 ducks the bed under the voice and masters to −16 LUFS; use that one file in the seam at data-volume="1".

5.6 · Subtitles (optional)

Author caption cues timed to the beats → projects/<slug>/captions.<lang>.srt — soft, toggleable, platform-standard; one file per language covers "alternative subtitles". Ship the .srt next to the video (YouTube/LinkedIn read it). For autoplay-muted social, burn a hard cut: scripts/subtitles.sh projects/<slug> captions.en.srt. When narration exists, derive the cues from its transcript (WhisperX via /media-use) instead of authoring.

5.7 · Avatar (optional — face-only presenter)

A face-only circular bubble, lip-synced, shown ONLY at intro / one transition / CTA (product stays the hero — a full-time presenter reads as a webinar). Depends on narration. Trim the exact line the mouth should say from narration-mix.mp3 so lips match what's heard: ffmpeg -ss <t0> -to <t1> -i projects/<slug>/narration-mix.mp3 -ar 16000 -ac 1 line.wav. Then scripts/avatar.sh <plate> line.wav projects/<slug>/avatar-face.mp4 — runs LatentSync (256) on your own GPU host over SSH (set AVATAR_HOST/LS_DIR — see scripts/_env.sh; reference is an AMD ROCm box), lip-syncs, then pins the face (per-frame face-tracking via track_crop.py — follows the face every frame at constant size, so the head stays put in the small circle instead of drifting; vidstab alone can't fix a moving subject). Add a <video class="clip face-bubble" src="…" data-start data-duration data-track-index="11"> element with a shared .face-bubble CSS class (border-radius:50% = the circle) + a GSAP pop-in / fade-out over that window (data-duration = the line's length). For a bubble at more than one moment (e.g. intro and CTA), run avatar.sh once per line and add one element per window; set .face-bubble z-index above any full-screen scene card it overlaps (the CTA card is z-index 8 → bubble z-index 9). The <plate> is the avatar_plate: from brief.yaml — a private recording kept OUTSIDE the (public) repo (convention: ~/Videos/<Org>/DevRel/Talking_Head/<name>/); generated avatar-*.mp4 bubbles are gitignored, never committed. Format: front-on, sitting still, even light, mouth visible, ≥ the line's length; any fps (avatar.sh normalizes to 25 fps — LatentSync's rate, else the lips drift). Brighten a backlit plate first (ffmpeg -vf eq=brightness=0.06:contrast=1.10:gamma=1.12), and raise STEPS=30 (env, default 20) for a crisper mouth. ~10 min/clip cold. narrated-devrel + avatar.

5.8 · Multi-environment (optional — terminal ⇄ browser)

For a demo that moves between the CLI and the web (e.g. prompt in Claude Code → the product in the browser → back to Claude Code): capture each terminal beat with scripts/capture-terminal.sh <tape> — VHS renders the real Claude Code TUI headlessly (pixel-perfect; no sandbox flag needed) to term<N>.mp4. Copy templates/terminal-script.tape; set the demo dir + prompt. Sanitize like step 2 — the terminal is the CLI's screen: record in a clean throwaway dir (host paths show in the prompt and in tool calls), unset CLAUDE_CODE_CHILD_SESSION (kills the "transcript saving is off" warning), alias claude to claude --strict-mcp-config (hides the "N MCP servers need authentication" line — the flag lives in the alias so the recorded command stays a clean claude), and Escape onboarding popups. A live model turn is non-deterministic (wording + surprise popups vary) — for a repeatable cut, script a fixed answer (the HTML-terminal re-enactment — templates/cc-terminal.html) or record a good take and trim. Capture browser beats as usual (step 4). Then compose: place the beats as sequential timeline clips with terminal-frame / browser-frame chrome and hand off by fading each beat through the brand teal (the .bg shows through) — a pure crossfade ghosts terminal text through the page; fading over .bg is clean and adds the scale-pop the browser cut uses. See the MULTI-ENVIRONMENT seam in templates/composition.html. Quick non-composition preview: scripts/stitch-envs.sh out.mp4 0b1020 term1.mp4 capture.mp4 term2.mp4. Worked example of the re-enactment approach: templates/cc-terminal.html (a self-contained, renderable Claude Code beat). Tooling: VHS (go install) + ttyd (auto-fetched by the script) — for a free-form unscripted real session, record with asciinema and render with agg instead.

6 · Render + QA → projects/<slug>/renders/

scripts/render-qa.sh projects/<slug> → high master + web-compressed copy + ffprobe + contact sheet. Gates before "done":

  • hyperframes lint 0 errors · hyperframes check passes (Contrast AA).
  • ffprobe: target dims/fps/duration, video stream present, non-zero size.
  • Contact sheet: no clipped text, correct product state, chapters aligned, no PII.
  • Security: no keys/wallets/PII; all CDN assets vendored for confidential projects.
  • Terminal beats: sanitized — no host paths, no "transcript saving is off" / MCP-auth warnings, no onboarding popups on screen.

6.1 · Thumbnail (required deliverable)

Every video also ships a YouTube thumbnail (not just the QA contact sheet): copy templates/thumbnail.html → projects/<slug>/thumbnail.html, fill it from the brief + brands/<name>/tokens.json (kicker, headline, url label), then scripts/thumbnail.sh projects/<slug> → renders/thumbnail.jpg (1280×720, <2MB; pulls the hero shot from capture.mp4). For a README/social loop, a short GIF off the master: ffmpeg -ss <t> -to <t> -i renders/out.mp4 -vf "fps=12,scale=880:-1,palettegen" … → paletteuse.

Delegation map — do not reinvent

NeedUse
Live interaction captureplaywright-cli page.screencast (templates/hero-script.js)
Terminal / Claude Code captureVHS .tape (templates/terminal-script.tape) + scripts/capture-terminal.sh
Stitch terminal ⇄ browser beats (quick preview)scripts/stitch-envs.sh (fade through brand teal)
Static screenshots + brand tokenshyperframes capture <URL>
Composition + renderHyperFrames + templates/composition.html
Creative direction (promo)/product-launch-video, /hyperframes-creative
Audio (music/SFX/voice) + captions/media-use, /hyperframes-audio
Narration timing → compositiontemplates/narrate.py (writes timing.json) + scripts/retime.py
Swap the narration voice (whole re-gen)scripts/variant.sh <project> <voice>
Master / convert / QAFFmpeg / ffprobe (scripts/render-qa.sh)
YouTube thumbnail (1280×720)scripts/thumbnail.sh (templates/thumbnail.html)

Roadmap

Music, narration, avatar, subtitles, and multi-environment (terminal ⇄ browser) are all supported (steps 5.4–5.8). Still open: portrait/social output profiles (9×16 recompose, not crop) and a short muted web-loop. See references/production-notes.md.

Bundled files

The model reads these on demand while the skill is loaded. They are exposed as readable files and are never executed.

Frequently asked questions

What does the Devrel Video AI skill do?

Produce a silent DevRel-style product walkthrough video from a web URL. Playwright records the live flow, HyperFrames composes title/frame/chapters/CTA, FFmpeg masters. Use when asked to record, make, or update a product demo, feature walkthrough, catalog tour, or promo video from a web product.

Why use Devrel Video on TypingMind?

Because you install it once and use it with any model. Devrel Video is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Devrel Video in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/aaitor/skill-video-studio/tree/main/.claude/skills/devrel-video. TypingMind reads its SKILL.md and bundles its files and installs it as a skill you can enable per chat.

Which AI models can use Devrel Video?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Devrel Video?

As many as you like. As long as a model supports skills, you can use Devrel Video with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Devrel Video AI skill free?

Yes. It is published on GitHub by aaitor under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇