一键导入
retime-captions-to-words
Snap SRT cue starts to whisper word-level timestamps within ±100 ms so captions land on word boundaries instead of drifting.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Snap SRT cue starts to whisper word-level timestamps within ±100 ms so captions land on word boundaries instead of drifting.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
Produce a Photo-Grid promo card — a silent, music-optional feed-placement video where a scrolling 2×N tile grid (product photos + short brand video clips + big-type offer tiles + a promo-code tile) animates under a centered wordmark, headline, sub, and outline feature chips. 9:16 or 4:5, ~10s, $0 HTML-hyperframe pipeline (no T2V, no VO). Recreates the Meta "photo-grid mosaic" template (e.g. "Our New Band 2.0 / LAUNCH30"). Validated on Hume Health (Father's Day promo, 2026-06-03). Use when the brand wants a clean editorial feed card that works muted; NOT for kinetic-BG vignette (use create-vignette-ad), UGC, or VO-driven ads.
Remix a published Apple Notes video ad from the Goose Ads library for a new brand — keep the source's note structure and typing pacing, swap in the brand's product, voice, and promo code, get the note approved in-session, then render with create-apple-notes-video-ad and publish the MP4 back to Gooseworks with live stage reporting. The Apple Notes typing-reveal counterpart to remix-imessage-ad-from-sample; this is what the app's Apple Notes format tab calls.
Remix a published ChatGPT video ad from the Goose Ads library for a new brand — keep the source's conversation structure and pacing (the single ask → streamed answer beat), swap in the brand's product as the natural recommendation and the promo code woven into the response, get the conversation approved in-session, then render with create-chatgpt-video-ad and publish the MP4 back to Gooseworks with live stage reporting. The ChatGPT chat-reveal / ask-ChatGPT counterpart to remix-imessage-ad-from-sample; this is what the app's ChatGPT format tab calls.
Remix a published iMessage video ad from the Goose Ads library for a new brand — keep the source's conversation structure and pacing, swap in the brand's product, voice, and promo code, get the thread approved in-session, then render with create-imessage-video-ad and publish the MP4 back to Gooseworks with live stage reporting. The video counterpart to remix-graphic-ad-from-reference; this is what the app's iMessage format tab calls.
Remix a published Photo-Grid promo card from the Goose Ads library for a new brand — keep the source's grid layout, tile rhythm, scroll, and offer structure, swap in the brand's product photos, corpus video clips, wordmark, palette, copy, and promo code, get the card approved in-session, then render with create-photo-grid-ad and publish the MP4 back to Gooseworks with live stage reporting. The photo-grid counterpart to remix-imessage-ad-from-sample; this is what the app's Photo-Grid format tab calls.
mix a music track under a silent video using ffmpeg. normalizes loudness to roughly -14 LUFS, applies a short fade in and out, and trims or loops the music to match video duration. use after a silent video master and a chosen music file are both ready.
基于 SOC 职业分类
| name | retime-captions-to-words |
| description | Snap SRT cue starts to whisper word-level timestamps within ±100 ms so captions land on word boundaries instead of drifting. |
Captions authored by hand (or generated from an LLM transcript) frequently drift ±100–300 ms relative to actual word starts in the VO. This atom snaps each cue's start time to the nearest matching word from a whisper word-timestamps file, within a tolerance.
End times are recomputed to preserve the cue's original duration unless the next cue would overlap, in which case they butt up to the next cue's new start.
--input <path> — source .srt (required)--output <path> — destination .srt (required)--words <path> — whisper word-level timestamps JSON (required). Expected schema: {"words": [{"text": "...", "start": 1.234, "end": 1.456}, ...]}--tolerance <sec> — max snap distance (default 0.10)--preserve-duration <bool> — keep original duration after snap (default true)For each cue:
start is within tolerance of the cue's current start.|word.start - cue.start|.preserve-duration, shift cue.end by the same delta. Otherwise leave cue.end unchanged.skipped list.<output> — retimed SRTmanifest.json:
{
"input": "...", "output": "...", "words": "...",
"tolerance_seconds": 0.10,
"cues": 42,
"retimed": 31,
"skipped": 11,
"max_shift_seconds": 0.087,
"clipped_ends": 2,
"status": "ok"
}
verification.md — table of every retimed cue (before/after start, delta).max_shift_seconds <= tolerance.cue.end <= next_cue.start).--words file missing or malformed → fail fast with clear error.word → timestamp lookup against words.json outside this atom's tolerance-window flow (e.g. retiming overlays, SFX, or zoom-punches to a specific word like "every" or "Claude"), default first-match silently grabs the wrong occurrence if that word appears multiple times. Verified failure: 11-walking-felt-goose 2026-05-24 — "every" in "generate every clip" at 14.6s vs. "Every. Single. Frame." at 28.3s; first-match grabbed the early one, climax click-ratchets almost shipped 14s early.Any script that retimes media to a specific Whisper word MUST use this signature (or equivalent) — keyword-only after forces conscious disambiguation:
def find_word(words: list[dict], target: str, *, after: float = 0.0) -> dict | None:
"""Return the first Whisper word matching `target` (case-insensitive,
punctuation-stripped) whose `start` is >= `after`.
`after` is keyword-only — callers must consciously pass either 0.0
(acknowledged first-match) or a real disambiguating timestamp.
"""
t = target.lower().strip(".,?!")
for w in words:
if w["text"].lower().strip(".,?!") == t and w["start"] >= after:
return w
return None
Companion recommendation: print derived timestamps to stderr BEFORE rendering so misalignment shows up in the log, not in the final video.
scripts/retime.py \
--input peloton/ads/video-03-ironman-comeback/captions/captions.srt \
--output peloton/ads/video-03-ironman-comeback/captions/captions-retimed.srt \
--words peloton/ads/video-03-ironman-comeback/audio/word-timestamps.json
Consumed by /polish (caption-timing branch) and auto-refine.