{"id":"79d19c4f-404e-4b2c-bd15-3bbd5106baa2","entityType":"agent","slug":"clawhub-0x00000003-remotion-word-highlight-subtitles","name":"Remotion 逐词高亮字幕","canonicalUrl":"https://www.xpersona.co/agent/clawhub-0x00000003-remotion-word-highlight-subtitles","canonicalPath":"/agent/clawhub-0x00000003-remotion-word-highlight-subtitles","generatedAt":"2026-10-13T05:30:12.475Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T22:06:48.033Z","emptyReason":null},"description":"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。 Skill: Remotion 逐词高亮字幕 Owner: 0x00000003 Summary: 用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。 Tags: latest:0.1.4, remotion:0.1.4, short-video:0.1.4, subtitles:0.1.4, video:0.1.4, whisper:0.1.4 Version history: v0.1.4 | 2026-05-14T12:53:13.796Z | user Enforce larger subtitle sizing and strip display punctuation by default. v0.1.3 | 2026-05-03T16:42:58.642Z | user Make transcript QA mandatory before rendering; add cross-tok","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 987 downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s170qhqbpmn4wvbe5p927d7hd183mmwq:remotion-word-highlight-subtitles","sourceUrl":"https://clawhub.ai/0x00000003/remotion-word-highlight-subtitles","homepage":"https://clawhub.ai/0x00000003/skills/remotion-word-highlight-subtitles","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/0x00000003/remotion-word-highlight-subtitles","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/0x00000003/skills/remotion-word-highlight-subtitles","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。 Skill: Remotion 逐词高亮字幕 Owner: 0x00000003 Summary: 用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。 Tags: latest:0.1.4, remotion:0.1"},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T22:06:48.033Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T22:06:48.033Z","emptyReason":null},"stars":null,"forks":null,"downloads":987,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"0.1.4","tractionLabel":"987 downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T22:06:48.014Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T22:06:48.033Z","lastCrawledAt":"2026-10-11T22:06:48.014Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T22:06:48.014Z","lastVerifiedAt":null,"highlights":[{"version":"0.1.4","createdAt":"2026-05-14T12:53:13.796Z","changelog":"Enforce larger subtitle sizing and strip display punctuation by default.","fileCount":6,"zipByteSize":13935},{"version":"0.1.3","createdAt":"2026-05-03T16:42:58.642Z","changelog":"Make transcript QA mandatory before rendering; add cross-token phrase corrections and readable splitting for long Whisper segments. Details: https://github.com/0x00000003/remotion-word-highlight-subtitles","fileCount":5,"zipByteSize":11347},{"version":"0.1.2","createdAt":"2026-05-03T15:51:34.659Z","changelog":"Use the GitHub-hosted effect preview image in README while keeping the GitHub guide link in the skill instructions.","fileCount":5,"zipByteSize":8393},{"version":"0.1.1","createdAt":"2026-05-03T15:49:19.694Z","changelog":"Add GitHub README and effect preview link to the skill instructions.","fileCount":5,"zipByteSize":8353},{"version":"0.1.0","createdAt":"2026-05-03T15:10:15.082Z","changelog":"Initial public release: Whisper word timestamps to Remotion current-word highlighted subtitles.","fileCount":4,"zipByteSize":6071}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s170qhqbpmn4wvbe5p927d7hd183mmwq:remotion-word-highlight-subtitles","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-13T05:30:12.474Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-0x00000003-remotion-word-highlight-subtitles/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T22:06:48.033Z","emptyReason":null},"readme":"Skill: Remotion 逐词高亮字幕\n\nOwner: 0x00000003\n\nSummary: 用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。\n\nTags: latest:0.1.4, remotion:0.1.4, short-video:0.1.4, subtitles:0.1.4, video:0.1.4, whisper:0.1.4\n\nVersion history:\n\nv0.1.4 | 2026-05-14T12:53:13.796Z | user\n\nEnforce larger subtitle sizing and strip display punctuation by default.\n\nv0.1.3 | 2026-05-03T16:42:58.642Z | user\n\nMake transcript QA mandatory before rendering; add cross-token phrase corrections and readable splitting for long Whisper segments. Details: https://github.com/0x00000003/remotion-word-highlight-subtitles\n\nv0.1.2 | 2026-05-03T15:51:34.659Z | user\n\nUse the GitHub-hosted effect preview image in README while keeping the GitHub guide link in the skill instructions.\n\nv0.1.1 | 2026-05-03T15:49:19.694Z | user\n\nAdd GitHub README and effect preview link to the skill instructions.\n\nv0.1.0 | 2026-05-03T15:10:15.082Z | user\n\nInitial public release: Whisper word timestamps to Remotion current-word highlighted subtitles.\n\nArchive index:\n\nArchive v0.1.4: 6 files, 13935 bytes\n\nFiles: agents/openai.yaml (220b), README.md (6619b), scripts/whisper_json_to_captions.py (12594b), skill-card.md (2539b), SKILL.md (12777b), _meta.json (152b)\n\nFile v0.1.4:SKILL.md\n\n---\nname: remotion-word-highlight-subtitles\ndescription: Add word-level highlighted subtitles to local short videos using Whisper word timestamps and Remotion rendering.\nversion: 0.1.4\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - python3\n        - ffmpeg\n        - ffprobe\n        - whisper\n        - node\n        - npm\n    emoji: \"🎬\"\n---\n\n# Remotion Word Highlight Subtitles\n\n## Overview\n\nThis skill turns a local video into a subtitled video using the reusable \"fine version\": Whisper word timestamps plus Remotion-rendered current-word highlighting. Use this instead of plain SRT burn-in unless the user explicitly asks for simple static subtitles.\n\nDetailed usage guide, README, and effect preview: https://github.com/0x00000003/remotion-word-highlight-subtitles\n\n## Trigger Phrases\n\nUse this skill for requests like:\n\n- \"给这个视频添加字幕：/path/to/video.mp4\"\n- \"给这个视频加逐词高亮字幕\"\n- \"按之前 Remotion 那个字幕方案处理这个视频\"\n- \"重新转写 word timestamps，然后加当前词高亮字幕\"\n\nIf the user only gives one video path, write the output next to the source video.\n\n## Defaults\n\n- Source: local `.mp4`, `.mov`, `.m4v`, or audio/video file with usable audio.\n- Output: `<source-stem>_remotion逐词高亮字幕.mp4` in the same directory unless the user names another target.\n- Transcription: Whisper with word timestamps, Chinese by default: `--language zh --word_timestamps True --output_format json`.\n- Transcript QA: mandatory before rendering. Build a tiny glossary from the user prompt, folder/file names, visible context, and topic; correct obvious ASR mistakes in product/model/person/place names, English terms, numbers, and homophones.\n- Caption data: Remotion caption chunks built from Whisper words, with token-level `startMs` and `endMs`. Long Whisper segments must be split by punctuation, timing gaps, duration, or length before rendering.\n- Caption position: keep all captions in a screenshot-friendly lower band, slightly above the bottom UI area. Start around `height * 0.28` bottom padding, then adjust only if the source framing clearly needs it.\n- Visual style: bold Chinese UI font, white base text, current token yellow, optional sparse keyword accent, and black shadow/outline for readability.\n- Subtitle sizing: treat font size as a hard visual gate, not a loose style hint. For landscape 1080p footage, target `height * 0.056` (about `60px`) and never render below `56px`; for vertical `720x1280`, target `40-46px`. For other sizes, scale from height but enforce the same perceived size in still QA.\n- Display punctuation: default subtitles are clean Chinese display text. Strip visible sentence punctuation from caption text and token text before rendering, including `。 ， 、 ？ ！ ： ； , . ? ! : ;`. Keep punctuation only for splitting/timing unless the user explicitly asks for verbatim punctuation.\n- Verification: check the rendered file exists, keeps audio, matches the source duration closely, and visually inspect stills before accepting the style.\n\n## Workflow\n\n1. Inspect the source with `ffprobe` for width, height, fps, duration, and audio presence.\n2. Build a small domain glossary before transcription. Include likely product names, model names, people, places, mixed Chinese/English terms, numbers, and terms hinted by the folder or filename.\n3. Run Whisper word timestamp transcription. Prefer a cached/local model that works on the machine; `turbo` is a good default when available. Use `--initial_prompt` when the glossary contains high-risk names or English terms.\n4. Do a mandatory transcript QA pass before rendering. Read every segment, compare it with the video's topic/context, and create a correction map for obvious ASR mistakes. Do not render while known mistakes remain.\n5. Convert the Whisper JSON to `public/captions.json` using `scripts/whisper_json_to_captions.py`, passing corrections with `--replace` or `--replace-phrase`. Apply transcript corrections, merge terms, strip display punctuation, and keep the helper's caption splitting enabled if Whisper returns long paragraphs.\n6. Build or reuse a small Remotion project in the video's folder. Copy the video to `public/input.mp4` or encode an H.264 compatibility copy as `public/input-h264.mp4`.\n7. Set the Remotion composition to the exact source width, height, fps, and duration in frames.\n8. Before the full render, render and inspect at least two stills from the Remotion composition: one long/two-line caption and one dense keyword/current-token caption. Fix muddy text, excessive outline, large dark backing, bad line breaks, too-small text, visible display punctuation, poor placement, or remaining typo/wrong-character subtitles before rendering the final video.\n9. Render with Remotion to the output path next to the source.\n10. Verify the final output with `ffprobe`; extract and inspect a still from the rendered video to confirm the final encoded file kept the approved subtitle look.\n\n## Whisper Command\n\nUse this shape, adjusting model and paths as needed:\n\n```bash\nwhisper \"/absolute/path/video.mp4\" --model turbo --language zh --word_timestamps True --output_format json --output_dir \"/absolute/path\"\n```\n\nFor names and mixed Chinese/English topics, add a short prompt rather than relying on Whisper to infer them:\n\n```bash\nwhisper \"/absolute/path/video.mp4\" \\\n  --model turbo \\\n  --language zh \\\n  --word_timestamps True \\\n  --output_format json \\\n  --initial_prompt \"本视频可能出现这些词：Cursor、Kimi 2.5、马斯克、AI大模型、转推、套壳。\" \\\n  --output_dir \"/absolute/path\"\n```\n\nIf Whisper fails on the video container, extract audio first:\n\n```bash\nffmpeg -y -i \"/absolute/path/video.mp4\" -vn -ac 1 -ar 16000 \"/absolute/path/video_audio.wav\"\n```\n\nThen run Whisper on the WAV and keep the output naming clear.\n\n## Mandatory Transcript QA\n\nAfter Whisper finishes, print or read the segment transcript before building captions. Treat this as a required gate, not a nice-to-have.\n\nCheck especially:\n\n- product, model, company, person, and place names\n- mixed Chinese/English terms such as `Cursor`, `Kimi 2.5`, `ChatGPT`, `Claude`, `OpenAI`\n- numbers, dates, model versions, and acronyms\n- Chinese homophones that are plausible but wrong in context, such as \"却\" versus \"圈\" or \"死腿\" versus \"转推\"\n- low-confidence words if the Whisper JSON includes probabilities\n\nCreate a short correction map and apply it before rendering. Use `--replace` for single-token fixes and `--replace-phrase` for words split across adjacent Whisper tokens.\n\nExample:\n\n```bash\npython3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --replace-phrase \"科舍=Cursor\" \\\n  --replace-phrase \"KMI 2.5=Kimi 2.5\" \\\n  --replace-phrase \"Kimi 2.5=Kimi 2.5\" \\\n  --replace-phrase \"AI却=AI圈\" \\\n  --replace-phrase \"死腿=转推\" \\\n  --merge-term \"Cursor\" \\\n  --merge-term \"Kimi 2.5\" \\\n  --keyword \"AI\" \\\n  --keyword \"Kimi 2.5\"\n```\n\nIf a correction is uncertain, prefer rerunning Whisper with a better `--initial_prompt` or inspect the relevant audio/video moment before deciding. Report the correction map in the final response.\n\n## Caption JSON\n\nRemotion should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"我们用手机随便拍张照片\",\n    \"startMs\": 0,\n    \"endMs\": 1600,\n    \"tokens\": [\n      { \"text\": \"我们\", \"startMs\": 0, \"endMs\": 300, \"keyword\": false },\n      { \"text\": \"手机\", \"startMs\": 440, \"endMs\": 700, \"keyword\": true }\n    ]\n  }\n]\n```\n\nUse the helper script:\n\n```bash\npython3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --keyword \"提示词\" \\\n  --keyword \"Codex\" \\\n  --replace-phrase \"错识别词=正确词\" \\\n  --max-caption-chars 28 \\\n  --max-caption-duration-ms 4200 \\\n  --split-gap-ms 260 \\\n  --min-punctuation-caption-ms 900\n```\n\nRun the transcript QA pass before this conversion command. If any correction changes adjacent tokens into one display term, also pass that final term with `--merge-term` or a same-text `--replace-phrase` so the highlight appears as a clean word instead of broken characters.\n\nBy default, `scripts/whisper_json_to_captions.py` strips visible display punctuation from final caption text and tokens while still using punctuation as a split signal. Do not pass `--keep-display-punctuation` unless the user explicitly asks for verbatim transcript punctuation. If building JSON manually, remove punctuation-only tokens and trim trailing punctuation before rendering.\n\nThe helper splits long Whisper segments by visible length, duration, punctuation, and word timing gaps. Keep this behavior on for short-video subtitles; otherwise a single Whisper paragraph can become an unreadable multi-line caption.\n\n## Remotion Caption Layer Requirements\n\nThe caption layer should:\n\n- Use `OffthreadVideo` for the source video.\n- Load `captions.json` with `delayRender`, `continueRender`, and `staticFile`.\n- Find the active caption by `currentMs >= startMs && currentMs < endMs`.\n- Highlight the active token when `currentMs` is within the token's timing.\n- Use keyword coloring only as a secondary accent; the current spoken token is the main effect.\n- Keep `letterSpacing: 0`.\n- Render clean display subtitles without sentence-final punctuation. Do not show comma, period, question mark, exclamation mark, colon, semicolon, or dunhao tokens unless the user asked for verbatim punctuation.\n- Treat caption size as a hard gate. For 1080p landscape, the rendered subtitle should be around `60px` and never below `56px`; if a still looks like small UI annotation text, enlarge and rerender.\n- Keep all captions at the normal position; do not include special screenshot-sentence placement unless the user explicitly asks.\n- Do not use `WebkitTextStroke` as a thick Chinese subtitle outline. It easily eats the white fill at small resolutions. Prefer multi-direction `textShadow`; if `WebkitTextStroke` is used at all, keep it at or below `1.5px` and verify a still.\n- Do not use a large semi-transparent rounded black rectangle behind the whole caption by default. If the footage truly needs backing, use a very subtle per-line backing, opacity `<= 0.16`, tight padding, and verify it does not look like a dark banner.\n\nReject and revise any still where the caption has muddy/gray text, a thick black halo, a large black box, clipped words, awkward wrapping, visible sentence punctuation, text that is too small for the frame, or placement over the mouth/chin in a talking-head video.\n\nUse these style constants as the baseline:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst isLandscape = width >= height;\nconst baseCaptionFontSize = Math.round(height * (isLandscape ? 0.056 : 0.032));\nconst minCaptionFontSize = isLandscape && height >= 1000 ? 56 : Math.round(height * 0.032);\nconst captionFontSize = Math.max(baseCaptionFontSize, minCaptionFontSize);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\nconst outlinePx = Math.min(3, Math.max(1.5, captionFontSize * 0.055));\n```\n\nUse a clean shadow outline rather than a heavy stroke:\n\n```tsx\nconst textShadow = [\n  `${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `-${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 -${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx * 1.4}px ${outlinePx * 1.4}px rgba(0, 0, 0, 0.72)`,\n].join(\", \");\n```\n\nFor a `1920x1080` landscape video, this yields about `fontSize: 60`, and it must not fall below `56`. For a `720x1280` vertical video, this is roughly `paddingBottom: 358`, `fontSize: 41`, `maxWidth: 634`, and a `2px` outline. For the original `2160x2974` source that inspired this skill, the equivalent bottom padding was about `830`.\n\n## Keyword Handling\n\nIf the user does not specify keywords, infer a small set from the transcript:\n\n- product/tool names: `Codex`, `Remotion`, `Whisper`\n- content objects: `提示词`, `照片`, `手机`, `封面`\n- place names or nouns that carry the video's hook\n- numbers or outcomes that are important to the promise\n\nKeep keyword highlighting sparse. Too many colored words makes the active yellow word less clear.\n\n## Output Naming\n\nPrefer:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\nIf iterating for the same source, add `_v2`, `_v3`, etc. Do not overwrite the user's source file.\n\n## Final Response\n\nTell the user the output path, mention that it used the reusable Remotion + Whisper word timestamp flow, and include the transcript correction map or say no corrections were needed. If any verification step could not be run, say that plainly.\n\nFile v0.1.4:README.md\n\n# Remotion Word Highlight Subtitles\n\nUse Whisper word timestamps and Remotion to add short-video subtitles where the word currently being spoken is highlighted.\n\nThis Skill is designed for Chinese creator workflows where subtitles need to feel polished, readable, and screenshot-friendly.\n\n![Word highlight subtitle example](https://raw.githubusercontent.com/0x00000003/remotion-word-highlight-subtitles/main/assets/effect-word-highlight.jpg)\n\n## What It Does\n\n- Transcribes a local video with Whisper `word_timestamps`.\n- Converts Whisper's word-level JSON into Remotion-friendly `captions.json`.\n- Splits long Whisper paragraphs into readable caption chunks.\n- Requires a transcript QA pass before rendering so obvious ASR mistakes can be corrected.\n- Renders subtitles with Remotion instead of burning plain SRT text.\n- Highlights the current spoken word in yellow.\n- Optionally marks sparse keywords with a secondary accent.\n- Strips visible display punctuation by default while still using punctuation for caption splitting.\n- Enforces orientation-aware subtitle size floors so landscape subtitles do not render too small.\n- Keeps subtitles in a lower, screenshot-friendly band by default.\n- Writes the rendered video next to the source file.\n\nDefault output name:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\n## Installation\n\nInstall from ClawHub:\n\n```bash\nclawhub install remotion-word-highlight-subtitles\n```\n\nThen restart or reload your OpenClaw/Codex environment if your agent does not discover new skills immediately.\n\n## Example Prompts\n\nUse natural prompts like:\n\n```text\n给这个视频添加逐词高亮字幕：/absolute/path/to/video.mp4\n```\n\n```text\n按 Remotion 逐词高亮字幕方案，给这个视频加字幕：/absolute/path/to/video.mp4\n```\n\n```text\n重新转写 word timestamps，然后给这个视频加当前词高亮字幕：/absolute/path/to/video.mp4\n```\n\nThe agent should then follow the Skill workflow: inspect the video, transcribe with Whisper, prepare caption JSON, render with Remotion, and verify the output.\n\n## Requirements\n\nThe workflow expects these tools to be available locally:\n\n- `python3`\n- `ffmpeg`\n- `ffprobe`\n- `whisper`\n- `node`\n- `npm`\n- Remotion dependencies in the generated or reused Remotion project\n\nThe Skill does not upload your video anywhere by itself. It is intended for local video files and local rendering.\n\n## Workflow Summary\n\n1. Read source video metadata with `ffprobe`.\n2. Run Whisper with word-level timestamps:\n\n   ```bash\n   whisper \"/absolute/path/video.mp4\" \\\n     --model turbo \\\n     --language zh \\\n     --word_timestamps True \\\n     --output_format json \\\n     --output_dir \"/absolute/path/output-dir\"\n   ```\n\n3. Review the Whisper transcript before rendering. Build a correction map for obvious mistakes in names, model versions, English terms, numbers, and homophones.\n4. Convert Whisper JSON to Remotion caption data:\n\n   ```bash\n   python3 scripts/whisper_json_to_captions.py \\\n     \"/absolute/path/transcript.json\" \\\n     \"/absolute/path/remotion-project/public/captions.json\" \\\n     --replace-phrase \"错识别词=正确词\" \\\n     --max-caption-chars 28 \\\n     --max-caption-duration-ms 4200 \\\n     --min-punctuation-caption-ms 900 \\\n     --keyword \"提示词\" \\\n     --keyword \"Codex\"\n   ```\n\n5. Render the video with a Remotion component that reads `captions.json`.\n6. Inspect one or more still frames before the full render when the framing is uncertain.\n7. Verify the final video duration and audio with `ffprobe`.\n\n## Caption Style\n\nBaseline style choices:\n\n- Base text is white.\n- The current spoken word is yellow.\n- Keyword highlights are sparse and secondary.\n- Text uses a black shadow/outline, not a heavy stroke.\n- The caption position starts around `height * 0.28` bottom padding.\n- Landscape 1080p captions target about `60px` and must not render below `56px`.\n- Final display captions omit sentence punctuation unless the user asks for verbatim transcript punctuation.\n- Avoid large black subtitle boxes unless the footage truly needs extra contrast.\n\nRepresentative constants:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst isLandscape = width >= height;\nconst baseCaptionFontSize = Math.round(height * (isLandscape ? 0.056 : 0.032));\nconst minCaptionFontSize = isLandscape && height >= 1000 ? 56 : Math.round(height * 0.032);\nconst captionFontSize = Math.max(baseCaptionFontSize, minCaptionFontSize);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\n```\n\n## Caption JSON Format\n\nThe Remotion project should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"然后这个是意大利\",\n    \"startMs\": 11860,\n    \"endMs\": 13180,\n    \"tokens\": [\n      { \"text\": \"然后\", \"startMs\": 11860, \"endMs\": 12360, \"keyword\": false },\n      { \"text\": \"这个\", \"startMs\": 12360, \"endMs\": 12640, \"keyword\": false },\n      { \"text\": \"是\", \"startMs\": 12640, \"endMs\": 12780, \"keyword\": false },\n      { \"text\": \"意大利\", \"startMs\": 12780, \"endMs\": 13180, \"keyword\": true }\n    ]\n  }\n]\n```\n\n## Helper Script\n\nThe bundled script:\n\n```text\nscripts/whisper_json_to_captions.py\n```\n\nconverts Whisper JSON with `segments[].words[]` into the caption format above.\n\nUseful options:\n\n```bash\n--keyword \"提示词\"\n--keyword \"Codex\"\n--merge-term \"朋友圈\"\n--replace \"彭丽圈=朋友圈\"\n--replace-phrase \"科舍=Cursor\"\n--replace-phrase \"KMI 2.5=Kimi 2.5\"\n--max-caption-chars 28\n--max-caption-duration-ms 4200\n--split-gap-ms 260\n--min-punctuation-caption-ms 900\n--keep-display-punctuation\n```\n\nUse `--replace` for single-token corrections and `--replace-phrase` for corrections that span adjacent Whisper tokens, such as product names split into characters. Report the correction map when you deliver the final video.\n\nBy default, the helper uses punctuation as a split signal and then removes visible punctuation from final `caption.text` and token text. Use `--keep-display-punctuation` only when the user explicitly asks for verbatim punctuation.\n\nCaption splitting is enabled by default because Whisper may return long paragraph-like segments, especially when `--initial_prompt` is used. Keep the split settings unless you have inspected stills and confirmed longer captions remain readable.\n\n## Notes\n\nThis is a Skill for an AI agent, not a standalone one-command video editor. The Skill gives the agent a repeatable workflow and a helper script so it can create the Remotion project, render, and verify the result consistently.\n\n## License\n\nMIT-0. Free to use, modify, and redistribute. No attribution required.\n\nFile v0.1.4:_meta.json\n\n{\n  \"ownerId\": \"kn72xxfk73vbpw9t4yzms3ma5581mwqp\",\n  \"slug\": \"remotion-word-highlight-subtitles\",\n  \"version\": \"0.1.4\",\n  \"publishedAt\": 1778763193796\n}\n\nFile v0.1.4:skill-card.md\n\n## Description:\n\nAdd word-level highlighted subtitles to local short videos using Whisper word timestamps and Remotion rendering.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[0x00000003](https://clawhub.ai/user/0x00000003)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers, video creators, and agent users use this skill to transcribe local short videos, review and correct word-level captions, and render polished Chinese-oriented subtitles with current-word highlighting.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The workflow processes local media and writes rendered outputs, so users could choose the wrong input or output location.\n\nMitigation: Use only video files and output folders selected by the user, and keep the generated video separate from the source file.\n\nRisk: The default Whisper settings are optimized for Chinese-language subtitles and may produce inaccurate captions for other languages.\n\nMitigation: Change the Whisper language option for non-Chinese videos and complete the transcript QA pass before rendering.\n\nRisk: Missing or mismatched local rendering tools can cause failed renders, lost audio, or duration mismatches.\n\nMitigation: Verify python3, ffmpeg, ffprobe, whisper, node, npm, and Remotion dependencies, then inspect stills and check final duration and audio with ffprobe.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/0x00000003/skills/remotion-word-highlight-subtitles)\n- [Project documentation linked by skill](https://github.com/0x00000003/remotion-word-highlight-subtitles)\n- [Word highlight subtitle example image](https://raw.githubusercontent.com/0x00000003/remotion-word-highlight-subtitles/main/assets/effect-word-highlight.jpg)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance, files]\n\n**Output Format:** [Markdown guidance with shell commands, code snippets, and JSON caption data]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces Remotion caption JSON and guidance for rendering a local MP4 subtitle output; expects local python3, ffmpeg, ffprobe, whisper, node, and npm.]\n\n## Skill Version(s):\n\n0.1.4 (source: frontmatter and server release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nFile v0.1.4:agents/openai.yaml\n\ninterface:\n  display_name: \"Remotion 逐词高亮字幕\"\n  short_description: \"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。\"\n  default_prompt: \"给这个视频添加逐词高亮字幕：\"\n\nArchive v0.1.3: 5 files, 11347 bytes\n\nFiles: agents/openai.yaml (220b), README.md (5739b), scripts/whisper_json_to_captions.py (11364b), SKILL.md (10840b), _meta.json (152b)\n\nFile v0.1.3:SKILL.md\n\n---\nname: remotion-word-highlight-subtitles\ndescription: Add word-level highlighted subtitles to local short videos using Whisper word timestamps and Remotion rendering.\nversion: 0.1.3\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - python3\n        - ffmpeg\n        - ffprobe\n        - whisper\n        - node\n        - npm\n    emoji: \"🎬\"\n---\n\n# Remotion Word Highlight Subtitles\n\n## Overview\n\nThis skill turns a local video into a subtitled video using the reusable \"fine version\": Whisper word timestamps plus Remotion-rendered current-word highlighting. Use this instead of plain SRT burn-in unless the user explicitly asks for simple static subtitles.\n\nDetailed usage guide, README, and effect preview: https://github.com/0x00000003/remotion-word-highlight-subtitles\n\n## Trigger Phrases\n\nUse this skill for requests like:\n\n- \"给这个视频添加字幕：/path/to/video.mp4\"\n- \"给这个视频加逐词高亮字幕\"\n- \"按之前 Remotion 那个字幕方案处理这个视频\"\n- \"重新转写 word timestamps，然后加当前词高亮字幕\"\n\nIf the user only gives one video path, write the output next to the source video.\n\n## Defaults\n\n- Source: local `.mp4`, `.mov`, `.m4v`, or audio/video file with usable audio.\n- Output: `<source-stem>_remotion逐词高亮字幕.mp4` in the same directory unless the user names another target.\n- Transcription: Whisper with word timestamps, Chinese by default: `--language zh --word_timestamps True --output_format json`.\n- Transcript QA: mandatory before rendering. Build a tiny glossary from the user prompt, folder/file names, visible context, and topic; correct obvious ASR mistakes in product/model/person/place names, English terms, numbers, and homophones.\n- Caption data: Remotion caption chunks built from Whisper words, with token-level `startMs` and `endMs`. Long Whisper segments must be split by punctuation, timing gaps, duration, or length before rendering.\n- Caption position: keep all captions in a screenshot-friendly lower band, slightly above the bottom UI area. Start around `height * 0.28` bottom padding, then adjust only if the source framing clearly needs it.\n- Visual style: bold Chinese UI font, white base text, current token yellow, optional sparse keyword accent, and black shadow/outline for readability.\n- Verification: check the rendered file exists, keeps audio, matches the source duration closely, and visually inspect stills before accepting the style.\n\n## Workflow\n\n1. Inspect the source with `ffprobe` for width, height, fps, duration, and audio presence.\n2. Build a small domain glossary before transcription. Include likely product names, model names, people, places, mixed Chinese/English terms, numbers, and terms hinted by the folder or filename.\n3. Run Whisper word timestamp transcription. Prefer a cached/local model that works on the machine; `turbo` is a good default when available. Use `--initial_prompt` when the glossary contains high-risk names or English terms.\n4. Do a mandatory transcript QA pass before rendering. Read every segment, compare it with the video's topic/context, and create a correction map for obvious ASR mistakes. Do not render while known mistakes remain.\n5. Convert the Whisper JSON to `public/captions.json` using `scripts/whisper_json_to_captions.py`, passing corrections with `--replace` or `--replace-phrase`. If Whisper returns long paragraphs, keep the helper's caption splitting enabled.\n6. Build or reuse a small Remotion project in the video's folder. Copy the video to `public/input.mp4` or encode an H.264 compatibility copy as `public/input-h264.mp4`.\n7. Set the Remotion composition to the exact source width, height, fps, and duration in frames.\n8. Before the full render, render and inspect at least two stills from the Remotion composition: one long/two-line caption and one dense keyword/current-token caption. Fix muddy text, excessive outline, large dark backing, bad line breaks, poor placement, or remaining typo/wrong-character subtitles before rendering the final video.\n9. Render with Remotion to the output path next to the source.\n10. Verify the final output with `ffprobe`; extract and inspect a still from the rendered video to confirm the final encoded file kept the approved subtitle look.\n\n## Whisper Command\n\nUse this shape, adjusting model and paths as needed:\n\n```bash\nwhisper \"/absolute/path/video.mp4\" --model turbo --language zh --word_timestamps True --output_format json --output_dir \"/absolute/path\"\n```\n\nFor names and mixed Chinese/English topics, add a short prompt rather than relying on Whisper to infer them:\n\n```bash\nwhisper \"/absolute/path/video.mp4\" \\\n  --model turbo \\\n  --language zh \\\n  --word_timestamps True \\\n  --output_format json \\\n  --initial_prompt \"本视频可能出现这些词：Cursor、Kimi 2.5、马斯克、AI大模型、转推、套壳。\" \\\n  --output_dir \"/absolute/path\"\n```\n\nIf Whisper fails on the video container, extract audio first:\n\n```bash\nffmpeg -y -i \"/absolute/path/video.mp4\" -vn -ac 1 -ar 16000 \"/absolute/path/video_audio.wav\"\n```\n\nThen run Whisper on the WAV and keep the output naming clear.\n\n## Mandatory Transcript QA\n\nAfter Whisper finishes, print or read the segment transcript before building captions. Treat this as a required gate, not a nice-to-have.\n\nCheck especially:\n\n- product, model, company, person, and place names\n- mixed Chinese/English terms such as `Cursor`, `Kimi 2.5`, `ChatGPT`, `Claude`, `OpenAI`\n- numbers, dates, model versions, and acronyms\n- Chinese homophones that are plausible but wrong in context, such as \"却\" versus \"圈\" or \"死腿\" versus \"转推\"\n- low-confidence words if the Whisper JSON includes probabilities\n\nCreate a short correction map and apply it before rendering. Use `--replace` for single-token fixes and `--replace-phrase` for words split across adjacent Whisper tokens.\n\nExample:\n\n```bash\npython3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --replace-phrase \"科舍=Cursor\" \\\n  --replace-phrase \"KMI 2.5=Kimi 2.5\" \\\n  --replace-phrase \"Kimi 2.5=Kimi 2.5\" \\\n  --replace-phrase \"AI却=AI圈\" \\\n  --replace-phrase \"死腿=转推\" \\\n  --merge-term \"Cursor\" \\\n  --merge-term \"Kimi 2.5\" \\\n  --keyword \"AI\" \\\n  --keyword \"Kimi 2.5\"\n```\n\nIf a correction is uncertain, prefer rerunning Whisper with a better `--initial_prompt` or inspect the relevant audio/video moment before deciding. Report the correction map in the final response.\n\n## Caption JSON\n\nRemotion should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"我们用手机随便拍张照片\",\n    \"startMs\": 0,\n    \"endMs\": 1600,\n    \"tokens\": [\n      { \"text\": \"我们\", \"startMs\": 0, \"endMs\": 300, \"keyword\": false },\n      { \"text\": \"手机\", \"startMs\": 440, \"endMs\": 700, \"keyword\": true }\n    ]\n  }\n]\n```\n\nUse the helper script:\n\n```bash\npython3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --keyword \"提示词\" \\\n  --keyword \"Codex\" \\\n  --replace-phrase \"错识别词=正确词\" \\\n  --max-caption-chars 28 \\\n  --max-caption-duration-ms 4200 \\\n  --split-gap-ms 260 \\\n  --min-punctuation-caption-ms 900\n```\n\nRun the transcript QA pass before this conversion command. If any correction changes adjacent tokens into one display term, also pass that final term with `--merge-term` or a same-text `--replace-phrase` so the highlight appears as a clean word instead of broken characters.\n\nThe helper splits long Whisper segments by visible length, duration, punctuation, and word timing gaps. Keep this behavior on for short-video subtitles; otherwise a single Whisper paragraph can become an unreadable multi-line caption.\n\n## Remotion Caption Layer Requirements\n\nThe caption layer should:\n\n- Use `OffthreadVideo` for the source video.\n- Load `captions.json` with `delayRender`, `continueRender`, and `staticFile`.\n- Find the active caption by `currentMs >= startMs && currentMs < endMs`.\n- Highlight the active token when `currentMs` is within the token's timing.\n- Use keyword coloring only as a secondary accent; the current spoken token is the main effect.\n- Keep `letterSpacing: 0`.\n- Keep all captions at the normal position; do not include special screenshot-sentence placement unless the user explicitly asks.\n- Do not use `WebkitTextStroke` as a thick Chinese subtitle outline. It easily eats the white fill at small resolutions. Prefer multi-direction `textShadow`; if `WebkitTextStroke` is used at all, keep it at or below `1.5px` and verify a still.\n- Do not use a large semi-transparent rounded black rectangle behind the whole caption by default. If the footage truly needs backing, use a very subtle per-line backing, opacity `<= 0.16`, tight padding, and verify it does not look like a dark banner.\n\nReject and revise any still where the caption has muddy/gray text, a thick black halo, a large black box, clipped words, awkward wrapping, or placement over the mouth/chin in a talking-head video.\n\nUse these style constants as the baseline:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst captionFontSize = Math.round(height * 0.032);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\nconst outlinePx = Math.min(3, Math.max(1.5, captionFontSize * 0.055));\n```\n\nUse a clean shadow outline rather than a heavy stroke:\n\n```tsx\nconst textShadow = [\n  `${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `-${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 -${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx * 1.4}px ${outlinePx * 1.4}px rgba(0, 0, 0, 0.72)`,\n].join(\", \");\n```\n\nFor a `720x1280` vertical video, this is roughly `paddingBottom: 358`, `fontSize: 41`, `maxWidth: 634`, and a `2px` outline. For the original `2160x2974` source that inspired this skill, the equivalent bottom padding was about `830`.\n\n## Keyword Handling\n\nIf the user does not specify keywords, infer a small set from the transcript:\n\n- product/tool names: `Codex`, `Remotion`, `Whisper`\n- content objects: `提示词`, `照片`, `手机`, `封面`\n- place names or nouns that carry the video's hook\n- numbers or outcomes that are important to the promise\n\nKeep keyword highlighting sparse. Too many colored words makes the active yellow word less clear.\n\n## Output Naming\n\nPrefer:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\nIf iterating for the same source, add `_v2`, `_v3`, etc. Do not overwrite the user's source file.\n\n## Final Response\n\nTell the user the output path, mention that it used the reusable Remotion + Whisper word timestamp flow, and include the transcript correction map or say no corrections were needed. If any verification step could not be run, say that plainly.\n\nFile v0.1.3:README.md\n\n# Remotion Word Highlight Subtitles\n\nUse Whisper word timestamps and Remotion to add short-video subtitles where the word currently being spoken is highlighted.\n\nThis Skill is designed for Chinese creator workflows where subtitles need to feel polished, readable, and screenshot-friendly.\n\n![Word highlight subtitle example](https://raw.githubusercontent.com/0x00000003/remotion-word-highlight-subtitles/main/assets/effect-word-highlight.jpg)\n\n## What It Does\n\n- Transcribes a local video with Whisper `word_timestamps`.\n- Converts Whisper's word-level JSON into Remotion-friendly `captions.json`.\n- Splits long Whisper paragraphs into readable caption chunks.\n- Requires a transcript QA pass before rendering so obvious ASR mistakes can be corrected.\n- Renders subtitles with Remotion instead of burning plain SRT text.\n- Highlights the current spoken word in yellow.\n- Optionally marks sparse keywords with a secondary accent.\n- Keeps subtitles in a lower, screenshot-friendly band by default.\n- Writes the rendered video next to the source file.\n\nDefault output name:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\n## Installation\n\nInstall from ClawHub:\n\n```bash\nclawhub install remotion-word-highlight-subtitles\n```\n\nThen restart or reload your OpenClaw/Codex environment if your agent does not discover new skills immediately.\n\n## Example Prompts\n\nUse natural prompts like:\n\n```text\n给这个视频添加逐词高亮字幕：/absolute/path/to/video.mp4\n```\n\n```text\n按 Remotion 逐词高亮字幕方案，给这个视频加字幕：/absolute/path/to/video.mp4\n```\n\n```text\n重新转写 word timestamps，然后给这个视频加当前词高亮字幕：/absolute/path/to/video.mp4\n```\n\nThe agent should then follow the Skill workflow: inspect the video, transcribe with Whisper, prepare caption JSON, render with Remotion, and verify the output.\n\n## Requirements\n\nThe workflow expects these tools to be available locally:\n\n- `python3`\n- `ffmpeg`\n- `ffprobe`\n- `whisper`\n- `node`\n- `npm`\n- Remotion dependencies in the generated or reused Remotion project\n\nThe Skill does not upload your video anywhere by itself. It is intended for local video files and local rendering.\n\n## Workflow Summary\n\n1. Read source video metadata with `ffprobe`.\n2. Run Whisper with word-level timestamps:\n\n   ```bash\n   whisper \"/absolute/path/video.mp4\" \\\n     --model turbo \\\n     --language zh \\\n     --word_timestamps True \\\n     --output_format json \\\n     --output_dir \"/absolute/path/output-dir\"\n   ```\n\n3. Review the Whisper transcript before rendering. Build a correction map for obvious mistakes in names, model versions, English terms, numbers, and homophones.\n4. Convert Whisper JSON to Remotion caption data:\n\n   ```bash\n   python3 scripts/whisper_json_to_captions.py \\\n     \"/absolute/path/transcript.json\" \\\n     \"/absolute/path/remotion-project/public/captions.json\" \\\n     --replace-phrase \"错识别词=正确词\" \\\n     --max-caption-chars 28 \\\n     --max-caption-duration-ms 4200 \\\n     --min-punctuation-caption-ms 900 \\\n     --keyword \"提示词\" \\\n     --keyword \"Codex\"\n   ```\n\n5. Render the video with a Remotion component that reads `captions.json`.\n6. Inspect one or more still frames before the full render when the framing is uncertain.\n7. Verify the final video duration and audio with `ffprobe`.\n\n## Caption Style\n\nBaseline style choices:\n\n- Base text is white.\n- The current spoken word is yellow.\n- Keyword highlights are sparse and secondary.\n- Text uses a black shadow/outline, not a heavy stroke.\n- The caption position starts around `height * 0.28` bottom padding.\n- Avoid large black subtitle boxes unless the footage truly needs extra contrast.\n\nRepresentative constants:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst captionFontSize = Math.round(height * 0.032);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\n```\n\n## Caption JSON Format\n\nThe Remotion project should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"然后这个是意大利\",\n    \"startMs\": 11860,\n    \"endMs\": 13180,\n    \"tokens\": [\n      { \"text\": \"然后\", \"startMs\": 11860, \"endMs\": 12360, \"keyword\": false },\n      { \"text\": \"这个\", \"startMs\": 12360, \"endMs\": 12640, \"keyword\": false },\n      { \"text\": \"是\", \"startMs\": 12640, \"endMs\": 12780, \"keyword\": false },\n      { \"text\": \"意大利\", \"startMs\": 12780, \"endMs\": 13180, \"keyword\": true }\n    ]\n  }\n]\n```\n\n## Helper Script\n\nThe bundled script:\n\n```text\nscripts/whisper_json_to_captions.py\n```\n\nconverts Whisper JSON with `segments[].words[]` into the caption format above.\n\nUseful options:\n\n```bash\n--keyword \"提示词\"\n--keyword \"Codex\"\n--merge-term \"朋友圈\"\n--replace \"彭丽圈=朋友圈\"\n--replace-phrase \"科舍=Cursor\"\n--replace-phrase \"KMI 2.5=Kimi 2.5\"\n--max-caption-chars 28\n--max-caption-duration-ms 4200\n--split-gap-ms 260\n--min-punctuation-caption-ms 900\n```\n\nUse `--replace` for single-token corrections and `--replace-phrase` for corrections that span adjacent Whisper tokens, such as product names split into characters. Report the correction map when you deliver the final video.\n\nCaption splitting is enabled by default because Whisper may return long paragraph-like segments, especially when `--initial_prompt` is used. Keep the split settings unless you have inspected stills and confirmed longer captions remain readable.\n\n## Notes\n\nThis is a Skill for an AI agent, not a standalone one-command video editor. The Skill gives the agent a repeatable workflow and a helper script so it can create the Remotion project, render, and verify the result consistently.\n\n## License\n\nMIT-0. Free to use, modify, and redistribute. No attribution required.\n\nFile v0.1.3:_meta.json\n\n{\n  \"ownerId\": \"kn72xxfk73vbpw9t4yzms3ma5581mwqp\",\n  \"slug\": \"remotion-word-highlight-subtitles\",\n  \"version\": \"0.1.3\",\n  \"publishedAt\": 1777826578642\n}\n\nFile v0.1.3:agents/openai.yaml\n\ninterface:\n  display_name: \"Remotion 逐词高亮字幕\"\n  short_description: \"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。\"\n  default_prompt: \"给这个视频添加逐词高亮字幕：\"\n\nArchive v0.1.2: 5 files, 8393 bytes\n\nFiles: agents/openai.yaml (220b), README.md (4694b), scripts/whisper_json_to_captions.py (5665b), SKILL.md (7392b), _meta.json (152b)\n\nFile v0.1.2:SKILL.md\n\n---\nname: remotion-word-highlight-subtitles\ndescription: Add word-level highlighted subtitles to local short videos using Whisper word timestamps and Remotion rendering.\nversion: 0.1.2\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - python3\n        - ffmpeg\n        - ffprobe\n        - whisper\n        - node\n        - npm\n    emoji: \"🎬\"\n---\n\n# Remotion Word Highlight Subtitles\n\n## Overview\n\nThis skill turns a local video into a subtitled video using the reusable \"fine version\": Whisper word timestamps plus Remotion-rendered current-word highlighting. Use this instead of plain SRT burn-in unless the user explicitly asks for simple static subtitles.\n\nDetailed usage guide, README, and effect preview: https://github.com/0x00000003/remotion-word-highlight-subtitles\n\n## Trigger Phrases\n\nUse this skill for requests like:\n\n- \"给这个视频添加字幕：/path/to/video.mp4\"\n- \"给这个视频加逐词高亮字幕\"\n- \"按之前 Remotion 那个字幕方案处理这个视频\"\n- \"重新转写 word timestamps，然后加当前词高亮字幕\"\n\nIf the user only gives one video path, write the output next to the source video.\n\n## Defaults\n\n- Source: local `.mp4`, `.mov`, `.m4v`, or audio/video file with usable audio.\n- Output: `<source-stem>_remotion逐词高亮字幕.mp4` in the same directory unless the user names another target.\n- Transcription: Whisper with word timestamps, Chinese by default: `--language zh --word_timestamps True --output_format json`.\n- Caption data: one Remotion caption per Whisper segment, with token-level `startMs` and `endMs`.\n- Caption position: keep all captions in a screenshot-friendly lower band, slightly above the bottom UI area. Start around `height * 0.28` bottom padding, then adjust only if the source framing clearly needs it.\n- Visual style: bold Chinese UI font, white base text, current token yellow, optional sparse keyword accent, and black shadow/outline for readability.\n- Verification: check the rendered file exists, keeps audio, matches the source duration closely, and visually inspect stills before accepting the style.\n\n## Workflow\n\n1. Inspect the source with `ffprobe` for width, height, fps, duration, and audio presence.\n2. Run Whisper word timestamp transcription. Prefer a cached/local model that works on the machine; `turbo` is a good default when available.\n3. Convert the Whisper JSON to `public/captions.json` using `scripts/whisper_json_to_captions.py`.\n4. Build or reuse a small Remotion project in the video's folder. Copy the video to `public/input.mp4` or encode an H.264 compatibility copy as `public/input-h264.mp4`.\n5. Set the Remotion composition to the exact source width, height, fps, and duration in frames.\n6. Before the full render, render and inspect at least two stills from the Remotion composition: one long/two-line caption and one dense keyword/current-token caption. Fix muddy text, excessive outline, large dark backing, bad line breaks, or poor placement before rendering the final video.\n7. Render with Remotion to the output path next to the source.\n8. Verify the final output with `ffprobe`; extract and inspect a still from the rendered video to confirm the final encoded file kept the approved subtitle look.\n\n## Whisper Command\n\nUse this shape, adjusting model and paths as needed:\n\n```bash\nwhisper \"/absolute/path/video.mp4\" --model turbo --language zh --word_timestamps True --output_format json --output_dir \"/absolute/path\"\n```\n\nIf Whisper fails on the video container, extract audio first:\n\n```bash\nffmpeg -y -i \"/absolute/path/video.mp4\" -vn -ac 1 -ar 16000 \"/absolute/path/video_audio.wav\"\n```\n\nThen run Whisper on the WAV and keep the output naming clear.\n\n## Caption JSON\n\nRemotion should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"我们用手机随便拍张照片\",\n    \"startMs\": 0,\n    \"endMs\": 1600,\n    \"tokens\": [\n      { \"text\": \"我们\", \"startMs\": 0, \"endMs\": 300, \"keyword\": false },\n      { \"text\": \"手机\", \"startMs\": 440, \"endMs\": 700, \"keyword\": true }\n    ]\n  }\n]\n```\n\nUse the helper script:\n\n```bash\npython3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --keyword \"提示词\" --keyword \"Codex\"\n```\n\nAfter conversion, quickly scan the transcript for obvious recognition mistakes and fix `captions.json` before rendering.\n\n## Remotion Caption Layer Requirements\n\nThe caption layer should:\n\n- Use `OffthreadVideo` for the source video.\n- Load `captions.json` with `delayRender`, `continueRender`, and `staticFile`.\n- Find the active caption by `currentMs >= startMs && currentMs < endMs`.\n- Highlight the active token when `currentMs` is within the token's timing.\n- Use keyword coloring only as a secondary accent; the current spoken token is the main effect.\n- Keep `letterSpacing: 0`.\n- Keep all captions at the normal position; do not include special screenshot-sentence placement unless the user explicitly asks.\n- Do not use `WebkitTextStroke` as a thick Chinese subtitle outline. It easily eats the white fill at small resolutions. Prefer multi-direction `textShadow`; if `WebkitTextStroke` is used at all, keep it at or below `1.5px` and verify a still.\n- Do not use a large semi-transparent rounded black rectangle behind the whole caption by default. If the footage truly needs backing, use a very subtle per-line backing, opacity `<= 0.16`, tight padding, and verify it does not look like a dark banner.\n\nReject and revise any still where the caption has muddy/gray text, a thick black halo, a large black box, clipped words, awkward wrapping, or placement over the mouth/chin in a talking-head video.\n\nUse these style constants as the baseline:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst captionFontSize = Math.round(height * 0.032);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\nconst outlinePx = Math.min(3, Math.max(1.5, captionFontSize * 0.055));\n```\n\nUse a clean shadow outline rather than a heavy stroke:\n\n```tsx\nconst textShadow = [\n  `${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `-${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 -${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx * 1.4}px ${outlinePx * 1.4}px rgba(0, 0, 0, 0.72)`,\n].join(\", \");\n```\n\nFor a `720x1280` vertical video, this is roughly `paddingBottom: 358`, `fontSize: 41`, `maxWidth: 634`, and a `2px` outline. For the original `2160x2974` source that inspired this skill, the equivalent bottom padding was about `830`.\n\n## Keyword Handling\n\nIf the user does not specify keywords, infer a small set from the transcript:\n\n- product/tool names: `Codex`, `Remotion`, `Whisper`\n- content objects: `提示词`, `照片`, `手机`, `封面`\n- place names or nouns that carry the video's hook\n- numbers or outcomes that are important to the promise\n\nKeep keyword highlighting sparse. Too many colored words makes the active yellow word less clear.\n\n## Output Naming\n\nPrefer:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\nIf iterating for the same source, add `_v2`, `_v3`, etc. Do not overwrite the user's source file.\n\n## Final Response\n\nTell the user the output path and mention that it used the reusable Remotion + Whisper word timestamp flow. If any verification step could not be run, say that plainly.\n\nFile v0.1.2:README.md\n\n# Remotion Word Highlight Subtitles\n\nUse Whisper word timestamps and Remotion to add short-video subtitles where the word currently being spoken is highlighted.\n\nThis Skill is designed for Chinese creator workflows where subtitles need to feel polished, readable, and screenshot-friendly.\n\n![Word highlight subtitle example](https://raw.githubusercontent.com/0x00000003/remotion-word-highlight-subtitles/main/assets/effect-word-highlight.jpg)\n\n## What It Does\n\n- Transcribes a local video with Whisper `word_timestamps`.\n- Converts Whisper's word-level JSON into Remotion-friendly `captions.json`.\n- Renders subtitles with Remotion instead of burning plain SRT text.\n- Highlights the current spoken word in yellow.\n- Optionally marks sparse keywords with a secondary accent.\n- Keeps subtitles in a lower, screenshot-friendly band by default.\n- Writes the rendered video next to the source file.\n\nDefault output name:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\n## Installation\n\nInstall from ClawHub:\n\n```bash\nclawhub install remotion-word-highlight-subtitles\n```\n\nThen restart or reload your OpenClaw/Codex environment if your agent does not discover new skills immediately.\n\n## Example Prompts\n\nUse natural prompts like:\n\n```text\n给这个视频添加逐词高亮字幕：/absolute/path/to/video.mp4\n```\n\n```text\n按 Remotion 逐词高亮字幕方案，给这个视频加字幕：/absolute/path/to/video.mp4\n```\n\n```text\n重新转写 word timestamps，然后给这个视频加当前词高亮字幕：/absolute/path/to/video.mp4\n```\n\nThe agent should then follow the Skill workflow: inspect the video, transcribe with Whisper, prepare caption JSON, render with Remotion, and verify the output.\n\n## Requirements\n\nThe workflow expects these tools to be available locally:\n\n- `python3`\n- `ffmpeg`\n- `ffprobe`\n- `whisper`\n- `node`\n- `npm`\n- Remotion dependencies in the generated or reused Remotion project\n\nThe Skill does not upload your video anywhere by itself. It is intended for local video files and local rendering.\n\n## Workflow Summary\n\n1. Read source video metadata with `ffprobe`.\n2. Run Whisper with word-level timestamps:\n\n   ```bash\n   whisper \"/absolute/path/video.mp4\" \\\n     --model turbo \\\n     --language zh \\\n     --word_timestamps True \\\n     --output_format json \\\n     --output_dir \"/absolute/path/output-dir\"\n   ```\n\n3. Convert Whisper JSON to Remotion caption data:\n\n   ```bash\n   python3 scripts/whisper_json_to_captions.py \\\n     \"/absolute/path/transcript.json\" \\\n     \"/absolute/path/remotion-project/public/captions.json\" \\\n     --keyword \"提示词\" \\\n     --keyword \"Codex\"\n   ```\n\n4. Render the video with a Remotion component that reads `captions.json`.\n5. Inspect one or more still frames before the full render when the framing is uncertain.\n6. Verify the final video duration and audio with `ffprobe`.\n\n## Caption Style\n\nBaseline style choices:\n\n- Base text is white.\n- The current spoken word is yellow.\n- Keyword highlights are sparse and secondary.\n- Text uses a black shadow/outline, not a heavy stroke.\n- The caption position starts around `height * 0.28` bottom padding.\n- Avoid large black subtitle boxes unless the footage truly needs extra contrast.\n\nRepresentative constants:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst captionFontSize = Math.round(height * 0.032);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\n```\n\n## Caption JSON Format\n\nThe Remotion project should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"然后这个是意大利\",\n    \"startMs\": 11860,\n    \"endMs\": 13180,\n    \"tokens\": [\n      { \"text\": \"然后\", \"startMs\": 11860, \"endMs\": 12360, \"keyword\": false },\n      { \"text\": \"这个\", \"startMs\": 12360, \"endMs\": 12640, \"keyword\": false },\n      { \"text\": \"是\", \"startMs\": 12640, \"endMs\": 12780, \"keyword\": false },\n      { \"text\": \"意大利\", \"startMs\": 12780, \"endMs\": 13180, \"keyword\": true }\n    ]\n  }\n]\n```\n\n## Helper Script\n\nThe bundled script:\n\n```text\nscripts/whisper_json_to_captions.py\n```\n\nconverts Whisper JSON with `segments[].words[]` into the caption format above.\n\nUseful options:\n\n```bash\n--keyword \"提示词\"\n--keyword \"Codex\"\n--merge-term \"朋友圈\"\n--replace \"彭丽圈=朋友圈\"\n```\n\nUse `--replace` for obvious transcription corrections before rendering.\n\n## Notes\n\nThis is a Skill for an AI agent, not a standalone one-command video editor. The Skill gives the agent a repeatable workflow and a helper script so it can create the Remotion project, render, and verify the result consistently.\n\n## License\n\nMIT-0. Free to use, modify, and redistribute. No attribution required.\n\nFile v0.1.2:_meta.json\n\n{\n  \"ownerId\": \"kn72xxfk73vbpw9t4yzms3ma5581mwqp\",\n  \"slug\": \"remotion-word-highlight-subtitles\",\n  \"version\": \"0.1.2\",\n  \"publishedAt\": 1777823494659\n}\n\nFile v0.1.2:agents/openai.yaml\n\ninterface:\n  display_name: \"Remotion 逐词高亮字幕\"\n  short_description: \"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。\"\n  default_prompt: \"给这个视频添加逐词高亮字幕：\"\n\nArchive v0.1.1: 5 files, 8353 bytes\n\nFiles: agents/openai.yaml (220b), README.md (4610b), scripts/whisper_json_to_captions.py (5665b), SKILL.md (7392b), _meta.json (152b)\n\nFile v0.1.1:SKILL.md\n\n---\nname: remotion-word-highlight-subtitles\ndescription: Add word-level highlighted subtitles to local short videos using Whisper word timestamps and Remotion rendering.\nversion: 0.1.1\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - python3\n        - ffmpeg\n        - ffprobe\n        - whisper\n        - node\n        - npm\n    emoji: \"🎬\"\n---\n\n# Remotion Word Highlight Subtitles\n\n## Overview\n\nThis skill turns a local video into a subtitled video using the reusable \"fine version\": Whisper word timestamps plus Remotion-rendered current-word highlighting. Use this instead of plain SRT burn-in unless the user explicitly asks for simple static subtitles.\n\nDetailed usage guide, README, and effect preview: https://github.com/0x00000003/remotion-word-highlight-subtitles\n\n## Trigger Phrases\n\nUse this skill for requests like:\n\n- \"给这个视频添加字幕：/path/to/video.mp4\"\n- \"给这个视频加逐词高亮字幕\"\n- \"按之前 Remotion 那个字幕方案处理这个视频\"\n- \"重新转写 word timestamps，然后加当前词高亮字幕\"\n\nIf the user only gives one video path, write the output next to the source video.\n\n## Defaults\n\n- Source: local `.mp4`, `.mov`, `.m4v`, or audio/video file with usable audio.\n- Output: `<source-stem>_remotion逐词高亮字幕.mp4` in the same directory unless the user names another target.\n- Transcription: Whisper with word timestamps, Chinese by default: `--language zh --word_timestamps True --output_format json`.\n- Caption data: one Remotion caption per Whisper segment, with token-level `startMs` and `endMs`.\n- Caption position: keep all captions in a screenshot-friendly lower band, slightly above the bottom UI area. Start around `height * 0.28` bottom padding, then adjust only if the source framing clearly needs it.\n- Visual style: bold Chinese UI font, white base text, current token yellow, optional sparse keyword accent, and black shadow/outline for readability.\n- Verification: check the rendered file exists, keeps audio, matches the source duration closely, and visually inspect stills before accepting the style.\n\n## Workflow\n\n1. Inspect the source with `ffprobe` for width, height, fps, duration, and audio presence.\n2. Run Whisper word timestamp transcription. Prefer a cached/local model that works on the machine; `turbo` is a good default when available.\n3. Convert the Whisper JSON to `public/captions.json` using `scripts/whisper_json_to_captions.py`.\n4. Build or reuse a small Remotion project in the video's folder. Copy the video to `public/input.mp4` or encode an H.264 compatibility copy as `public/input-h264.mp4`.\n5. Set the Remotion composition to the exact source width, height, fps, and duration in frames.\n6. Before the full render, render and inspect at least two stills from the Remotion composition: one long/two-line caption and one dense keyword/current-token caption. Fix muddy text, excessive outline, large dark backing, bad line breaks, or poor placement before rendering the final video.\n7. Render with Remotion to the output path next to the source.\n8. Verify the final output with `ffprobe`; extract and inspect a still from the rendered video to confirm the final encoded file kept the approved subtitle look.\n\n## Whisper Command\n\nUse this shape, adjusting model and paths as needed:\n\n```bash\nwhisper \"/absolute/path/video.mp4\" --model turbo --language zh --word_timestamps True --output_format json --output_dir \"/absolute/path\"\n```\n\nIf Whisper fails on the video container, extract audio first:\n\n```bash\nffmpeg -y -i \"/absolute/path/video.mp4\" -vn -ac 1 -ar 16000 \"/absolute/path/video_audio.wav\"\n```\n\nThen run Whisper on the WAV and keep the output naming clear.\n\n## Caption JSON\n\nRemotion should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"我们用手机随便拍张照片\",\n    \"startMs\": 0,\n    \"endMs\": 1600,\n    \"tokens\": [\n      { \"text\": \"我们\", \"startMs\": 0, \"endMs\": 300, \"keyword\": false },\n      { \"text\": \"手机\", \"startMs\": 440, \"endMs\": 700, \"keyword\": true }\n    ]\n  }\n]\n```\n\nUse the helper script:\n\n```bash\npython3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --keyword \"提示词\" --keyword \"Codex\"\n```\n\nAfter conversion, quickly scan the transcript for obvious recognition mistakes and fix `captions.json` before rendering.\n\n## Remotion Caption Layer Requirements\n\nThe caption layer should:\n\n- Use `OffthreadVideo` for the source video.\n- Load `captions.json` with `delayRender`, `continueRender`, and `staticFile`.\n- Find the active caption by `currentMs >= startMs && currentMs < endMs`.\n- Highlight the active token when `currentMs` is within the token's timing.\n- Use keyword coloring only as a secondary accent; the current spoken token is the main effect.\n- Keep `letterSpacing: 0`.\n- Keep all captions at the normal position; do not include special screenshot-sentence placement unless the user explicitly asks.\n- Do not use `WebkitTextStroke` as a thick Chinese subtitle outline. It easily eats the white fill at small resolutions. Prefer multi-direction `textShadow`; if `WebkitTextStroke` is used at all, keep it at or below `1.5px` and verify a still.\n- Do not use a large semi-transparent rounded black rectangle behind the whole caption by default. If the footage truly needs backing, use a very subtle per-line backing, opacity `<= 0.16`, tight padding, and verify it does not look like a dark banner.\n\nReject and revise any still where the caption has muddy/gray text, a thick black halo, a large black box, clipped words, awkward wrapping, or placement over the mouth/chin in a talking-head video.\n\nUse these style constants as the baseline:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst captionFontSize = Math.round(height * 0.032);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\nconst outlinePx = Math.min(3, Math.max(1.5, captionFontSize * 0.055));\n```\n\nUse a clean shadow outline rather than a heavy stroke:\n\n```tsx\nconst textShadow = [\n  `${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `-${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 -${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx * 1.4}px ${outlinePx * 1.4}px rgba(0, 0, 0, 0.72)`,\n].join(\", \");\n```\n\nFor a `720x1280` vertical video, this is roughly `paddingBottom: 358`, `fontSize: 41`, `maxWidth: 634`, and a `2px` outline. For the original `2160x2974` source that inspired this skill, the equivalent bottom padding was about `830`.\n\n## Keyword Handling\n\nIf the user does not specify keywords, infer a small set from the transcript:\n\n- product/tool names: `Codex`, `Remotion`, `Whisper`\n- content objects: `提示词`, `照片`, `手机`, `封面`\n- place names or nouns that carry the video's hook\n- numbers or outcomes that are important to the promise\n\nKeep keyword highlighting sparse. Too many colored words makes the active yellow word less clear.\n\n## Output Naming\n\nPrefer:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\nIf iterating for the same source, add `_v2`, `_v3`, etc. Do not overwrite the user's source file.\n\n## Final Response\n\nTell the user the output path and mention that it used the reusable Remotion + Whisper word timestamp flow. If any verification step could not be run, say that plainly.\n\nFile v0.1.1:README.md\n\n# Remotion Word Highlight Subtitles\n\nUse Whisper word timestamps and Remotion to add short-video subtitles where the word currently being spoken is highlighted.\n\nThis Skill is designed for Chinese creator workflows where subtitles need to feel polished, readable, and screenshot-friendly.\n\n![Word highlight subtitle example](assets/effect-word-highlight.jpg)\n\n## What It Does\n\n- Transcribes a local video with Whisper `word_timestamps`.\n- Converts Whisper's word-level JSON into Remotion-friendly `captions.json`.\n- Renders subtitles with Remotion instead of burning plain SRT text.\n- Highlights the current spoken word in yellow.\n- Optionally marks sparse keywords with a secondary accent.\n- Keeps subtitles in a lower, screenshot-friendly band by default.\n- Writes the rendered video next to the source file.\n\nDefault output name:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\n## Installation\n\nInstall from ClawHub:\n\n```bash\nclawhub install remotion-word-highlight-subtitles\n```\n\nThen restart or reload your OpenClaw/Codex environment if your agent does not discover new skills immediately.\n\n## Example Prompts\n\nUse natural prompts like:\n\n```text\n给这个视频添加逐词高亮字幕：/absolute/path/to/video.mp4\n```\n\n```text\n按 Remotion 逐词高亮字幕方案，给这个视频加字幕：/absolute/path/to/video.mp4\n```\n\n```text\n重新转写 word timestamps，然后给这个视频加当前词高亮字幕：/absolute/path/to/video.mp4\n```\n\nThe agent should then follow the Skill workflow: inspect the video, transcribe with Whisper, prepare caption JSON, render with Remotion, and verify the output.\n\n## Requirements\n\nThe workflow expects these tools to be available locally:\n\n- `python3`\n- `ffmpeg`\n- `ffprobe`\n- `whisper`\n- `node`\n- `npm`\n- Remotion dependencies in the generated or reused Remotion project\n\nThe Skill does not upload your video anywhere by itself. It is intended for local video files and local rendering.\n\n## Workflow Summary\n\n1. Read source video metadata with `ffprobe`.\n2. Run Whisper with word-level timestamps:\n\n   ```bash\n   whisper \"/absolute/path/video.mp4\" \\\n     --model turbo \\\n     --language zh \\\n     --word_timestamps True \\\n     --output_format json \\\n     --output_dir \"/absolute/path/output-dir\"\n   ```\n\n3. Convert Whisper JSON to Remotion caption data:\n\n   ```bash\n   python3 scripts/whisper_json_to_captions.py \\\n     \"/absolute/path/transcript.json\" \\\n     \"/absolute/path/remotion-project/public/captions.json\" \\\n     --keyword \"提示词\" \\\n     --keyword \"Codex\"\n   ```\n\n4. Render the video with a Remotion component that reads `captions.json`.\n5. Inspect one or more still frames before the full render when the framing is uncertain.\n6. Verify the final video duration and audio with `ffprobe`.\n\n## Caption Style\n\nBaseline style choices:\n\n- Base text is white.\n- The current spoken word is yellow.\n- Keyword highlights are sparse and secondary.\n- Text uses a black shadow/outline, not a heavy stroke.\n- The caption position starts around `height * 0.28` bottom padding.\n- Avoid large black subtitle boxes unless the footage truly needs extra contrast.\n\nRepresentative constants:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst captionFontSize = Math.round(height * 0.032);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\n```\n\n## Caption JSON Format\n\nThe Remotion project should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"然后这个是意大利\",\n    \"startMs\": 11860,\n    \"endMs\": 13180,\n    \"tokens\": [\n      { \"text\": \"然后\", \"startMs\": 11860, \"endMs\": 12360, \"keyword\": false },\n      { \"text\": \"这个\", \"startMs\": 12360, \"endMs\": 12640, \"keyword\": false },\n      { \"text\": \"是\", \"startMs\": 12640, \"endMs\": 12780, \"keyword\": false },\n      { \"text\": \"意大利\", \"startMs\": 12780, \"endMs\": 13180, \"keyword\": true }\n    ]\n  }\n]\n```\n\n## Helper Script\n\nThe bundled script:\n\n```text\nscripts/whisper_json_to_captions.py\n```\n\nconverts Whisper JSON with `segments[].words[]` into the caption format above.\n\nUseful options:\n\n```bash\n--keyword \"提示词\"\n--keyword \"Codex\"\n--merge-term \"朋友圈\"\n--replace \"彭丽圈=朋友圈\"\n```\n\nUse `--replace` for obvious transcription corrections before rendering.\n\n## Notes\n\nThis is a Skill for an AI agent, not a standalone one-command video editor. The Skill gives the agent a repeatable workflow and a helper script so it can create the Remotion project, render, and verify the result consistently.\n\n## License\n\nMIT-0. Free to use, modify, and redistribute. No attribution required.\n\nFile v0.1.1:_meta.json\n\n{\n  \"ownerId\": \"kn72xxfk73vbpw9t4yzms3ma5581mwqp\",\n  \"slug\": \"remotion-word-highlight-subtitles\",\n  \"version\": \"0.1.1\",\n  \"publishedAt\": 1777823359694\n}\n\nFile v0.1.1:agents/openai.yaml\n\ninterface:\n  display_name: \"Remotion 逐词高亮字幕\"\n  short_description: \"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。\"\n  default_prompt: \"给这个视频添加逐词高亮字幕：\"\n\nArchive v0.1.0: 4 files, 6071 bytes\n\nFiles: agents/openai.yaml (220b), scripts/whisper_json_to_captions.py (5665b), SKILL.md (7277b), _meta.json (152b)\n\nFile v0.1.0:SKILL.md\n\n---\nname: remotion-word-highlight-subtitles\ndescription: Add word-level highlighted subtitles to local short videos using Whisper word timestamps and Remotion rendering.\nversion: 0.1.0\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - python3\n        - ffmpeg\n        - ffprobe\n        - whisper\n        - node\n        - npm\n    emoji: \"🎬\"\n---\n\n# Remotion Word Highlight Subtitles\n\n## Overview\n\nThis skill turns a local video into a subtitled video using the reusable \"fine version\": Whisper word timestamps plus Remotion-rendered current-word highlighting. Use this instead of plain SRT burn-in unless the user explicitly asks for simple static subtitles.\n\n## Trigger Phrases\n\nUse this skill for requests like:\n\n- \"给这个视频添加字幕：/path/to/video.mp4\"\n- \"给这个视频加逐词高亮字幕\"\n- \"按之前 Remotion 那个字幕方案处理这个视频\"\n- \"重新转写 word timestamps，然后加当前词高亮字幕\"\n\nIf the user only gives one video path, write the output next to the source video.\n\n## Defaults\n\n- Source: local `.mp4`, `.mov`, `.m4v`, or audio/video file with usable audio.\n- Output: `<source-stem>_remotion逐词高亮字幕.mp4` in the same directory unless the user names another target.\n- Transcription: Whisper with word timestamps, Chinese by default: `--language zh --word_timestamps True --output_format json`.\n- Caption data: one Remotion caption per Whisper segment, with token-level `startMs` and `endMs`.\n- Caption position: keep all captions in a screenshot-friendly lower band, slightly above the bottom UI area. Start around `height * 0.28` bottom padding, then adjust only if the source framing clearly needs it.\n- Visual style: bold Chinese UI font, white base text, current token yellow, optional sparse keyword accent, and black shadow/outline for readability.\n- Verification: check the rendered file exists, keeps audio, matches the source duration closely, and visually inspect stills before accepting the style.\n\n## Workflow\n\n1. Inspect the source with `ffprobe` for width, height, fps, duration, and audio presence.\n2. Run Whisper word timestamp transcription. Prefer a cached/local model that works on the machine; `turbo` is a good default when available.\n3. Convert the Whisper JSON to `public/captions.json` using `scripts/whisper_json_to_captions.py`.\n4. Build or reuse a small Remotion project in the video's folder. Copy the video to `public/input.mp4` or encode an H.264 compatibility copy as `public/input-h264.mp4`.\n5. Set the Remotion composition to the exact source width, height, fps, and duration in frames.\n6. Before the full render, render and inspect at least two stills from the Remotion composition: one long/two-line caption and one dense keyword/current-token caption. Fix muddy text, excessive outline, large dark backing, bad line breaks, or poor placement before rendering the final video.\n7. Render with Remotion to the output path next to the source.\n8. Verify the final output with `ffprobe`; extract and inspect a still from the rendered video to confirm the final encoded file kept the approved subtitle look.\n\n## Whisper Command\n\nUse this shape, adjusting model and paths as needed:\n\n```bash\nwhisper \"/absolute/path/video.mp4\" --model turbo --language zh --word_timestamps True --output_format json --output_dir \"/absolute/path\"\n```\n\nIf Whisper fails on the video container, extract audio first:\n\n```bash\nffmpeg -y -i \"/absolute/path/video.mp4\" -vn -ac 1 -ar 16000 \"/absolute/path/video_audio.wav\"\n```\n\nThen run Whisper on the WAV and keep the output naming clear.\n\n## Caption JSON\n\nRemotion should load `public/captions.json` with this shape:\n\n```json\n[\n  {\n    \"text\": \"我们用手机随便拍张照片\",\n    \"startMs\": 0,\n    \"endMs\": 1600,\n    \"tokens\": [\n      { \"text\": \"我们\", \"startMs\": 0, \"endMs\": 300, \"keyword\": false },\n      { \"text\": \"手机\", \"startMs\": 440, \"endMs\": 700, \"keyword\": true }\n    ]\n  }\n]\n```\n\nUse the helper script:\n\n```bash\npython3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --keyword \"提示词\" --keyword \"Codex\"\n```\n\nAfter conversion, quickly scan the transcript for obvious recognition mistakes and fix `captions.json` before rendering.\n\n## Remotion Caption Layer Requirements\n\nThe caption layer should:\n\n- Use `OffthreadVideo` for the source video.\n- Load `captions.json` with `delayRender`, `continueRender`, and `staticFile`.\n- Find the active caption by `currentMs >= startMs && currentMs < endMs`.\n- Highlight the active token when `currentMs` is within the token's timing.\n- Use keyword coloring only as a secondary accent; the current spoken token is the main effect.\n- Keep `letterSpacing: 0`.\n- Keep all captions at the normal position; do not include special screenshot-sentence placement unless the user explicitly asks.\n- Do not use `WebkitTextStroke` as a thick Chinese subtitle outline. It easily eats the white fill at small resolutions. Prefer multi-direction `textShadow`; if `WebkitTextStroke` is used at all, keep it at or below `1.5px` and verify a still.\n- Do not use a large semi-transparent rounded black rectangle behind the whole caption by default. If the footage truly needs backing, use a very subtle per-line backing, opacity `<= 0.16`, tight padding, and verify it does not look like a dark banner.\n\nReject and revise any still where the caption has muddy/gray text, a thick black halo, a large black box, clipped words, awkward wrapping, or placement over the mouth/chin in a talking-head video.\n\nUse these style constants as the baseline:\n\n```tsx\nconst captionBottom = Math.round(height * 0.28);\nconst captionFontSize = Math.round(height * 0.032);\nconst captionMaxWidth = Math.round(width * 0.88);\nconst activeColor = \"#FFE45C\";\nconst keywordColor = \"#D6FFF8\";\nconst outlinePx = Math.min(3, Math.max(1.5, captionFontSize * 0.055));\n```\n\nUse a clean shadow outline rather than a heavy stroke:\n\n```tsx\nconst textShadow = [\n  `${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `-${outlinePx}px 0 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 -${outlinePx}px 0 rgba(0, 0, 0, 0.96)`,\n  `0 ${outlinePx * 1.4}px ${outlinePx * 1.4}px rgba(0, 0, 0, 0.72)`,\n].join(\", \");\n```\n\nFor a `720x1280` vertical video, this is roughly `paddingBottom: 358`, `fontSize: 41`, `maxWidth: 634`, and a `2px` outline. For the original `2160x2974` source that inspired this skill, the equivalent bottom padding was about `830`.\n\n## Keyword Handling\n\nIf the user does not specify keywords, infer a small set from the transcript:\n\n- product/tool names: `Codex`, `Remotion`, `Whisper`\n- content objects: `提示词`, `照片`, `手机`, `封面`\n- place names or nouns that carry the video's hook\n- numbers or outcomes that are important to the promise\n\nKeep keyword highlighting sparse. Too many colored words makes the active yellow word less clear.\n\n## Output Naming\n\nPrefer:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\nIf iterating for the same source, add `_v2`, `_v3`, etc. Do not overwrite the user's source file.\n\n## Final Response\n\nTell the user the output path and mention that it used the reusable Remotion + Whisper word timestamp flow. If any verification step could not be run, say that plainly.\n\nFile v0.1.0:_meta.json\n\n{\n  \"ownerId\": \"kn72xxfk73vbpw9t4yzms3ma5581mwqp\",\n  \"slug\": \"remotion-word-highlight-subtitles\",\n  \"version\": \"0.1.0\",\n  \"publishedAt\": 1777821015082\n}\n\nFile v0.1.0:agents/openai.yaml\n\ninterface:\n  display_name: \"Remotion 逐词高亮字幕\"\n  short_description: \"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。\"\n  default_prompt: \"给这个视频添加逐词高亮字幕：\"","readmeExcerpt":"Skill: Remotion 逐词高亮字幕 Owner: 0x00000003 Summary: 用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。 Tags: latest:0.1.4, remotion:0.1.4, short-video:0.1.4, subtitles:0.1.4, video:0.1.4, whisper:0.1.4 Version history: v0.1.4 | 2026-05-14T12:53:13.796Z | user Enforce larger subtitle sizing and strip display punctuation by default. v0.1.3 | 2026-05-03T16:42:58.642Z | user Make transcript QA mandatory before rendering; add cross-tok","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"whisper \"/absolute/path/video.mp4\" --model turbo --language zh --word_timestamps True --output_format json --output_dir \"/absolute/path\""},{"language":"bash","snippet":"whisper \"/absolute/path/video.mp4\" \\\n  --model turbo \\\n  --language zh \\\n  --word_timestamps True \\\n  --output_format json \\\n  --initial_prompt \"本视频可能出现这些词：Cursor、Kimi 2.5、马斯克、AI大模型、转推、套壳。\" \\\n  --output_dir \"/absolute/path\""},{"language":"bash","snippet":"ffmpeg -y -i \"/absolute/path/video.mp4\" -vn -ac 1 -ar 16000 \"/absolute/path/video_audio.wav\""},{"language":"bash","snippet":"python3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --replace-phrase \"科舍=Cursor\" \\\n  --replace-phrase \"KMI 2.5=Kimi 2.5\" \\\n  --replace-phrase \"Kimi 2.5=Kimi 2.5\" \\\n  --replace-phrase \"AI却=AI圈\" \\\n  --replace-phrase \"死腿=转推\" \\\n  --merge-term \"Cursor\" \\\n  --merge-term \"Kimi 2.5\" \\\n  --keyword \"AI\" \\\n  --keyword \"Kimi 2.5\""},{"language":"json","snippet":"[\n  {\n    \"text\": \"我们用手机随便拍张照片\",\n    \"startMs\": 0,\n    \"endMs\": 1600,\n    \"tokens\": [\n      { \"text\": \"我们\", \"startMs\": 0, \"endMs\": 300, \"keyword\": false },\n      { \"text\": \"手机\", \"startMs\": 440, \"endMs\": 700, \"keyword\": true }\n    ]\n  }\n]"},{"language":"bash","snippet":"python3 scripts/whisper_json_to_captions.py \\\n  \"/absolute/path/transcript.json\" \\\n  \"/absolute/path/remotion-project/public/captions.json\" \\\n  --keyword \"提示词\" \\\n  --keyword \"Codex\" \\\n  --replace-phrase \"错识别词=正确词\" \\\n  --max-caption-chars 28 \\\n  --max-caption-duration-ms 4200 \\\n  --split-gap-ms 260 \\\n  --min-punctuation-caption-ms 900"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: remotion-word-highlight-subtitles\ndescription: Add word-level highlighted subtitles to local short videos using Whisper word timestamps and Remotion rendering.\nversion: 0.1.4\nmetadata:\n  openclaw:\n    requires:\n      bins:\n        - python3\n        - ffmpeg\n        - ffprobe\n        - whisper\n        - node\n        - npm\n    emoji: \"🎬\"\n---\n\n# Remotion Word Highlight Subtitles\n\n## Overview\n\nThis skill turns a local video into a subtitled video using the reusable \"fine version\": Whisper word timestamps plus Remotion-rendered current-word highlighting. Use this instead of plain SRT burn-in unless the user explicitly asks for simple static subtitles.\n\nDetailed usage guide, README, and effect preview: https://github.com/0x00000003/remotion-word-highlight-subtitles\n\n## Trigger Phrases\n\nUse this skill for requests like:\n\n- \"给这个视频添加字幕：/path/to/video.mp4\"\n- \"给这个视频加逐词高亮字幕\"\n- \"按之前 Remotion 那个字幕方案处理这个视频\"\n- \"重新转写 word timestamps，然后加当前词高亮字幕\"\n\nIf the user only gives one video path, write the output next to the source video.\n\n## Defaults\n\n- Source: local `.mp4`, `.mov`, `.m4v`, or audio/video file with usable audio.\n- Output: `<source-stem>_remotion逐词高亮字幕.mp4` in the same directory unless the user names another target.\n- Transcription: Whisper with word timestamps, Chinese by default: `--language zh --word_timestamps True --output_format json`.\n- Transcript QA: mandatory before rendering. Build a tiny glossary from the user prompt, folder/file names, visible context, and topic; correct obvious ASR mistakes in product/model/person/place names, English terms, numbers, and homophones.\n- Caption data: Remotion caption chunks built from Whisper words, with token-level `startMs` and `endMs`. Long Whisper segments must be split by punctuation, timing gaps, duration, or length before rendering.\n- Caption position: keep all captions in a screenshot-friendly lower band, slightly above the bottom UI area. Start around `height * 0.28` bottom padding, then adjust only if the source framing clearly needs it.\n- Visual style: bold Chinese UI font, white base text, current token yellow, optional sparse keyword accent, and black shadow/outline for readability.\n- Subtitle sizing: treat font size as a hard visual gate, not a loose style hint. For landscape 1080p footage, target `height * 0.056` (about `60px`) and never render below `56px`; for vertical `720x1280`, target `40-46px`. For other sizes, scale from height but enforce the same perceived size in still QA.\n- Display punctuation: default subtitles are clean Chinese display text. Strip visible sentence punctuation from caption text and token text before rendering, including `。 ， 、 ？ ！ ： ； , . ? ! : ;`. Keep punctuation only for splitting/timing unless the user explicitly asks for verbatim punctuation.\n- Verification: check the rendered file exists, keeps audio, matches the source duration closely, and visually inspect stills before accepting the style.\n\n## Workflow\n\n1. Inspect the source with `ffprobe` for width, h"},{"path":"README.md","content":"# Remotion Word Highlight Subtitles\n\nUse Whisper word timestamps and Remotion to add short-video subtitles where the word currently being spoken is highlighted.\n\nThis Skill is designed for Chinese creator workflows where subtitles need to feel polished, readable, and screenshot-friendly.\n\n![Word highlight subtitle example](https://raw.githubusercontent.com/0x00000003/remotion-word-highlight-subtitles/main/assets/effect-word-highlight.jpg)\n\n## What It Does\n\n- Transcribes a local video with Whisper `word_timestamps`.\n- Converts Whisper's word-level JSON into Remotion-friendly `captions.json`.\n- Splits long Whisper paragraphs into readable caption chunks.\n- Requires a transcript QA pass before rendering so obvious ASR mistakes can be corrected.\n- Renders subtitles with Remotion instead of burning plain SRT text.\n- Highlights the current spoken word in yellow.\n- Optionally marks sparse keywords with a secondary accent.\n- Strips visible display punctuation by default while still using punctuation for caption splitting.\n- Enforces orientation-aware subtitle size floors so landscape subtitles do not render too small.\n- Keeps subtitles in a lower, screenshot-friendly band by default.\n- Writes the rendered video next to the source file.\n\nDefault output name:\n\n```text\n<source-stem>_remotion逐词高亮字幕.mp4\n```\n\n## Installation\n\nInstall from ClawHub:\n\n```bash\nclawhub install remotion-word-highlight-subtitles\n```\n\nThen restart or reload your OpenClaw/Codex environment if your agent does not discover new skills immediately.\n\n## Example Prompts\n\nUse natural prompts like:\n\n```text\n给这个视频添加逐词高亮字幕：/absolute/path/to/video.mp4\n```\n\n```text\n按 Remotion 逐词高亮字幕方案，给这个视频加字幕：/absolute/path/to/video.mp4\n```\n\n```text\n重新转写 word timestamps，然后给这个视频加当前词高亮字幕：/absolute/path/to/video.mp4\n```\n\nThe agent should then follow the Skill workflow: inspect the video, transcribe with Whisper, prepare caption JSON, render with Remotion, and verify the output.\n\n## Requirements\n\nThe workflow expects these tools to be available locally:\n\n- `python3`\n- `ffmpeg`\n- `ffprobe`\n- `whisper`\n- `node`\n- `npm`\n- Remotion dependencies in the generated or reused Remotion project\n\nThe Skill does not upload your video anywhere by itself. It is intended for local video files and local rendering.\n\n## Workflow Summary\n\n1. Read source video metadata with `ffprobe`.\n2. Run Whisper with word-level timestamps:\n\n   ```bash\n   whisper \"/absolute/path/video.mp4\" \\\n     --model turbo \\\n     --language zh \\\n     --word_timestamps True \\\n     --output_format json \\\n     --output_dir \"/absolute/path/output-dir\"\n   ```\n\n3. Review the Whisper transcript before rendering. Build a correction map for obvious mistakes in names, model versions, English terms, numbers, and homophones.\n4. Convert Whisper JSON to Remotion caption data:\n\n   ```bash\n   python3 scripts/whisper_json_to_captions.py \\\n     \"/absolute/path/transcript.json\" \\\n     \"/absolute/path/remotion-project/public/captions.json\" \\\n     --replace-phrase \"错识别词=正确词\" \\\n     --"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn72xxfk73vbpw9t4yzms3ma5581mwqp\",\n  \"slug\": \"remotion-word-highlight-subtitles\",\n  \"version\": \"0.1.4\",\n  \"publishedAt\": 1778763193796\n}"},{"path":"skill-card.md","content":"## Description:\n\nAdd word-level highlighted subtitles to local short videos using Whisper word timestamps and Remotion rendering.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[0x00000003](https://clawhub.ai/user/0x00000003)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers, video creators, and agent users use this skill to transcribe local short videos, review and correct word-level captions, and render polished Chinese-oriented subtitles with current-word highlighting.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The workflow processes local media and writes rendered outputs, so users could choose the wrong input or output location.\n\nMitigation: Use only video files and output folders selected by the user, and keep the generated video separate from the source file.\n\nRisk: The default Whisper settings are optimized for Chinese-language subtitles and may produce inaccurate captions for other languages.\n\nMitigation: Change the Whisper language option for non-Chinese videos and complete the transcript QA pass before rendering.\n\nRisk: Missing or mismatched local rendering tools can cause failed renders, lost audio, or duration mismatches.\n\nMitigation: Verify python3, ffmpeg, ffprobe, whisper, node, npm, and Remotion dependencies, then inspect stills and check final duration and audio with ffprobe.\n\n## Reference(s):\n\n- [ClawHub skill page](https://clawhub.ai/0x00000003/skills/remotion-word-highlight-subtitles)\n- [Project documentation linked by skill](https://github.com/0x00000003/remotion-word-highlight-subtitles)\n- [Word highlight subtitle example image](https://raw.githubusercontent.com/0x00000003/remotion-word-highlight-subtitles/main/assets/effect-word-highlight.jpg)\n\n## Skill Output:\n\n**Output Type(s):** [text, markdown, code, shell commands, configuration, guidance, files]\n\n**Output Format:** [Markdown guidance with shell commands, code snippets, and JSON caption data]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Produces Remotion caption JSON and guidance for rendering a local MP4 subtitle output; expects local python3, ffmpeg, ffprobe, whisper, node, and npm.]\n\n## Skill Version(s):\n\n0.1.4 (source: frontmatter and server release)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."},{"path":"agents/openai.yaml","content":"interface:\n  display_name: \"Remotion 逐词高亮字幕\"\n  short_description: \"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。\"\n  default_prompt: \"给这个视频添加逐词高亮字幕：\""}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。 Skill: Remotion 逐词高亮字幕 Owner: 0x00000003 Summary: 用 Whisper 逐词时间戳和 Remotion 给视频加当前词高亮字幕。 Tags: latest:0.1.4, remotion:0.1.4, short-video:0.1.4, subtitles:0.1.4, video:0.1.4, whisper:0.1.4 Version history: v0.1.4 | 2026-05-14T12:53:13.796Z | user Enforce larger subtitle sizing and strip display punctuation by default. v0.1.3 | 2026-05-03T16:42:58.642Z | user Make transcript QA mandatory before rendering; add cross-tok","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1458,"uniquenessScore":47,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T22:06:48.033Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T22:06:48.033Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-13T05:30:12.475Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}