Local-first YouTube understanding for coding agents. Give it one exact video URL and it builds an evidence bundle from the best available transcript plus sampled video frames.
Created by @hyungchulc with Aria.
The workflow combines five evidence lanes:
- manual captions
- automatic captions
- Apple's on-device SpeechAnalyzer on eligible macOS 26+ systems when the language asset is already installed
- local Whisper when Apple SpeechAnalyzer is unavailable, unsupported, disabled, or fails
- evenly sampled frames and a contact sheet for visual inspection
It does not require a Gemini API key or a YouTube Data API key. The optional Antigravity CLI is used only to format extracted transcript text. A strict word-sequence check rejects any formatter output that adds, removes, rewrites, or reorders spoken words.
- Python 3.10 or newer
yt-dlpffmpegfor visual bundles and Apple-compatible audio conversion- OpenAI Whisper's local
whisperCLI as the portable captionless-video fallback - optional
agyCLI for verified transcript formatting - optional Apple SpeechAnalyzer on macOS 26 or newer, with supported hardware and locale plus a compatible Xcode or Command Line Tools SDK
The Python script itself uses only the standard library. External media tools must be installed separately and available on PATH. Whisper may download a local model the first time a model is used. SpeechAnalyzer runs on device after its system-managed language asset is installed. The default route never downloads an Apple asset.
Clone the repository, then run:
python3 scripts/youtube_inspect.py \
--out-dir ./youtube-evidence \
"https://www.youtube.com/watch?v=VIDEO_ID"To avoid sending transcript text through Antigravity:
python3 scripts/youtube_inspect.py \
--no-antigravity \
--out-dir ./youtube-evidence \
"https://www.youtube.com/watch?v=VIDEO_ID"For transcript-only output:
python3 scripts/youtube_inspect.py \
--transcript-only --no-antigravity \
--out-dir ./youtube-transcript \
"https://www.youtube.com/watch?v=VIDEO_ID"The output directory is never overwritten. Omit --out-dir to create a uniquely named bundle under ./youtube-inspections/.
Apple SpeechAnalyzer is tried automatically only on macOS when the video language is known. Use --no-apple-speech to skip it. Use --install-apple-speech-assets only when you explicitly want to permit a system-managed model download. Missing or unsupported Apple support falls back to Whisper.
youtube-evidence/
├── manifest.json
├── transcript.txt
├── contact-sheet.jpg
└── frames/
├── frame-001.jpg
└── ...
manifest.json records the source of the transcript (manual-caption, auto-caption, apple-speech-analyzer, or local-whisper), the formatter decision, word count, duration, frame timestamps, and visual availability.
yt-dlpconnects to YouTube to retrieve public metadata, captions, audio, or a low-resolution visual stream.- SpeechAnalyzer runs transcription on device after a supported language asset is installed. It is a macOS 26+ API, not a macOS 27-only API.
- Whisper runs transcription locally after its model is available and remains the cross-platform fallback.
--no-antigravityprevents the optional formatter from receiving transcript text.- Without
--no-antigravity, an installedagymay use its configured provider. The result still has to pass the exact normalized-word invariant. - No direct vendor API integration or API key is built into this repository.
Copy or clone this repository to ~/.codex/skills/aria-youtube, keeping SKILL.md and scripts/youtube_inspect.py together. Codex can then route exact-video questions through the evidence-bundle workflow described in SKILL.md.
Run the deterministic test suite with:
python3 -m pytest -qThe tests cover URL boundaries, caption preference, rolling-caption merging, explicit Apple asset installation, Apple-to-Whisper fallback routing, Antigravity drift rejection, visual-bundle assembly, output safety, and removal of direct vendor API dependencies.
- Automatic captions, SpeechAnalyzer, and Whisper can be wrong, especially when the inferred language is wrong or the audio mixes languages.
- Sampled frames do not prove what happens between samples. Increase
--frame-countfor visually dense videos. - The tool does not perform speaker diarization.
- Private, age-restricted, or region-restricted videos may require an independently authorized authenticated retrieval setup.
- Platform terms and content rights still apply. Do not use this project to bypass access controls or redistribute protected content.
MIT