subtitles
Skill1 starsChanged 3 months agoMITView on GitHub
Convert, shift, extract, and burn subtitle files (SRT/WebVTT). Use when you already have caption text or embedded subtitle tracks and need format conversion, sync adjustment, extraction from containers, or hardcoded captions on video.
6 other projects use a version of this.
Adopted by
Most recently taken up by
- openai/pluginstheir own version, first seen Oct 13, 2026
- Gopyr/gopyr-skills-hubtheir own version, first seen Oct 11, 2026
- artemchuikin/youtube-skillstheir own version, first seen Oct 11, 2026
- ZeroPointRepo/youtube-skillstheir own version, first seen Aug 11, 2026
- bwhite001/nas-claude-skillstheir own version, first seen May 23, 2026
- MatrixReligio/ProductVideoCreatortheir own version, first seen Jan 26, 2026
Other versions6 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 6
- openai/plugins★ 7.8ksame name
- ZeroPointRepo/youtube-skills★ 972same name
- artemchuikin/youtube-skills★ 273same name
- MatrixReligio/ProductVideoCreator★ 41same name
- bwhite001/nas-claude-skills★ 1same name
- Gopyr/gopyr-skills-hub★ 0same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository16 other files it gives its agents.
- AGENTS.mdAGENTS.md
- site/AGENTS.mdAGENTS.md
- site/CLAUDE.mdCLAUDE.md
- audioSkill
- captions-complianceSkill
- downloadSkill
- forced-narrative-exactSkill
- imageSkill
- inspectSkill
- install-media-toolsSkill
- program-masterSkill
- shotsSkill
- speech-captionsSkill
- timecodeSkill
- video-transformationSkill
- vision-analysisSkill
The file
We split this skill into the rules it gives an agent
6 rules. 0 are common, 2 are distinctive, and 4 are very specific to this project.
0
Common
Most of the 4 edited versions we read keep these.
2
Distinctive
This author's own choices. Worth a look.
4
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 43
If your tools showed a filesystem path when loading this SKILL.md, strip SKILL.md and use that folder.
- Very specific: line 44
If you already ran another mediaskills script (for example .../audio/scripts/extract.py), this skill is a sibling of that folder: same …
- Very specific: line 67
Prefer absolute paths for --input / --output when cwd is uncertain.
- Distinctive: line 72
Before running any script, treat these two failures differently:
- Very specific: line 75
Only escalate sandbox permissions if the error is explicitly a permission denial (e.g.
- Distinctive: line 91
Use negative values if captions are late relative to dialogue.
“Common” is measured: kept by at least 6 in 10 of the 4 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Subtitles
Subtitle file operations and burn-in. Use this skill when you need to work with caption files or embedded tracks — not automatic speech recognition (use speech-captions for that).
When to use
- This skill — SRT ↔ VTT conversion, sync offset, extract
0:s:0subtitle stream, burn SRT into video. speech-captions— generate captions from spoken audio when no subtitle track exists.video-transformation— mux soft subtitles into a container, transcode, or re-wrap streams without burning.inspect— list streams and confirm a subtitle track exists beforeextract.py.
Gotchas
- Extract maps first subtitle stream only —
extract.pyuses-map 0:s:0. Multi-language containers may need manual ffmpeg maps for other indices. - Burn re-encodes video —
burn.pyoverlays PNG captions and outputs H.264 (libx264, CRF 20). Audio is stream-copied when present. Expect generation time to scale with cue count. - Burn expects SRT — WebVTT must be converted with
convert.pyfirst. VTT timing and styling tags are not preserved on burn. - Shift clamps to zero — negative offsets clamp cue starts at
0.0; very negative shifts can collapse short cues to a 0.1 s minimum duration. - No libass dependency — burn uses Pillow text rendering with a simple bottom-centered box. Complex ASS styling (fonts, positioning, karaoke) is not supported.
- SRT vs VTT on shift — output format follows input extension (
.srtor.vtt). Convert first if you need a different target format.
Running scripts
This skill's scripts live in scripts/ alongside this file. Before running any script, resolve its absolute path from this skill's own directory — do not assume the shell cwd is the skill folder, the repo root, or the workspace. Stay in the workspace (so media paths resolve) and pass the absolute script path to uv run:
uv run <skill_directory>/scripts/convert.py --input captions.srt --format vtt<skill_directory> is a placeholder. Never pass those angle brackets to the shell — the command will fail. Replace it with a real absolute directory before invoking uv run.
How to get that directory (do this yourself; do not ask the user first; do not skip the skill):
- If your tools showed a filesystem path when loading this
SKILL.md, stripSKILL.mdand use that folder. - If you already ran another mediaskills script (for example
.../audio/scripts/extract.py), this skill is a sibling of that folder: same parent, directory namesubtitles. - Otherwise search standard install locations and confirm the script exists:
NAME=subtitles
for d in \
"$HOME/.agents/skills/$NAME" \
"$HOME/.cursor/skills/$NAME" \
"$HOME/.codex/skills/$NAME" \
"$HOME/.claude/skills/$NAME" \
"$PWD/.agents/skills/$NAME" \
"$PWD/.cursor/skills/$NAME" \
"$PWD/skills/$NAME"
do
if [ -f "$d/SKILL.md" ] && [ -e "$d/scripts/convert.py" ]; then
SKILL_DIR=$(cd "$d" && pwd)
break
fi
done
[ -n "$SKILL_DIR" ] || { echo "mediaskills: $NAME not found" >&2; exit 1; }
uv run "$SKILL_DIR/scripts/convert.py" --input captions.srt --format vttPrefer absolute paths for --input / --output when cwd is uncertain.
Missing binaries vs permissions
Before running any script, treat these two failures differently:
- If a required binary (
uv,ffmpeg,ffprobe) reportsNo such file or directoryorcommand not found: this is a missing or unreachable binary, not a permissions issue. Escalating sandbox permissions will not fix it. Runcommand -v uv,command -v ffmpeg, andcommand -v ffprobeto see whether they resolve at all. If not, install or re-link them (install-media-toolsdoctor/install) rather than retrying with wider permissions. - Only escalate sandbox permissions if the error is explicitly a permission denial (e.g.
Operation not permitted,Permission denied).
Recipes
Convert SRT to WebVTT for HTML5 players
uv run <skill_directory>/scripts/convert.py --input captions.srt --format vtt --output captions.vttFix captions that start 1.5 seconds early
uv run <skill_directory>/scripts/shift.py --input captions.srt --offset-seconds 1.5Use negative values if captions are late relative to dialogue.
Extract embedded subtitles from MKV/MP4
uv run <skill_directory>/scripts/extract.py --input movie.mkv --output extracted.srtFails clearly when no subtitle stream exists — fall back to speech-captions transcribe.
Hardcode captions for social delivery
uv run <skill_directory>/scripts/burn.py --input clip.mp4 --subtitle captions.srt --output clip_subbed.mp4Each cue becomes a timed full-frame PNG overlay; plan for longer encodes on caption-heavy videos.
Typical workflow after ASR
speech-captions transcribe→ SRTsubtitles shift— fix syncsubtitles convert— VTT for web, keep SRT for editorssubtitles burn— optional deliverable without player subtitle support
Troubleshooting
| Error / symptom | Likely cause | Action |
No embedded subtitle track found | Container has no s: stream | Use speech-captions transcribe or mux subs first |
No subtitle cues found | Empty or malformed file | Validate SRT/VTT structure; re-export from editor |
ffmpeg failed on burn | Overlay filter error, corrupt video | Probe with inspect; test shorter clip |
| Wrong language track extracted | Not stream 0:s:0 | Extract manually with ffmpeg -map 0:s:N |
| Blurry burned text | Small output resolution | Use higher-res source; burn scales font to frame height |
Available scripts
| Script | Purpose |
scripts/convert.py | SRT ↔ WebVTT |
scripts/shift.py | Offset all cue timings |
scripts/extract.py | Pull embedded subtitle track to SRT |
scripts/burn.py | Hardcode SRT captions into video |
Acceptance checks (agent must pass before delivery)
- Contract: exit 0,
ok: true, everyoutput_pathsentry exists and is non-empty. - Spot-check: after
shift.py, first/last cue times moved by the requested offset; afterburn.py, re-inspectand visually sample burned frames. - On failure: fix timing/path and retry; do not deliver burn-in without opening at least one frame.
Do not use for
- Automatic speech recognition (use
speech-captions) - FCC/SCC compliance validation (use
captions-compliance) - On-screen text / graphics QC (use
vision-analysis)
Related skills
speech-captions— automatic transcription to SRT/VTTvideo-transformation— trim, transcode, mux without burninginspect— stream and duration metadatainstall-media-tools— install ffmpeg/ffprobe
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

