transcribe-anything
Skill0 starsChanged 3 months agoMITView on GitHub
Transcribe audio or video into text and subtitles (.txt + .srt) from ANY source — a URL (YouTube, Instagram, TikTok, Twitter/X, Vimeo, a podcast, a direct .mp4/.mp3 link), an uploaded or local media file, or a whole batch (playlist, channel, saved collection). Use this whenever the user wants a transcript, captions, subtitles, or "what's said" in any video or audio, mentions yt-dlp or Whisper, wants to caption reels/shorts, or points at a media link or file and asks what's in it — even if they don't say the word "transcribe." Handles the parts that usually break: platform bot-blocking on cloud/datacenter IPs (routes the work to a local runner), private or login-only content (cookies-from-browser + browser enumeration), engine selection (faster-whisper by default, whisper.cpp / openai-whisper / parakeet as alternatives), and batch resume after interruptions.
- Installs packages
2 other projects use a version of this.
Adopted by
Most recently taken up by
- biyearly-mesothelioma790/skillstheir own version, first seen Mar 28, 2026
- swyxio/skillstheir own version, first seen Mar 28, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- swyxio/skills★ 199same name
- biyearly-mesothelioma790/skills★ 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 repository3 other files it gives its agents.
- get-it-out-thereSkill
- trial-reelsSkill
- voice-skill-templateSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 3 are distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈3
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 53
If you're unsure whether a platform blocks, it's cheap to just try it in the sandbox once — a bot-check or 503 tells you immediately to …
- Very specific: line 155
If a plain-CLI Whisper isn't installed but whisper-ctranslate2 is (the self-bootstrap case), the script falls back to it automatically.
- Distinctive: line 167
When given many items (a playlist, a folder, a list of URLs, an enumerated collection):
- Very specific: line 185
Write them to --out-dir (default: current directory.
- Distinctive: line 195
Music/lyrics: If a track is a song, Whisper will attempt the lyrics, but reproducing song lyrics is a copyright problem.
- Distinctive: line 198
Other people's private content: Don't help pull login-only content the user doesn't actually have access to.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Transcribe Anything
Turn any spoken audio or video into a transcript and subtitles. The mental model is always the same three moves:
- Acquire the audio — either it's already a file you have, or you pull it
from a URL with
yt-dlp. - Transcribe it with a Whisper-family model.
- Emit a
.txttranscript and a.srtsubtitle file, then clean up the audio (after confirming, unless told otherwise).
The reason this skill exists is that step 1 is where things quietly fail, and where the work runs matters more than the code. Get the routing right and the rest is easy. So start there.
Nothing to configure. Unlike the scheduling skills in this repo, this one needs no accounts, API keys or recorded settings — it installs its own dependencies. The only thing it needs from you is the media (or a URL), and for some sources, permission to run on your own machine rather than in a sandbox. Step 0 works out which.
Step 0 — Decide the input type and where it can run
This decision determines everything else. Don't skip it. The key fact: some platforms block downloads from datacenter/cloud IPs (which is what this sandbox is) but not from a person's home/office connection. Reason it through:
| Input | Where it works | Notes |
| An uploaded / local file (they attached an mp3, mp4, wav, m4a, etc.) | Anywhere, including this sandbox | No download step at all — go straight to transcribe. This is the easiest case; prefer it when possible. |
A URL on an open platform — Twitter/X, TikTok, Vimeo, most podcasts, a direct .mp4/.mp3 link | Sandbox OK (after the SSL fix below) or local | These generally don't bot-block, so you can download + transcribe right here. |
| A YouTube URL | Local only (reliably) | YouTube rejects datacenter IPs with "Sign in to confirm you're not a bot." Not fixable server-side. |
| An Instagram URL | Local only (reliably) | Instagram returns HTTP 503 to datacenter IPs. |
| Private / login-only content — an IG saved collection, a private post, members-only video | Local only, with the user's browser session | Needs --cookies-from-browser; a saved collection also needs its items enumerated from a logged-in browser first (see references/private-and-batch.md). |
If you're unsure whether a platform blocks, it's cheap to just try it in the
sandbox once — a bot-check or 503 tells you immediately to route local.
When the answer is "local only," don't fake it. You cannot run software on the user's machine and this sandbox is blocked, so the honest move is to hand them a runner they execute locally (next section). Never invent a transcript for media you couldn't actually hear — a fabricated transcript is far worse than an honest "run this and paste me the output."
Running in the sandbox (uploaded files & open platforms)
For uploaded files this is the whole job; for open-platform URLs it works once the proxy's certificate is trusted.
Fix SSL first (one time per sandbox session) — yt-dlp and Python
requests fail TLS verification against the egress proxy's self-signed cert
until you append the gateway CAs to certifi's bundle:
CERTIFI=$(python3 -c "import certifi; print(certifi.where())")
for f in /usr/local/share/ca-certificates/egress-gateway-ca-*.crt \
/usr/local/share/ca-certificates/swp-ca-*.crt; do
[ -f "$f" ] && { printf '\n' >> "$CERTIFI"; cat "$f" >> "$CERTIFI"; }
doneThen install and run:
pip install --break-system-packages -q yt-dlp faster-whisper
python3 scripts/transcribe.py "<url-or-/mnt/user-data/uploads/file>" --out-dir /mnt/user-data/outputsUploaded files live under /mnt/user-data/uploads/. Pass the path directly —
no download, no SSL fix needed for that case.
Running locally (YouTube, Instagram, private, or big batches)
Hand the user scripts/transcribe.py. If they're not set up with Python
tooling (no yt-dlp, no Whisper on PATH — common), give them the
self-bootstrapping runner instead: scripts/transcribe_local.sh. It builds
its own private virtualenv, installs yt-dlp + whisper-ctranslate2 into it,
needs no admin password and no system ffmpeg (the av/PyAV wheel bundles
ffmpeg libraries, and a single progressive download needs no muxing), and then
transcribes. The user runs exactly one command:
bash ~/Downloads/transcribe_local.shKey local-only details, explained so you can adapt them:
--cookies-from-browser chromeletsyt-dlpborrow the user's logged-in session, which is what makes private/age-gated/region-locked content reachable. macOS will prompt for the login keychain password to read the cookie store — that's the OS asking, normal and safe; the user types it into Apple's own dialog. Swapchromeforsafari/firefox/brave/edgeto match their browser.- Batches should be resumable. These runs get interrupted by rate limits. Skip any item whose transcript already exists so re-running just continues.
- Offer to wire it as a Claude Code slash command (
~/.claude/commands/ transcribe.mdcontainingRun: python3 /full/path/transcribe.py $ARGUMENTS) or a shell alias, since this user reuses these as CLI tools.
For private collections and playlists (enumerating items, browser-driven
extraction), read references/private-and-batch.md.
Smoothest batch hand-off (prefer this for collections)
Handing over transcribe.py + transcribe_local.sh + a long pasted list of
URLs works, but it has friction and depends on the user's Python version. When
you already know the fixed set of items (an enumerated IG collection, a
playlist), the smooth path is to give the user one self-contained script
with the IDs baked in, run with a single bare command:
bash ~/Downloads/collection_runner.shCopy scripts/collection_runner.sh, paste the enumerated shortcodes/URLs into
its ITEMS=( ... ) array, set PLATFORM/BROWSER/MODEL, and deliver that
one file. It calls yt-dlp + whisper-ctranslate2 directly (so it never hits
transcribe.py's import path), reuses an already-built venv, uses the user's
browser cookies, is resumable, and leaves photo-only posts alone. This is the
flow that runs cleanly end-to-end in practice.
The script
scripts/transcribe.py is the unified CLI. It accepts one or more URLs and/or
local file paths, auto-detects whether each needs downloading, and writes
.srt + .txt per item. Read the top of the file for the full flag list;
the ones that matter most:
--model—tiny|base|small|medium|large-v3(defaultbase; bigger = more accurate + slower).smallis a good speed/quality balance for talking-head content.--engine—faster-whisper(default),whisper-cpp, oropenai-whisper. Seereferences/backends.mdfor when to pick which.--language— force a language (e.g.pl,en) to skip auto-detect.--cookies-from-browser <browser>— for local private/blocked content.--out-dir,--keep-audio,-y/--yes— output location and cleanup policy.
If a plain-CLI Whisper isn't installed but whisper-ctranslate2 is (the
self-bootstrap case), the script falls back to it automatically.
Python version gotcha: macOS ships Python 3.9 as python3, which chokes on
X | None type hints evaluated at function-definition time. transcribe.py
guards against this with from __future__ import annotations at the top — keep
that line. If you ever see TypeError: unsupported operand type(s) for | on a
user's machine, that import is missing or the venv is using an old Python.
collection_runner.sh sidesteps the issue entirely by not importing the script.
Batch behavior (get this right — it's what makes it usable)
When given many items (a playlist, a folder, a list of URLs, an enumerated collection):
- Process them one by one with a clear
[3/25]-style progress line. - Skip items already transcribed (check for the output file) so an interrupted run resumes cleanly on re-invocation.
- Continue past failures — one dead link shouldn't halt the batch.
- Leave no-audio items alone and report them at the end. Not every saved post is a video; photo posts simply have no audio, and that's fine — collect their IDs and list them in a short summary rather than erroring.
Output
Per source you produce two files named after the source (title or ID):
<name>.txt— plain transcript, paragraph text.<name>.srt— timestamped subtitles ready for video editors / uploads.
Write them to --out-dir (default: current directory; in-sandbox use
/mnt/user-data/outputs).
Being a good citizen
This skill is for transcribing content the user owns or has legitimate access to — their own recordings, uploads, or their own saved/subscribed media — for personal reference, captioning, notes, or accessibility. Keep two things in mind and mention them when relevant:
- Music/lyrics. If a track is a song, Whisper will attempt the lyrics, but reproducing song lyrics is a copyright problem. Flag music-driven items and note them rather than treating garbled lyric output as a useful "transcript."
- Other people's private content. Don't help pull login-only content the user doesn't actually have access to. Using their own logged-in session to reach their own saved items is fine; circumventing access they don't have is not.
Reference files
Load these as needed — don't read them all up front:
references/environments.md— sandbox vs. local specifics, the SSL cert fix in depth, the full per-platform blocking picture, and how to test quickly.references/private-and-batch.md— private IG saved collections, playlists, channels; enumerating items from a logged-in browser; cookies handling.references/backends.md— faster-whisper vs. whisper.cpp vs. openai-whisper vs. parakeet: install, speed/accuracy tradeoffs, and how to choose.
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.

