Instant YouTube subtitle extraction for Safari — no login, no tracking, no BS.
A lightweight userscript that adds a floating button to YouTube for one-click transcript extraction. Works with Safari (via Userscripts) and any browser with userscript manager support (Tampermonkey, Violentmonkey, Greasemonkey).
- ⚡ Instant extraction — intercepts YouTube's internal subtitle loading, works in ~1 second regardless of video length
- 🌍 Language switching — choose between all available subtitle tracks right in the modal
- 📋 One-click copy — copy full transcript to clipboard (Safari-compatible via
execCommand) - 💾 Download as TXT — save transcript as a text file
- 🎨 Clean dark UI — modal with video title, line/char count, keyboard shortcuts
- 🔒 Zero tracking — no accounts, no analytics, no data collection
- 🆓 100% free & open source
- Open any YouTube video with subtitles
- Click the red 📋 Copy Transcript button (bottom-right corner)
- Modal appears with full transcript text
- Copy, download, or switch language
- Install Userscripts from the App Store
- Set a directory for your scripts in the extension settings
- Download
yt-transcript-extractor.user.jsand place it in that directory - Enable the extension in Safari → Settings → Extensions
- Open any YouTube video — the button appears automatically
- Install Tampermonkey or Violentmonkey
- Click Install Userscript or create a new script and paste the contents
- Open any YouTube video
Most YouTube transcript tools try to fetch() the subtitle URL directly — but YouTube blocks these requests, returning empty responses (Content-Length: 0).
This script takes a different approach:
- Intercepts
XMLHttpRequest— patchesXHR.prototype.open/sendto listen for YouTube's internaltimedtextAPI calls - Triggers subtitle reload — calls
player.setOption('captions', 'reload', true)which forces the YouTube player to re-fetch subtitles through its own internal mechanism (which works because the player has the right cookies/headers) - Captures the response — grabs the full JSON3 subtitle data from the intercepted XHR
- Parses and deduplicates — extracts text segments, removes consecutive duplicates, joins into clean text
This is why it works where direct API calls fail — we're reading the data that YouTube's own player successfully fetches, not making our own requests.
| Key | Action |
|---|---|
Esc |
Close modal |
| Browser | Userscript Manager | Status |
|---|---|---|
| Safari (macOS) | Userscripts | ✅ Primary target |
| Safari (iOS) | Userscripts | ✅ Should work |
| Chrome | Tampermonkey / Violentmonkey | ✅ Works |
| Firefox | Tampermonkey / Violentmonkey / Greasemonkey | ✅ Works |
| Edge | Tampermonkey | ✅ Works |
- Only works on videos that have subtitles (auto-generated or manual)
- Prefers subtitles in this order: Russian → English → first available
- YouTube SPA navigation is supported — button appears/disappears as you navigate
Contributions are welcome! Feel free to open issues or submit PRs.
Built with frustration and determination when no Safari extension could do this simple thing. 🦞