polli-video

GitHub

用于录制 polli CLI 终端演示视频的技能,结合 VHS、Polli 语音和背景音乐生成社交媒体剪辑。提供 BlackHole 实时捕获或 ffmpeg 后期合成两种管道方案。

.claude/skills/polli-video/SKILL.md pollinations/pollinations

Trigger Scenarios

录制 CLI 演示视频 制作社交媒体短视频 迭代 .tape 脚本

Install

npx skills add pollinations/pollinations --skill polli-video -g -y
More Options

Non-standard path

npx skills add https://github.com/pollinations/pollinations/tree/main/.claude/skills/polli-video -g -y

Use without installing

npx skills use pollinations/pollinations@polli-video

指定 Agent (Claude Code)

npx skills add pollinations/pollinations --skill polli-video -a claude-code -g -y

安装 repo 全部 skill

npx skills add pollinations/pollinations --all -g -y

预览 repo 内 skill

npx skills add pollinations/pollinations --list

SKILL.md

Frontmatter
{
    "name": "polli-video",
    "description": "Record terminal demo videos of the polli CLI using VHS (charmbracelet) with polli-generated voiceover and background music. Ships a working `example\/demo.tape` + `example\/render.sh` pipeline. Use when the user asks to make, record, or iterate on a polli demo video, LinkedIn\/social clip of the CLI, or any terminal screencast for pollinations.",
    "allowed-tools": "Bash(vhs *), Bash(ffmpeg *), Bash(ffprobe *), Bash(sox *), Bash(afplay *), Bash(polli *), Bash(open *), Bash(ls *), Bash(pkill *), Bash(rm *), Bash(cp *), Bash(mv *), Read, Write, Edit"
}

polli-video — record polli CLI demos

VHS records silent terminal video. Polli generates audio. ffmpeg merges. VHS cannot capture system audio — either capture it live via BlackHole, or overlay narration in post with adelay.

When to use

  • Demo video for polli CLI, pollinations.ai, or terminal workflows
  • LinkedIn / social clip with voiceover and lofi background
  • Iterating on an existing .tape script

Quick start

mkdir -p temp/vhs-demo && cp .claude/skills/polli-video/example/* temp/vhs-demo/
cd temp/vhs-demo
# Set system default output → BlackHole 2ch (see Pipeline A)
./render.sh

Produces demo.mp4. Edit demo.tape to change content.

Pipeline A — BlackHole live capture (recommended)

Single command, no adelay math, perfect sync. Requires BlackHole 2ch and default system output set to it (Option+click menu-bar speaker, or SwitchAudioSource -s "BlackHole 2ch").

See example/render.sh — archives old renders, captures while VHS runs, muxes trimmed to video length with a 5s audio pre-roll shift (ffmpeg startup + API roundtrip offset) and a 3s audio fade-out at the end. Copy and adapt.

Capture tool: sox over ffmpeg avfoundation. ffmpeg dropped samples on long recordings (choppy audio) even with -thread_queue_size 4096, -async 1, nice -20. sox + coreaudio is stable end-to-end, addresses device by name ("BlackHole 2ch") instead of a flaky index, and needs no post-trim:

AUDIODRIVER=coreaudio sox -q -c 2 -r 48000 -t coreaudio "BlackHole 2ch" \
    -c 2 -r 48000 -b 16 captured.wav 2>/tmp/sox-capture.log &

Music gen must use --play so BlackHole captures it. Switch default output back to Speakers after.

Pipeline B — post-hoc ffmpeg overlay (fallback)

When BlackHole unavailable. Pre-generate narration + music, overlay with manual timestamps:

vhs demo.tape   # produces demo-silent.mp4
ffmpeg -y -i demo-silent.mp4 -i speech.mp3 -i music.mp3 \
  -filter_complex "[1:a]adelay=16000|16000[narr]; \
                   [2:a]volume=0.18,atrim=end=75[bg]; \
                   [narr][bg]amix=inputs=2:duration=longest[a]" \
  -map 0:v -map "[a]" -c:v copy -c:a aac demo.mp4

adelay=16000|16000 = ms, left|right (must be stereo pair). Tune to tape timestamp where narration should hit. Ducking: 0.12–0.20 under narration, 0.25–0.35 music-only. Never pass -shortest — truncates video to shortest audio.

VHS tape conventions

  • Set Shell "bash" is mandatory. zsh + long Type lines triggers a VHS command-concatenation bug: two consecutive long commands get glued onto a single prompt line and the Enter between them is lost. Root cause is zsh's ZLE + VHS's wall-clock-timed CDP keystroke injection (no prompt-wait primitive). Bash's simpler line editor has no such race. Not fixable with Wait+Line (regex fails on colored prompts), precmd hooks (VHS #691), longer Sleeps, or Ctrl+L substitution. Just use bash.
  • 960×720 or 960×640, Menlo 16pt — reads on mobile, fits polli gen text --model X "...".
  • Absolute path in Hide-block cd; relative path in Output (parser splits on /).
  • Always export FORCE_COLOR=1 in Hide — VHS pty fails isTTY, chalk strips colors otherwise.
  • Scene titles via ANSI from shell (no VHS primitive). \033[1;38;5;141m = polli purple.
  • announce() pattern: one function that prints the bold title AND fires backgrounded TTS. Every later scene is a one-liner. See example/demo.tape.

Canonical bash Hide block (copy verbatim — fixes job notices, heredoc prompts, prompt trailing-line):

Set Shell "bash"
Hide
Type "cd /absolute/path/to/working/dir"
Enter
Type "export FORCE_COLOR=1"
Enter
Type "export PS1='» '"
Enter
Type "export PS2='» '"
Enter
Type "PROMPT_COMMAND='echo'"
Enter
Type "set +m"
Enter
Type "clear"
Enter
Show
  • PS2='» ' — hides heredoc/continuation > prompts that leak on wrapped Type lines.
  • PROMPT_COMMAND='echo' — trailing blank line between scenes so output doesn't crash into the next prompt.
  • set +m — disables job-control, suppresses [1] 12345 notices from & backgrounding.
  • Wrap backgrounded commands in a subshell anyway: ( cmd & ) never prints a PID even in interactive shells.

The announce function

One-liner per scene: prints a bold purple title AND fires backgrounded TTS. The sed strip removes ElevenLabs emotion cues ([whispers], [excited], …) from the printed title while keeping them in the spoken audio.

announce() {
  printf '\n\033[1;38;5;141m»» %s\033[0m\n\n' "$(sed -E 's/\[[^]]*\] *//g' <<< "$1")"
  ( polli gen audio --play --output /tmp/narr-$$-$RANDOM.mp3 "$1" >/dev/null 2>&1 & )
}

Usage:

Type `announce "[excited] first — we need some backing music"`
Enter

ElevenLabs emotion cues (must use ElevenLabs-backed voice, e.g. default sage): [whispers], [excited], [confident], [curious], [sighs], [laughs]. Place inline — the TTS engine interprets them; the sed strip keeps the on-screen text clean.

Why subshell ( cmd & ), not bare & or disown:

  • Bare & in a non-interactive bash (VHS) still prints [1] 12345 — even with set +m, occasional leakage.
  • disown after & still shows the job-start notice.
  • ( cmd & ) spawns the background job inside a subshell that exits immediately, so no job record is ever attached to the parent shell — nothing to print.

Gotchas

Symptom Cause Fix
Two commands merge on one line, Enter eaten zsh + long Type (ZLE race) Set Shell "bash"
heredoc> or > prompts visible Wrapped line, zsh/bash PROMPT2 export PS2='» '
[1] 12345 leaks on screen Bash job-control notice set +m + ( cmd & ) subshell
Scene collides with previous output No trailing newline PROMPT_COMMAND='echo'
Nested temp/vhs-demo/temp/vhs-demo/ Absolute path in Output Use relative; cd in Hide
Typing takes forever Default TypingSpeed 50ms Set 12–20ms
Colors stripped VHS pty, no FORCE_COLOR export FORCE_COLOR=1
Font renders wrong JetBrains Mono not on macOS Use Menlo
FontSize >18 wraps prompts 960 width Stick with 16
BG output corrupts next command & with stdout live cmd >/dev/null 2>&1 &
/ multibyte char eats adjacent chars VHS Type + Unicode edge case Drop the arrow; use plain ASCII
Choppy/dropped audio in long capture ffmpeg avfoundation Use sox -t coreaudio "BlackHole 2ch"
Video only 2s long -shortest on ffmpeg Drop -shortest
No sound in final mp4 Missing audio map -map 0:v -map "[a]"
BlackHole not found by ffmpeg Wrong device index Use sox + device name instead
Disk fills during capture Uncompressed wav, forgot to trap trap "kill $FFPID" EXIT
Final MP4 narration lands too late ffmpeg startup + API pre-roll In mux: ffmpeg -ss 5 -i captured.wav … (tune 3–6s)
Music cuts abruptly at end No fade filter Add -af "afade=t=out:st=$((VID_DUR-3)):d=3"
afade filter errors No option name near '3' on st=66,36 Locale uses comma for decimals Wrap the awk computing FADE_START with LC_ALL=C
Punctuation/wording cached across renders Pollinations text cache keys on exact string Change a character (swap ·;,, add !) each re-render

Voice selection

Default: sage. Others: fin, callum, onyx, rachel. Preview:

polli gen audio --voice <name> --output sample.mp3 "test line" && afplay sample.mp3

Full list: polli models --type audio --json | jq '.[].voices'.

Music (elevenmusic)

Deterministic cache — same prompt+duration = same bytes. Always --instrumental. Match duration to ffprobe demo-silent.mp4. Example prompt: "lofi instrumental hip hop, warm analog, jazzy bass".

Demo design principles

  • Open silent with polli --help — orients without narration.
  • One audio moment per scene, not many.
  • Hold scenes: help ~4s, streaming text 10–20s, ASCII outro 15–17s.
  • Payoff produces something reusable (the post, an image, a doc).
  • Streaming > buffered — lean into polli's default streaming reveal (drop --no-stream when used in a recorded tape so the audience sees generation happening live).
  • End with a punchy ASCII wordmark outro (see "Streaming outros" section).
  • 960×720 or 960×640 beats 1920×1080 on mobile feeds.

Brand voice for generated content

See operations/social/prompts/tone/linkedin.md, operations/social/prompts/brand/about.md.

  • Dry, information-dense, anti-corporate.
  • No "excited to announce", "game-changing", hashtag spam.
  • Plain text for LinkedIn (markdown renders raw).

Generating the announcement post (lessons)

Model selection (ranked for this task):

  • claude-fastpick this for live demos. Consistent ~4s latency, never leaks scaffolding in this prompt shape. Voice slightly flatter than glm but reliability wins when a Sleep 30000ms hold has to cover the call.
  • glm — best voice quality when it works. But latency is wildly variable (12s first call → 31s next → sometimes >60s); not safe behind a fixed Sleep budget. Use for offline one-shots, not live-tape renders.
  • kimi — strong rhythm, hacker-genz feel. Solid backup.
  • openai — leaks prompt scaffolding verbatim (e.g. sign-off:, 110w, your own line-1 hook), overshoots word count. Avoid.
  • gemini-search / perplexity-fast — web-search adds citation markers [1][2]; hallucinate features, inflate corpo voice. Avoid for this.

Call flags:

  • Use --no-stream. Streaming + > file hangs on long prompts; --no-stream returns in 3–5s.
  • Never wrap polli in timeout N — it breaks the stdout flush and always kills the call.

Input context (what to pipe in):

  • polli --help only — leanest, forces the model to describe the command surface without repackaging README bullet points.
  • Feeding the README causes models to repeat README-specific phrases ("humans, AI agents, and everything in between") and hallucinate flags (--budget etc).
  • --help limitation: doesn't expose npm package name → model guesses polli-cli. Patch install line manually.

Prompt shape (compressed, declarative, no imperative wordiness):

  • State the task (announce polli on LinkedIn), not a procedure.
  • Voice in 1 line with · separators. Let the model interpret rather than listing banned phrases.
  • Don't put counted claims in the prompt (7-verb CLI) — every model echoes them. Just list the verbs.
  • Don't say "scroll-stopper" or "your own line-1 hook" — models paste those labels literally.
  • Keep no md · no 🚀 · no corpo as the only negative constraints. More bans → defensive, boring output.
  • Ask for sign-off not CTA.

Final prompt used (LinkedIn launch post):

↑ polli --help for polli CLI.
task: announce polli on LinkedIn. reformat this into a post.
voice: hacker-genz .nfo irc-drop · dry · emojis 🐝💾⚡🔮🧪👁️🌀 scattered
100-130w · sharp sign-off · no md · no 🚀 · no corpo

Pipe in via: polli --help | polli gen text --model claude-fast --no-stream "<prompt>".

For live tape renders (where a Sleep Xms must cover the call): use claude-fast — ~4s predictable. For offline post generation without timing constraints, glm gives slightly better voice but polli --help | polli gen text --model glm --no-stream … may take 10–60s.

Parallel batching gotcha: 3+ concurrent calls to the same model hit Cloudflare 520. Run sequentially for reliable batches.

Streaming outros (ASCII demoscene)

polli gen text streams by default — no animate helper or frame splitter needed. Pipe straight to the terminal and the characters appear as generated:

Type "clear"
Enter
Sleep 400ms
Type `polli gen text --model claude "ascii frame 50×20; spell POLLI big block letters centered. organic evolving mycelium decor — demoscene."`
Enter
Sleep 17000ms   # hold long enough for full generation + read time

Prompt engineering notes for ASCII wordmarks:

  • Small prompts work best. Every added constraint (CA rules, 6 frames, palette, emoji) pushes the model away from the actual word. Keep it one sentence.
  • Strict letter constraints ("P O L L I — two L's") drift anyway with claude-fast. Use claude (non-fast) for final renders; claude-fast often outputs "POLL" / "PELL" / random block shapes.
  • Canvas 50×20 is the sweet spot for 960-wide terminals at FontSize 16. 60×40 overflows vertically.
  • No color/palette mentions — ASCII is monochrome. Confuses the model.
  • One keyword for "evolving" (e.g. mycelium, cellular automaton) > a full description. But cellular automaton sometimes confuses the model into abandoning the word entirely — mycelium is more reliable.

Layered emotion cues in announce()

ElevenLabs handles multiple [cue] markers in one line, changing tone mid-sentence. Useful for punchy payoff lines:

announce "[playful] confused? just ask your agent to [whispers] install me... [curious] install me? [excited] install me!!"

The sed strip removes all cues from the printed text, so the screen just shows »» confused? just ask your agent to install me... install me? install me!! while the audio layers whisper → curious → excited across three repetitions. The ... and ? / !! punctuation gives ElevenLabs natural beats to change register.

Files

  • example/demo.tape — canonical working tape (polli launch demo, 5 scenes incl. streaming ASCII outro, bash, claude)
  • example/render.sh — canonical pipeline (sox BlackHole capture + mux with 5s audio pre-roll + 3s fade-out)
  • example/.gitignore — ignores *.mp4, *.wav, music.mp3, speech.mp3, .DS_Store, timestamped archives

Render artifacts (regenerable, gitignored): demo.mp4, demo-silent.mp4, captured.wav, music.mp3, speech.mp3. Previous renders are auto-archived to <base>-vHHMM.<ext> by render.sh.

Version History

  • 8303332 Current 2026-08-20 04:57

    重构:将社交管道移至 operations 目录下,并更新数据消费者指向。

  • 99bce92 2026-07-25 10:39

Same Skill Collection

.claude/skills/abuse-detection/SKILL.md
.claude/skills/candidate-evaluation/SKILL.md
.claude/skills/code-formatting/SKILL.md
.claude/skills/community-leaderboard/SKILL.md
.claude/skills/enter-services/SKILL.md
.claude/skills/issue-maker/SKILL.md
.claude/skills/manage-vast-gpu-fleet/SKILL.md
.claude/skills/model-debugging/SKILL.md
.claude/skills/model-management/SKILL.md
.claude/skills/monitor-services/SKILL.md
.claude/skills/polli/SKILL.md
.claude/skills/r2-glacier-migration/SKILL.md
.claude/skills/spending-analysis/SKILL.md
.claude/skills/sync-production/SKILL.md
.claude/skills/tinybird-deploy/SKILL.md
.claude/skills/voting-status/SKILL.md
.claude/skills/web-research/SKILL.md
apps/openclaw/skills/founder-meditation/SKILL.md
packages/polli-cli/SKILL.md

Metadata

Files
0
Version
8303332
Hash
35003a02
Indexed
2026-07-25 10:39

- 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-08-22 07:28
浙ICP备14020137号-1 $방문자$