A screen recording, transcribed on the Mac's GPU by MLX Whisper — whisper-large-v3-turbo, running local. Nothing uploaded. No CPU-bound crawl.
Speech-to-text is the boring prerequisite for half the interesting work — reading a narrated video, salvaging a meeting capture, mining a voice memo. So every skill that needed it re-derived the same Whisper command, badly. And the obvious one, the plain openai-whisper CLI, quietly falls back to CPU and grinds.
One primitive, one engine. mlx_whisper is the MLX-optimized Whisper build — it runs on the Mac's GPU, default model whisper-large-v3-turbo: near-large-v3 quality at a fraction of the time. The script normalizes any input (audio or video) to 16 kHz mono wav, runs it, and prints the transcript path as the last stdout line so a caller can just capture it.
read-narrated-video, extract-video-subtitles, and extract-gdrive-transcript now all route here instead of rolling their own. One engine, shared.
--format json gives a word-timestamped transcript.Not this skill: what a video shows visually → read-narrated-video. An already-embedded caption track → extract-video-subtitles (ffmpeg stream copy, instant). A Drive/Meet recording behind a browser → extract-gdrive-transcript.
Point it at a file. That's the whole interface:
# writes txt/vtt/srt/tsv/json alongside the recording skills/transcribe-media/transcribe.sh ~/Movies/"2026-07-15 16-33-32.mkv" # or capture just the transcript path for downstream use transcript=$(skills/transcribe-media/transcribe.sh meeting.mp4 --format txt --language en | tail -1)
-- --condition-on-previous-text False to break the loop, or trim the silent lead/tail first.~/.cache/huggingface; cached after that.mlx_whisper + ffmpeg on PATH, Apple Silicon. Failure prints TRANSCRIBE_FAILED … and exits non-zero.--model mlx-community/whisper-large-v3 buys accuracy with time.