wjs-teaching-english

$npx mdskill add jianshuo/claude-skills/wjs-teaching-english

Turn an English word into a self-contained video lesson

  • Users request teaching or learning an English word as a video.
  • Deploys search-app API to find relevant clips and integrates them with Claude's TTS.
  • Uses ffmpeg for transcoding and Volcengine SDK for text-to-speech functionality.
  • Generates an HLS playlist containing the requested word, intro card, and CTA.

SKILL.md

.github/skills/wjs-teaching-englishView on GitHub ↗
---
name: wjs-teaching-english
description: Use when the user wants to teach / learn an English word as a video — turn a single English word into a self-contained HLS "supercut" lesson built from the mira video base. Stitches every season2 clip where the word is spoken (via the search-app API) into one .m3u8, prepended with a Claude-written bilingual word-intro card (word + IPA + 中文 gloss + usage, Volcano TTS) and appended with a 关注王建硕 CTA card. No MP4 burn. Triggers — "teach <word>", "讲讲 <word>", "学英语 <word>", "把 <word> 做成视频", "/wjs-teaching-english <word>".
---

# Teach an English word as a video supercut

Turn one English word into a self-contained HLS lesson:

```
intro.ts  (word /IPA/ · 中文 gloss · usage + Volcano TTS)
   ⋯ EXT-X-DISCONTINUITY
[supercut] every season2 clip where the word is spoken  (search-app /api/playlist, COS URLs)
   ⋯ EXT-X-DISCONTINUITY
cta.ts    (关注王建硕 + Volcano TTS)
= search-app/out/<word>.m3u8
```

No MP4 is burned — only the two cards are rendered as tiny `.ts`, re-encoded to
match the supercut's codec so they play in any HLS player.

## Prerequisites (check once)

- `ffmpeg` / `ffprobe` on PATH (Homebrew).
- Python `volcengine` SDK (declared in mira `requirements.txt`, used for TTS):
  `python3 -c "import volcengine"`. If missing, ask the user to allow
  `pip3 install volcengine==1.0.58` (it's a pinned repo dependency).
- The deployed search-app at `https://search-app-three-kappa.vercel.app`
  (default). Override with `SEARCH_APP_BASE=http://localhost:3000` if running
  locally (needs Node ≥ 23.6 + `npm start`).

## Steps

1. **Get the word.** A single English word (or short phrase). If the user gave
   a sentence, pick the target word.

2. **Write the mini-lesson JSON.** YOU (Claude) author it — no dictionary API.
   Keep it accurate and concise. Save to a temp file, e.g. `/tmp/lesson.json`:

   ```json
   {
     "word": "love",
     "ipa": "/lʌv/",
     "pos": "v. / n.",
     "gloss": "爱,热爱",
     "usage": "下面是它在真实电影里的说法",
     "tts_text": "love. 爱。"
   }
   ```

   - `tts_text` is read aloud over the intro card — keep it to the word + a
     short 中文 gloss (Volcano reads mixed English/中文 fine).
   - `usage` is one short line shown on the card (≤ ~20 chars renders best at
     low resolutions).

3. **Build it:**

   ```bash
   cd /Users/jianshuo/code/mira/search-app
   python3 scripts/build_lesson.py --word love --lesson /tmp/lesson.json
   ```

   Useful flags: `--speaker zh_female_qingxin` (default), `--limit 300` (max
   clips), `--no-tts` (silent cards), `--base <url>`, `--out <dir>`.

4. **Report** the printed output path (`search-app/out/<word>.m3u8`) and the
   clip count. The `.m3u8` plus its sibling `<word>.intro.ts` / `<word>.cta.ts`
   are the deliverable; `out/` is git-ignored.

## Notes

- If the word has no clips, the script exits with "no clips match" and writes
  nothing — tell the user and suggest a more common word.
- Intro/CTA are encoded to the FIRST supercut segment's resolution/codec/fps so
  the first discontinuity needs no decoder re-init (avoids `bufferAppendError`).
- To play locally: `ffplay search-app/out/<word>.m3u8`, or serve the `out/`
  folder over HTTP and open in any HLS player (Safari plays `.m3u8` natively).

More from jianshuo/claude-skills

SkillDescription
wangjianshuo-perspective|
wjs-auditing-projectUse when the user asks to audit what's wrong with a project, "make it right", "看看项目出了什么问题", "为什么用户的需求还没上线", "为什么没提交App Store", "为什么没新build", or wants a holistic state-of-the-project check covering unmerged branches, stalled PRs, failed GitHub Actions, stale builds, plan drift (TODOS.md / ROADMAP), unreleased commits, and log errors. Runs read-only investigation, presents a grouped checklist, fixes only after explicit user confirmation. Aware of the Cathier iOS app workflow (Xcode + fastlane + auto-merge @claude PRs from in-app feedback).
wjs-burning-subtitlesUse when the user has a video + an SRT and wants the subtitles either burned into the pixels (libass, always-visible) or soft-muxed as a togglable track. Also handles the final composite step for the localization pipeline — burn subs, mix a dub track, and keep the original audio as a low-volume bed, all in ONE ffmpeg encode (no cascade). Verifies libass availability and auto-downloads a static evermeet ffmpeg build when Homebrew's stripped binary lacks it. Triggers — "烧字幕", "硬字幕", "burn subtitles", "burn-in subs", "embed subtitle", "soft mux SRT", "把字幕烧进视频", "做最终合成".
wjs-cleaning-spamUse when the user complains about spam on his X/Twitter posts — 同城面付 / 寻固炮 / 线下上门 / 免费破处 这类引流号在他推文下刷的 emoji 垃圾回复 — and wants them removed. Covers the last 7 days (X recent-search window). Triggers — "把这些spam删掉", "清理X垃圾回复", "推文下面好多引流号", "clean spam replies", "/wjs-cleaning-spam".
wjs-converting-text-to-videoUse when the user wants a 王建硕-style WeChat article (article.md) turned into a narrated short MP4 video — TTS voiceover via 火山引擎 Volcano TTS, HyperFrames CSS/GSAP animation per scene, subtle SFX, abstract watercolor background, full pipeline rendering to 1080×1920 portrait MP4 (30-90s). Triggers — "把这篇文章做成视频", "做一个解说视频", "讲解视频", "/wjs-converting-text-to-video".
wjs-converting-wp-to-hugoUse when migrating a WordPress site to a Hugo static site on GitHub Pages from a WXR export (.xml) plus the wp-content/uploads folder — preserving /archives/<id>/ URLs, localizing images, and deploying via GitHub Actions. Triggers — "把 WordPress 迁成 Hugo", "wordpress 转静态站", "migrate WordPress to Hugo", "WXR to Hugo", "publish WordPress to GitHub Pages", "/wjs-converting-wp-to-hugo".
wjs-distilling-styleUse when the user wants to capture a writer's voice from a few sample articles and rewrite text to sound like that author — "蒸馏文风", "提炼XX的风格", "把这篇改成XX的味儿", "学某某笔法改写", "mimic this writer", "match this author's style", "style transfer". Works for any author, 王建硕 included.
wjs-dubbing-videoUse when the user has a video + a target-language SRT and wants the video to actually speak that language — generates a time-aligned TTS voice dub. Routes by voice ID — Volcano (豆包) TTS for Chinese, edge-tts neural for any language. Defaults to one voice (single-speaker); opt-in multi-speaker via visual diarization. Outputs `*_<lang>_dub.mp4` with the dub audio in place of the original. Final mixing (audio bed + burn-in) is handed off to `/wjs-burning-subtitles`. Triggers — "配音", "中文配音", "Chinese dub", "voice over this", "dub the video", "TTS this SRT", "different voice for each speaker".
wjs-eating-and-growing吃一堑长一智 — 走完 5 步交互式反思(堑 → 自动输出 → 旧权重 → 新参数 → 替代动作),从「情绪复盘」推进到「行为训练」,把第一反应这一层 L3 权重练新。Use when 王建硕 reflects on a personal setback, mistake, or recurring pattern (反思, 复盘, 回顾, 总结教训, 吃一堑, 长一智, "这次又栽了", "怎么又这样", "为什么我总是…", "想开点都做不到", "知道道理但做不到"). For the user as a human, not for Claude's task post-mortems.
wjs-editing-multicamUse when the user has 2+ recordings of the same event (each with a `.sync.json` sidecar from wjs-syncing-multicam) and wants them combined into a single MP4 — auto-switching between cams second-by-second on audio energy, with optional picture-in-picture inset. Triggers — "auto-edit multicam", "做个剪辑", "切几个机位", "把这几个视频合成一个", "combine these angles", "PiP overlay".