Synchronized closed captions, SRT/WebVTT/TXT/JSON export, and opt-in encrypted cloud sync for Google NotebookLM Video Overviews.
Download lm-subs-v0.2.8.zip | Beginner Setup Guide | Neon vs Supabase & Firebase Guide (DEPLOYMENT_GUIDE.md) | About (@sarang-cmd)
You do not need terminal commands, developer tools, or a paid subscription to use LM Subs. Follow these four steps in Google Chrome, Brave, Microsoft Edge, or Arc:
- Download
lm-subs-v0.2.8.zipto your computer. - Unzip it into a normal folder:
- macOS: Open Downloads in Finder and double-click
lm-subs-v0.2.8.zip. Move the unzipped folder into Documents so it stays in a permanent spot. - Windows: Open Downloads in File Explorer, right-click
lm-subs-v0.2.8.zip, click Extract All..., and click Extract. Keep the unzipped folder somewhere permanent such as Documents.
- macOS: Open Downloads in Finder and double-click
- Open a new browser tab, type
chrome://extensionsinto the address bar, and press Enter (brave://extensionsin Brave,edge://extensionsin Edge). - Turn ON the Developer mode switch in the top-right corner of the page.
- Click the Load unpacked button in the top-left corner and select the unzipped
lm-subsfolder from Step 1. - Click the puzzle-piece icon in the top-right Chrome toolbar and click the pin icon beside LM Subs.
LM Subs connects directly from your browser to a speech-to-text provider so nobody charges you a subscription fee. Groq offers a free developer account with no credit card that transcribes up to 8 hours of audio per day:
- Open console.groq.com/keys and sign in with Google or GitHub.
- Click Create API Key, enter
LM Subsas the name, and copy the key starting withgsk_. - Click the LM Subs icon in your Chrome toolbar, paste that
gsk_...code into the API key box, and click Save.
- Open notebooklm.google.com, open any notebook, and play a Video Overview.
- Within about three seconds, synchronized captions with active-word highlighting appear inside the lower frame of the video player (accompanied by an optional completion chime).
- Use the compact CC, Transcript, and ••• controls docked inside the bottom play bar to toggle captions (
C), open the click-to-seek Transcript drawer (T), adjust word-for-word highlight delay ({/}or the Style slider), switch caption backdrop (B), resize text (A- / A+), shift cue timing ([/]), view keyboard shortcuts (?), or export.srt,.vtt,.txt,.md,.csv, or.jsonfiles.
Synchronized closed captions with 3-state progressive word highlighting, adjustable word-highlight delay (-500 ms to +1500 ms), compact CC and Transcript controls integrated directly into the bottom play bar, and a secondary tools popover for styling, study loops, and .srt/.vtt/.txt/.md/.csv/.json export.
Every number on the website is the same number the extension reports, computed on your device and merged with your account when you sign in: watch time, listening time, exports, and per provider usage.
Configure a free Groq or Mistral key, inspect account sync state, trigger captions on the active NotebookLM tab, or export .srt, .vtt, .txt, and .json files in two clicks. Includes an inline first-time setup guide when no key is saved yet.
Sign in with Google, GitHub, or a 6-digit email code, toggle granular cloud sync switches (Sync API keys, Sync transcriptions, Sync preferences), inspect real transcription metrics, and order all 12 speech-to-text providers.
Setup finishes itself: pin the extension, paste one free API key, then press CC on any overview.
Google NotebookLM generates narrated Studio Video Overviews, yet its built-in player ships without closed captions, downloadable subtitle files, or cross-browser transcript sync.
Naive transcription tools upload entire 50 to 120 MB HD .mp4 video files or inflate compressed audio into 40+ MB of uncompressed .wav data, hitting API upload limits and turning a 3-minute Video Overview into a multi-minute wait.
| Metric | Full Video / WAV Upload | LM Subs (v0.2.8) |
|---|---|---|
| Media payload | 50 to 120 MB .mp4 + 42 MB .wav |
~3.4 MB =m140 AAC (or HTTP 206 audio byte ranges) |
| Audio prep overhead | 45 to 90s full download + decode | 0 ms direct =m140 passthrough (<1.2s Range remux) |
| Whisper timestamp mode | Slow word-level DTW alignment | Segment timestamps (~200x real-time) + clause balancer |
| Long-video chunking | Sequential 1-by-1 upload | 3x concurrent workers + live progressive cues |
| Second-browser open | Re-downloads and re-transcribes | ~50 ms Neon Postgres cache hit (0 media bytes fetched) |
- Zero-decode
=m140audio stream passthrough (0 msIPC): Google's FIFE=m140stream serves a ~3 to 6 MBaudio/mp4payload.service-worker.jsinspectsinspectMp4Tracks()andContent-Typeand forwards pure-audio payloads (<=24 MB) directly to your speech-to-text provider without inflating them into PCM.wav. - Parallel
HTTP 206 Partial Contentaudio byte-range extraction: When a CDN edge serves a muxed 50 to 120 MB=m22video/mp4, LM Subs aborts the full download after reading headers, probes themoovatom viaRange: bytes=..., and fetches only the 3 to 6 MBsounaudio slices over 6 parallelHTTP 206requests. - Segment-level Whisper timestamps (~200x real-time): Requesting segment timestamps instead of word-level DTW alignment and balancing two-line cues client-side via
cuesFromSegments()cuts transcription latency by 4 to 8x. - Concurrent chunk workers + progressive cues (
SUBTITLES_PARTIAL): Long recordings (>24 MB) transcribe 3 audio chunks concurrently and render live cues on the<video>element as soon as chunk 1 completes. - Pre-download Neon Postgres cache hit (~50 ms): Before downloading media from Google's CDN,
service-worker.jschecks local storage andGET /api/sync/subtitle?cacheKey=...so previously captioned videos load instantaneously across your signed-in browsers.
- Page Main World (
src/content/page-hook.jsatdocument_start): Observes NotebookLM SSRAF_initDataCallbackpayloads andbatchexecuteRPCs (R7cb6c,gArtLc) without touching storage or credentials. - Isolated Content Script (
src/content/content.js+player-overlay.js): Attaches both a native<track kind="subtitles">(for OS Picture-in-Picture) and an isolated closed ShadowRoot caption bar inside NotebookLM's<video>container. - MV3 Service Worker (
src/background/service-worker.js): Sole reader ofsecretApiKeysandcloudSyncSecretinchrome.storage.local. Executes audio stream extraction, 12-provider failover, and opt-in cloud sync. - Hosted Web App & Neon Postgres API (
src/web/,server/,api/index.js): React + Radix UI web application (/,/guide,/library,/stats,/about) and Hono REST API backed by Neon Serverless PostgreSQL (db/schema.sql). Includes Vercel Web Analytics and Vercel Speed Insights.
End users never self-host a database or configure a server URL. Sign in from the extension or web app using Google, GitHub, or a passwordless 6-digit email code:
- Granular opt-in switches: Control three independent switches in both the web library and extension settings:
- Sync API keys (
AES-256-GCMper-user HKDF-derived encryption bound to${userId}:${providerId}as AAD). - Sync transcriptions (searchable caption archive with
.srt,.vtt,.txt, and.jsondownloads). - Sync preferences (provider priority order, caption font scale, and target language).
- Sync API keys (
- One-click cloud purge: Turning off any switch can immediately delete your stored cloud rows for that category in Neon Postgres while keeping your local Chrome data untouched.
- Live SQL statistics (
/stats): Displays realCOUNT,SUM,AVG, 14-day daily transcription volume, upload bandwidth saved, and per-provider latency queried directly fromlmsubs_subtitlesandlmsubs_transcription_events.
Read DEPLOYMENT_GUIDE.md for:
- A first-principles guide correlating Neon with Supabase and Firebase (SQL Editor migrations, why no storage buckets are needed, why Firebase auto-configures Google OAuth while Supabase and Vercel + Neon use Google Cloud Console OAuth credentials, and server-vault encryption vs client RLS).
- Exact step-by-step instructions to connect Neon (
falling-cherry-16443194), Google OAuth, GitHub OAuth, and Resend on Vercel.
Configure one key or stack multiple providers in priority order for automatic HTTP 429 rate-limit failover:
| Rank | Provider | Default model | Free tier and billing notes |
|---|---|---|---|
| 1 | Groq (Recommended) | whisper-large-v3-turbo |
Free developer tier (~8 hrs/day, no credit card) |
| 2 | Mistral AI (Recommended) | voxtral-mini-latest |
Free La Plateforme tier, 48 MB file cap |
| 3 | Google Gemini | gemini-2.5-flash |
Free Google AI Studio tier, native translation |
| 4 | Deepgram | nova-3 |
$200 free starter credit |
| 5 | AssemblyAI | universal |
$50 free starter credit |
| 6 | Gladia | solaria-1 |
10 free hours per month |
| 7 | Cloudflare Workers AI | @cf/openai/whisper-large-v3-turbo |
10,000 free neurons per day |
| 8 | ElevenLabs | scribe_v1 |
Free starter quota, 99 languages |
| 9 | Hugging Face | openai/whisper-large-v3-turbo |
Free monthly inference credits |
| 10 | OpenRouter | google/gemini-2.5-flash |
Unified multi-model router |
| 11 | OpenAI | whisper-1 |
Pay-as-you-go ($0.006/min) |
| 12 | Local / Custom | Systran/faster-whisper-small |
100% free and offline (faster-whisper-server / whisper.cpp) |
- Minimal Manifest V3 permissions: Requests only
"storage"inextension/manifest.json, plus narrow host permissions for NotebookLM and Google media CDNs. - Service-worker secret isolation: Automated static-analysis tests (
tests/e2e.test.js) verify thatcontent.js,page.js,popup.js, andoptions.jsnever import secret-storage getters. - Diagnostic redaction:
GET_DEBUG_REPORTscrubsBearerheaders,lms_...session tokens,gsk_.../sk-.../AIza...keys, and signed FIFE query parameters.
npm install # Install dependencies (0 vulnerabilities)
npm run assets # Render SVG/PNG brand marks, favicons, badges, diagram, and 4 screenshots
npm run build # Bundle all 5 MV3 extension entrypoints + React web app (docs/app.js)
npm run zip # Rebuild bundles and package docs/releases/lm-subs-v0.2.8.zip
npm test # Run unit, security, speed, export, and PGlite Postgres E2E tests
npm start # Start unified Web App + /api/* Hono server on http://0.0.0.0:4173Created by Sarang (@sarang-cmd), a computer science student and agentic engineer based in Germany.
Released under the MIT License. Independent open-source project, unaffiliated with Google LLC.




