transcribe-media
Skill2 starsChanged 4 months agoMITView on GitHub
Transcribe local audio or video files into timestamped JSON and readable Markdown with resumable processing and source provenance. Use when a user asks to transcribe, extract spoken content, create subtitles or text from local media, or passes a supported video URL for transcription. For URLs, invoke $download-video first and consume its verified artifact manifest. After a non-empty transcript is complete, ask whether the user wants to invoke $ingest-knowledge; never write to a knowledge base without confirmation.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- VideoTranscriberAI/videotranscriber-skillstheir own version, first seen Oct 13, 2026
- celeryhq/simplified-aitheir own version, first seen Jul 13, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- VideoTranscriberAI/videotranscriber-skills★ 14same name
- celeryhq/simplified-ai★ 4same 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 repository4 other files it gives its agents.
- AGENTS.mdAGENTS.md
- build-obsidian-vaultSkill
- download-videoSkill
- ingest-knowledgeSkill
The file
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 5 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 62
Prefer an exact-basename .srt or .vtt sidecar when present.
- Very specific: line 111
If the transcript contains speech, ask exactly one follow-up: “是否需要把这份内容写入本地 Obsidian 知识库?” If yes, invoke $ingest-knowledge with …
- Very specific: line 146
Keep awesome-capture.transcription-state/v1, the complete awesome-capture.chunk-set/v1 manifest, and per-chunk results so an interrupted …
- Distinctive: line 153
Do not download models. Every ASR engine requires an explicit local model.
- Very specific: line 163
Write chunk results and derivative outputs while state remains running.
- Very specific: line 164
After validating every result and output hash, durably write transcript.pending.json.
- Distinctive: line 172
Treat a platform title, description, chapter summary, or LLM-generated reconstruction as metadata, not transcription.
- Distinctive: line 173
Do not summarize before the transcript artifact is complete.
- Distinctive: line 180
Read engines.md before choosing models, handling long files, or adding an engine.
- Distinctive: line 181
Read artifact-contract.md when composing with another skill.
≈ “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 media
Turn one verified local media input into a traceable transcript artifact. Do not combine transcription with summarization or knowledge-base writes.
Platform boundary
- Mutating and file-verifying operations support Python 3.11–3.14 on macOS and Linux.
- They require POSIX
fcntl,dir_fd,O_NOFOLLOW,O_DIRECTORY, directoryfsync, atomic no-replace rename, and atomic exchange rename. Missing capabilities fail closed withUNSUPPORTED_PLATFORM; there is no weaker fallback. - Input, model, adapter, output, state, and chunk paths must not traverse arbitrary symlinks. Managed files must be current-user-owned regular files with one link.
CLI protocol
Success prints exactly one JSON object to stdout, leaves stderr empty, and exits 0. An expected failure leaves stdout empty and prints exactly one redacted JSON error to stderr. Repository-wide failure codes are: 2 for arguments, schemas, or unsafe inputs/paths; 3 for unavailable dependencies, models, or platform capabilities; 4 for locks, conflicts, recovery conflicts, or stale plans; 5 for external-tool, network, or runtime I/O failures; 7 for contract, identity, or file-evidence integrity failures; and 130 for interruption.
Workflow
- Determine whether the input is a URL or a local path.
- For a URL, invoke
$download-video, require a completeawesome-capture.artifact/v2video artifact, and retain both the artifact path andmedia.path. - For a local path, inspect it directly. Do not invent or guess an adjacent artifact path.
- For a URL, invoke
Check the environment:
python3 scripts/transcribe_media.py doctor \ --model "<absolute-local-ggml-model-path>" \ --whisper-cpp-bin "<absolute-whisper-cli-path>"--engine autorequires both this explicit binary path and the explicit local model path. An explicit--engine whisper-cppmay still discoverwhisper-clionPATHwhen the binary option is omitted. For speech recognition without a sidecar subtitle, requireready_for_asr: true;status: okonly means the diagnostic command itself completed.Inspect the media and confirm it has an audio stream:
python3 scripts/transcribe_media.py inspect "<absolute-media-path>"- Prefer an exact-basename
.srtor.vttsidecar when present. Otherwise select an engine:auto: whisper.cpp only when both--whisper-cpp-binand--modelexplicitly name existing local files. It never discovers the binary fromPATHor selects a Python engine.whisper-cpp: first-class local engine. It requires an explicit local--modelfile and optionally--whisper-cpp-bin.faster-whisper: explicit only; requires a fully local model directory.mlx-whisper: explicit only; requires a fully local model directory and a compatible local MLX installation.external: explicit only; requires--adapter, a local--model, and--trust-external-adapter.
For a local file, run:
python3 scripts/transcribe_media.py transcribe "<absolute-media-path>" \ --output-dir "<absolute-dir>" \ --engine auto \ --model "<absolute-local-ggml-model-path>"For a video produced by
$download-video, pass the handoff explicitly:python3 scripts/transcribe_media.py transcribe \ "<video-artifact.media.path>" \ --source-artifact "<absolute-video-artifact-v2-path>" \ --output-dir "<absolute-dir>" \ --engine auto \ --model "<absolute-local-ggml-model-path>"--source-artifactis never inferred. When present, its schema, contract digest, media path, bytes, SHA-256, duration, stream counts, and current ffprobe evidence are all revalidated.Other transcription options are:
--language <code>to request a language;--ignore-sidecarto force ASR despite an exact-basename subtitle;--chunk-seconds <n>(default600, minimum30);--timeout <seconds>for each external process (default3600);--lock-timeout <seconds>for the persistent job lock (default30).
To bypass the initial whisper.cpp GPU subprocess, add
--whisper-cpp-cpu-only. Normally leave it off: the first GPU failure is recorded, retried with-ng, and cached so the remaining chunks in that task go directly to CPU.- Require zero exit status and a complete
awesome-capture.artifact/v2transcript. Read output paths fromartifact.outputs; do not derive them from filenames. Report the engine, detected language, duration, segment count, transcript Markdown path, and any empty/silent result. - If the transcript contains speech, ask exactly one follow-up: “是否需要把这份内容写入本地 Obsidian 知识库?” If yes, invoke
$ingest-knowledgewithtranscript.json. If no, stop.
Recovery
Transcription uses a persistent job lock and private managed layout:
<output>/.awesome-capture-media/v2/
locks/
staging/
transcriptions/<64-hex-job-id>/
quarantine/The source is copied to a private content-verified snapshot before ffmpeg or
ASR reads it. Managed directories use mode 0700; locks, snapshots, chunks,
state, outputs, pending artifacts, and final artifacts use 0600.
Re-running the same command acquires the same lock and either resumes a valid
running state, publishes a verified pending artifact, or returns reused.
For an explicit recovery pass:
python3 scripts/transcribe_media.py recover \
--output-dir "<absolute-dir>" \
--lock-timeout 30Recovery never overwrites an existing artifact. Unknown workspace files,
unsafe links, conflicting identities, or invalid hashes produce
RECOVERY_CONFLICT or an integrity error.
Reliability rules
- Preserve source timestamps; never invent missing speech.
- Keep
awesome-capture.transcription-state/v1, the completeawesome-capture.chunk-set/v1manifest, and per-chunk results so an interrupted run can resume. - Reject missing or extra chunks, filename gaps, changed hashes, non-mono 16 kHz PCM16 WAVs, inconsistent cumulative timing, foreign state entries, and incomplete result sets.
- Offset each chunk by the cumulative duration measured from the normalized WAV sample counts. Never multiply the nominal
--chunk-secondsvalue by the chunk index. - Do not download models. Every ASR engine requires an explicit local model. Record and bind the model, engine executable or adapter, package versions, settings, and source to the job identity.
- Re-hash the private source snapshot, model, executable/adapter, and the
versioned content identity of the standalone transcription implementation
before publishing. Also compare the execution metadata guard so a component
changed and then restored to the same bytes still aborts with
IDENTITY_CHANGED. Once the private snapshot is durably verified, recovery does not require the original source path or upstream video artifact to remain present. - Write chunk results and derivative outputs while state remains
running. After validating every result and output hash, durably writetranscript.pending.json; only then advance state toready_to_publish. Promotion revalidates source/model/adapter/chunks, advances state tocomplete, and refreshes the pending artifact's state descriptor. Publishtranscript.jsonlast without clobbering an existing entry. - Reject artifact/v1, unversioned or unknown state, duplicate JSON keys, non-finite numbers, and unknown contract properties. Do not migrate or silently fall back.
- Treat a platform title, description, chapter summary, or LLM-generated reconstruction as metadata, not transcription.
- Do not summarize before the transcript artifact is complete.
externalexecutes explicitly trusted local code. It is not selected automatically and is not an OS-level network sandbox.- External media tools run with a working directory pinned by directory FD; regular media/model-file inputs are passed through inherited read-only FDs where supported. Local model directories are still re-hashed before and after execution and are not an OS sandbox.
- Read engines.md before choosing models, handling long files, or adding an engine.
- Read artifact-contract.md when composing with another skill.
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.

