Table of Contents
What Widevine DRM Actually Is
Widevine is Google's DRM system, used by almost every premium streaming service (Netflix, Prime, Disney+, HBO, Sky, many regional OTTs). It works by encrypting the video segments with AES-128 or AES-128-CTR, and delivering the decryption keys only to client devices that pass an integrity check against Widevine's license server.
The server-side encryption is CENC (Common Encryption). The key itself is delivered to the client through a license request signed by the Widevine CDM on the device. For an IPTV panel that wants to restream a Widevine-protected source, you need:
- The encrypted MPD/DASH manifest and its segments.
- The KID (key ID) and KEY (128-bit AES key) to decrypt them.
- A decryption pipeline that produces cleartext video bytes.
- A re-mux step that wraps the cleartext bytes in HLS/TS for your clients.
Legal Preface
The Decrypt-and-Republish Pipeline
The hard steps are (1) the decryptor and (2) the pipe handoff without disk writes (critical if the keys rotate).
Where Keys Come From
Three legitimate sources:
- Contract with the rights holder. They give you the CENC keys directly. Most common for B2B OTT deals.
- Self-signed DRM for your own content - you encrypt, you keep the keys.
- License server integration - your panel authenticates as an authorized device and the license server returns a signed key response.
Keys are typically delivered as:
Or as a manifest entry matching the <ContentProtection> block in the MPD.
AOption A: shaka-packager (Google's Tool)
Google's open-source shaka-packager can decrypt CENC content if you supply the keys:
Then serve the output as HLS with FFmpeg:
BOption B: Named Pipes + FFmpeg (Zero-Disk)
For live streams you do not want to buffer to disk - latency and key-rotation reasons. Use named pipes (FIFOs) so the decryptor writes cleartext to a pipe that FFmpeg reads from:
Decryptor writes to the pipes:
FFmpeg reads from the pipes, muxes, writes HLS:
No decrypted bytes ever touch the disk. On process restart the pipes are flushed cleanly.
COption C: A Panel That Handles All of This
Doing the above by hand per channel is a full-time job. A panel with built-in DRM handling exposes a single dialog per channel with fields for:
- Source MPD URL
- KID:KEY pairs (one-off or rotating)
- License server URL (if automated key fetch)
- HTTP headers to send on source pulls
- Key refresh interval
The panel then creates the pipes, spawns the decryptor, wires FFmpeg, and publishes HLS to your existing admin workflow. On a key rotation or source disconnect, the panel restarts the pipeline without a user-visible pause.
Xtream-Masters ships this natively - see our DRM panel tips for the UI walkthrough. XUI.ONE and Xtream UI have no DRM pipeline at all.
Key Rotation and Refresh
Many modern DRM sources rotate keys every few hours. Without automatic refresh your decryptor starts producing garbage output the moment the source switches to a new KID.
Two strategies:
- Manifest refresh - re-fetch the MPD periodically, re-read the
<ContentProtection>block, and trigger a pipeline restart if the KID changed. - License-server refresh - where the panel periodically re-authenticates against the license server and fetches current keys.
Xtream-Masters exposes a manifest_refresh_min field in stream profiles exactly for this.
Common Failure Modes
“Non-decryptable box” error from shaka-packager
The KID you supplied does not match the one in the manifest. Re-check by parsing the MPD:
FFmpeg blocks forever on named pipe
Order of opening matters. Start the decryptor before FFmpeg tries to read the pipe. Or use mkfifo with a small buffer and non-blocking reads.
Audio drift after key rotation
The decryptor restarted but the audio pipe was not flushed. Force a full pipeline restart (both video and audio decryptor + FFmpeg) on rotation, not partial.
High CPU during decrypt
AES-NI should make CENC decrypt nearly free. If you see 100 percent CPU, check grep aes /proc/cpuinfo. On older VPS without AES-NI, decrypt can dominate CPU.
