Skip to content

Instantly share code, notes, and snippets.

@frozenpandaman
Last active August 17, 2026 18:30
Show Gist options
  • Select an option

  • Save frozenpandaman/a91f4dc7b999499761f798fdd6da6129 to your computer and use it in GitHub Desktop.

Select an option

Save frozenpandaman/a91f4dc7b999499761f798fdd6da6129 to your computer and use it in GitHub Desktop.
download videos protected with widevine DRM

Downloading Widevine content

Specifically from Rakuten TV (live.tv.rakuten.co.jp)

FMI: https://cdm-project.com/How-To/ & https://old.reddit.com/r/Piracy/comments/y30ffr/

Setup

  1. Install Tampermonkey: https://www.tampermonkey.net/
  2. Install yt-dlp: https://github.com/yt-dlp/yt-dlp#installation
  3. Install ffmpeg: https://ffmpeg.org/download.html
  4. Download Bento4: https://www.bento4.com/downloads/
  5. Have a proxy/VPN if you're not in Japan since stuff is geolocked

Getting your decryption key

Get PSSH

  1. Install this userscript: https://greasyfork.org/en/scripts/373903-eme-logger
  2. Search browser JS Console for MediaKeySession::generateRequest, then press play on the video and look under "Init Data"
  3. Get something like AAAAMnBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAXXXXXXXXFtoyTEzFOZDD4T9lmTiI=

Get License URL

  1. After doing the above, go to your browser developer tools' Network tab and search for Widevine
  2. Right click > Copy > Copy link address
  3. Get something like https://azcp001.keydelivery.japaneast.media.azure.net/Widevine/?kid=e0c5b68c-9313-314e-6430-f8XXXXXXXX22

Get headers

  1. Left click on the Widevine entry from the above steps, under the "Headers tab" scroll down to "Request Headers"
  2. Copy the following lines & do some manual formatting, get something like:
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,ja-JP;q=0.8,ja;q=0.7
Authorization: blahblah
Cache-Control: no-cache
Content-Length: "blahblah"
Origin: https://live.tv.rakuten.co.jp
Pragma: no-cache
Referer: https://live.tv.rakuten.co.jp/
User-Agent: blahblah

Getting the key

  1. Open https://cdrm-project.com/
  2. Input the results from the previous steps and press "Send"
  3. Hopefully see the "SUCCESS" message along with a key that looks like e0c5b68c93133XXXXXXXX84fd9664e22:499047f36b770957XXXXXXXX9dfc4033

Downloading the encrypted files

  1. In the developer console Network tab, search for mpd
  2. Find something that starts with Manifest, right click and copy the URL, e.g. https://azclwds01.akamaized.net/9dc3547a-ede5-4aed-841f-5cXXXXXXXX0f/tXyKyP_tab_hd.ism/Manifest(format=mpd-time-csf,encryption=cenc,filter=pc_hd_001)
  3. Run the Terminal command: yt-dlp --allow-unplayable [url]
  4. Get two files, an .mp4 and an .m4a

Decrypting & merging the files

  1. In Bento4's bin/ folder, find the mp4decrypt command line utility
  2. Navigate to this folder in your Terminal and run mp4decrypt --key [yourkey] /path/to/corrupted.file /path/to/fixed.file on both files
  3. Run ffmpeg -i fixedvideo.mp4 -i fixedaudio.m4a -c:v copy -c:a copy output.mp4
  4. The end
@dmak

dmak commented Aug 4, 2026

Copy link
Copy Markdown

Maybe one can advise/describe the complete flow with N_m3u8DL-RE utulity? I see that it resolves PSSH/KID, but generated MP4 is still encrypted when I open it 😭

$ N_m3u8DL-RE 'https://npo-nl-ams-p30-am3.cdn.streamgate.nl/eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE3ODU4ODgzNjQsInVyaSI6Ilwvdm9kXC9ucG9cL3VzcFwvVEVTVFwvbnBvcGx1c1wvZGFzaF9jZW5jXC9BVF8zMDAwMjk2NDhcL0FUXzMwMDAyOTY0OF92MTc4NTYxNzYxOC5pc20iLCJ2aWV3ZXIiOiJ2aWV3ZXIiLCJyaWQiOiI5OGQ5NTFkIn0.VG2t-x9E1pN_1KL_7GnOcPrgniMf3TrHxeV-WuBBVc4/vod/npo/usp/TEST/npoplus/dash_cenc/AT_300029648/AT_300029648_v1785617618.ism/stream.mpd'
11:12:44.548 INFO : Selected streams:
11:12:44.548 INFO : Vid *CENC 1920x1080 | 7051 Kbps | video=7051000 | avc1.640029 | 260 Segments | Main | ~34m33s
11:12:44.549 INFO : Aud *CENC audio=128001 | 128 Kbps | mp4a.40.2 | 2CH | 261 Segments | Main | ~34m33s
11:12:44.551 INFO : Save Name: stream_2026-08-04_11-12-26
11:12:44.552 INFO : Start downloading...Vid 1920x1080 | 7051 Kbps | video=7051000 | avc1.640029 | Main
11:12:44.552 WARN : When CENC encryption is detected, binary merging is automatically enabled
11:12:44.558 WARN : Type: cenc
11:12:44.558 WARN : PSSH(WV): CAESEPlKIkd2umKvt8UEiWioId0aCHVzcC1jZW5jIhgrVW9pUjNhNllxKzN4UVNKYUtnaDNRPT0qADIA
11:12:44.558 WARN : KID: f94a224776ba62afb7c5048968a821dd
11:12:44.558 WARN : KID (from MPD): f94a224776ba62afb7c5048968a821dd
11:12:44.981 INFO : [0x1]: Video, h264 (avc1), 1920x1080
11:15:22.568 INFO : Binary merging...
11:15:38.442 INFO : Start downloading...Aud audio=128001 | 128 Kbps | mp4a.40.2 | 2CH | Main
11:15:38.449 WARN : Type: cenc
11:15:38.452 WARN : PSSH(WV): CAESEPlKIkd2umKvt8UEiWioId0aCHVzcC1jZW5jIhgrVW9pUjNhNllxKzN4UVNKYUtnaDNRPT0qADIA
11:15:38.455 WARN : KID: f94a224776ba62afb7c5048968a821dd
11:15:38.457 WARN : KID (from MPD): f94a224776ba62afb7c5048968a821dd
11:15:38.590 INFO : [0x1]: Audio, aac (mp4a), 128 kb/s
11:15:42.241 INFO : Binary merging...
11:15:42.511 INFO : Done
image

I have tried adding --decryption-engine=MP4DECRYPT or --decryption-engine=SHAKA_PACKAGER with same negative effect. Thanks in advance for any hint! πŸ™ Additional binaries are there but is there any evidence in console log they are executed?

$ ll `which mp4decrypt`
-rwxr-xr-x 1 root root 1018392  Nov 25  2023 /usr/local/bin/mp4decrypt
$ ll `which shaka-packager`
-rwxr-xr-x 1 root root 10289600 Aug  4 11:07 /usr/local/bin/shaka-packager

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment