Chrome extension (MV3) that auto-balances per-channel volume on Twitch using real-time ITU-R BS.1770 LUFS measurement of the playing audio. Separate gain is applied during ad breaks.
Twitch does not publish any loudness metadata (no loudnessDb-equivalent API, no HLS audio metadata), so the extension measures the playing <video> directly via Web Audio API and persists the resulting gain per channel × media kind (Live / VOD / Clip).
- Real-time LUFS metering: Momentary (400 ms), Short-term (3 s), Integrated (BS.1770 gated)
- Per-channel auto gain: Save gain per Live / VOD / Clip kind; applied automatically on revisit
- Ad-break handling: Detects
EXT-X-DATERANGE CLASS="twitch-stitched-ad"in HLS manifests and[data-a-target="video-ad-countdown"]in the DOM; applies a separate gain offset during ads - 0–600 % gain range via Web Audio
GainNode(HTML5video.volumewould cap at 1.0) - No external dependencies — pure JavaScript, no bundler
<video>
├─→ MediaElementSource ─→ GainNode ─→ destination (playback)
└─→ MediaElementSource ─→ K-pre ─→ K-RLB ─→ AudioWorklet (measurement)
│
└─→ port.postMessage
(per 100 ms mean-square)
The measurement path applies the BS.1770-4 K-weighting (high-shelf pre-filter + RLB high-pass), accumulates mean-square in an AudioWorklet, and the main thread aggregates 400 ms momentary, 3 s short-term, and gated integrated LUFS in real time.
- Clone or download this repository
- Open
chrome://extensions/ - Enable Developer mode
- Click Load unpacked and select this folder
- Open a Twitch stream, VOD, or clip
- Wait a few seconds for integrated LUFS to stabilize
- Click the extension icon → Apply to channel
- The computed gain is saved per channel × kind and re-applied on revisit
- Use the manual slider (0–600 %) for one-off adjustments
- Ad break gain is configurable in Settings (default −6 dB)
- Target LUFS: Reference loudness used to compute gain (default −18 LUFS, range −30 to −6)
- CM Gain: Extra gain applied during ad breaks (default −6 dB)
- Display unit: % or dB
- Saved channels: Table view with delete / clear-all
# Run tests
node test.js
# Regenerate icons (requires Pillow)
python3 gen_icons.py
# Build Chrome Web Store zip
python3 pack.pyA static compressor (like FrankerFaceZ's option) clips loud peaks but does nothing about median loudness drift across channels. This extension targets a constant integrated loudness across channels, the way YouTube does for VODs — except Twitch refuses to do it server-side.
- Twitch does not perform loudness normalization on either streams or ads
- Loudness varies wildly between channels (often 20 + dB)
- California SB 576 (enforcement 2026-07-01) may force changes for ads
- Other major platforms normalize: YouTube (-14 LUFS), Spotify (-14 LUFS), Apple Music (-16 LUFS)
- No external network requests; all data stays on your device in
chrome.storage.local - Audio/video data itself is never recorded or transmitted — only computed LUFS values and your gain settings are kept
- See PRIVACY_POLICY.md (日本語) for details
MIT