Keys:
Code:bc945de9a957ab14e80244c00b27e7fd:b8eea9fb4dce61c8cded0f136a37122d 23fe583a6bc4acc3c4372b57689c0d20:fb372447ce6d32edc583c4a08f0e14ae
+ Reply to Thread
Results 151 to 166 of 166
-
Bypass HMACs, One-time-tokens and Lic.Wrapping: https://github.com/DevLARLEY/WidevineProxy2
-
CBR 1080p:
VBR (from premium with no url hacks) 1080p:Code:https://vodnowusoawsdash-cf.tvnow.de/pgrn/streaming/watch/1025166/1-10000-1-1-1-X.ism/rtlplus.mpd 56922b077e89d58ac7c4b8a3f0243ec3:59de6c0fdc4ecfccc0021ee8e2a5f89c https://vodnowusoawsdash-cf.tvnow.de/pgrn/streaming/watch/1025167/1-10000-1-1-1-X.ism/rtlplus.mpd 637a19992e0c27df76d356e103fafa9b:862bd4e117a72b9ada96816d83b0e222
For whatever reason RTL gives you the /sd/ url for premium but doesnt matter its all the same mpd. Same for android/tv/tizen and so on.Code:https://vodnowusoawsdash-cf.tvnow.de/pgrn/cves/sd/rtlplus/1025166/3-1-1-1-2-1-12.ism/v1.mpd 906f41d341b6387d502064e5625e6c11:5527f4048344d84a6989680a3c1cf9b1 https://vodnowusoawsdash-cf.tvnow.de/pgrn/cves/sd/rtlplus/1025167/6-1-1-1-2-1-12.ism/v1.mpd 7a2cda05d355eb5e7ba64f7337ec5b6c:756f53b53134fe7818a02a8d4215e3f4
VBR is 99 % trash. So have fun with the CBR Playlist
Last edited by Lostion; 12th Sep 2025 at 18:23.
-
Hi all,
I also need a little help getting the keys.
I try to go step by step through what I've done so far:
1) The file I want to download: https://plus.rtl.de/video-tv/serien/alles-was-zaehlt-146430/2025-8-1039293/episode-476...bedroht-971749
2) --> mpd: https://vodnowusoawsdash-cf.tvnow.de/pgrn/streaming/watch/971749/3-10000-1-1-1-X.ism/rtlplus.mpd
3) --> licence url: https://rtlplus-widevine.streamingtech.de/index/rtlplus
Then I edited the headers.py with the x-auth-token show in the headers of the POST https://rtlplus-widevine.streamingtech.de/index/rtlplus:
[Attachment 88706 - Click to enlarge]
(scolling down a little to the x-auth-token:
[Attachment 88707 - Click to enlarge]
4) My headers.py:
Is this correct?Code:import requests headers = { 'x-auth-token': 'eyJhbGciO...', } params = ( ('platform', 'BROWSER'), ('type', 'MOVIE'), ) # params inserted below will be passed to data-raw token = 'PFYtFSqWMYIROJYywBp0rbKvpD3z6N6E6UezNrZmCeKHkcJ5BiH4J8qwO0kfWOmrSsyFJMg9OqKKEwvuQiXL4qdDTa6ZYplNV9IQt6eEuveglDxjVlYd0vAecS5TZKn5mIs01YxcYNlTC7tu3BIk63JhMykMWEMmj1oEqaLa7N3ZrfU2VTlEPaWXBQV6PxnFeD022Yi298GOX/lDik7sXt5u4duT0aKIYbz0HPmjoh8b9Uy8bvzJUa0/SlgRcsW8RNTNjRJHM6N7BESCBGFEZcWoSXeDLEblEfRoBKro2iDGB1neLfRdY1fj7tJX1Rn9lj+OJwRTrBV4XoTQFuSsFwvYCeQfkAoRHXnze9njI5pY7sYgIGxuM4Zh3Wqaps6kxdO53QMm0jJ/L41X6r5CikSGKQ3Rcps8eQccZb9svEuyXMof2nm+eYL+AVPPrfmAf/BrmUHfiuF9CmNsF9pI7PjJfLeASmh3KDI/5gUuC4uJB7rjTzHVWNRz8MSvYjJ37/5V9+FTihpu04+0jFZ1AlGRks2dzk2IGvm5WcwUhsW2l/oQXlh7AgsksIl2DT0wH11WeG+h1/ijymMcG9AZzsxtkC53eLJ8bl55/Aag0TJfX4N6KvV7UhglXxkLifb06bLK/wlcGCfb01b4cnngcjPJEMxh2+Q7sJSnbyrtsfodzNah8JXITmx5kTkFFZkdtga1ha9jAb+Z40VMQfbrCLgh0GEe2G3VczcIt8QHAWAeS91TkzLbMRAugbgLvdbI8yQXtM15uo+TXrV4PNFprug33AnvnQu7IpNxlmgPMZhEn4Qqc/V++OFIpz/JYEMnLFvjYcXE2+sPc4uKnoE0xk33+IgZKtWtDhxRg2SJKyKOYxXucXybUuqPP/d+Nq1VNhD84Of+EfVvBjs1u75pNz/kmu5ms9ppRMkafq0/2311hbYi6VXmp6AeJweGJWkGKEFxw7xADuC8iM7xWnXW5aiNvhbsXBOwuTK8b2ioxjrg6OFhiMck+z9M5FHg+ktY7YB8iY+0V6B/Op2cQGtLaZ2E9lsomlQpxL+LiPI7UWEqmALEGH/Pk5tdLnlFRjEk2PPc8YURw+/nkP9tqJ/AXQwaXc9iwC5yxlYPCsp/Tc4=' provider = 'kakaotv' releasePid = "_qVpiY31v_oU" #response = requests.post('https://rtlplus-widevine.streamingtech.de/index/rtlplus', headers=headers, cookies=cookies, data=data) response = requests.post('https://rtlplus-widevine.streamingtech.de/index/rtlplus', headers=headers) # print(f'{chr(10)}widevine_license: {response.content}') #NB. Original query string below. It seems impossible to parse and #reproduce query strings 100% accurately so the one below is given #in case the reproduced version is not "correct". # response = requests.options('https://api.ott.kinopoisk.ru/v12/license-affected-content-metadata?contentIds=4b63db58ab27e92b90a457e533b00007&serviceId=25', headers=headers) # dash-cenc/hdr10_uhd_hevc_ec3.mpd # https://strm.yandex.ru/vh-ottenc-converted/vod-content/4315082489d87677b21f7c83593fcb73/8614535x1631802676x41611665-4e76-41ac-93a7-5070b77b5f3c/dash-cenc/sdr_uhd_hevc_ec3.mpd # 'GET /certificate HTTP/1.1'
In the requests.post I removed the cookies=cookies and data=data as later on the l3.py crashed.
With the cookies I get this error:
5) Execute the l3.py using "python.exe .\l3.py"Code:Traceback (most recent call last): File "C:\Users\Marcel\Downloads\tmp\widevine_keys\l3.py", line 8, in <module> import headers File "C:\Users\Marcel\Downloads\tmp\widevine_keys\headers.py", line 17, in <module> response = requests.post('https://rtlplus-widevine.streamingtech.de/index/rtlplus', headers=headers, cookies=cookies, data=data) NameError: name 'cookies' is not defined
I get this error:
Any idea what could be the problem?Code:Input MPD URL: https://vodnowusoawsdash-cf.tvnow.de/pgrn/streaming/watch/971749/3-10000-1-1-1-X.ism/rtlplus.mpd License URL: https://rtlplus-widevine.streamingtech.de/index/rtlplus PSSH obtained. AAAAUHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADAIARIgNDQyNDZlNjUzMTNhNjk3N2I1MjA3ZDY3MzVhNjkyZTQiBjk3MTc0OSoCU0Q= license response status: <Response [404]> server reports: {"error":"invalid.meta.data.INVALID_LICENSE_CHALLENGE.100)","errorCode":12400,"origin":"google"} server did not issue license, make sure you have correctly pasted all the required headers in the headers.py. Also check json/raw params of POST request.Last edited by Marcel; 13th Sep 2025 at 14:09.
-
@Obo
@larley
Thank you very much for the links and for the keys, respectively. However, due to random, I have tried the links from @lostion first, and they worked at once, so I didn't try yours in addition.
@Lostion
As always, thank you very much! Your links and keys worked like a charm - no fiddling around. Next weekend I'll probably ask for the next two Schlefaz episodes
-
Hi Marcel,
I really can't tell you what the problem is. Nevertheless, I perhaps have a solution for you:
Personally, my motivation to play around with Python code is quite limited; I just want the stuff to be on my disk. Therefore, a while ago, I have searched for a more usable solution and have found something that is called `hellyes`. Watch out out for version 5 (hellyes5). It is a ZIP archive that (among a lot of other stuff) contains a python script with "...gui..." in its name.
This is what you may be after
. If you execute it, a minimal GUI appears where you enter the MPD URL in the first field and the license request URI in the second field, and it does the rest automatically. I always had success with it as long as I had the correct MPD and license URI. I didn't test it with anything else than RTL plus so far, though, because I am only interested in the Schlefaz show.
Two things to note:
1. Before you start the script mentioned above, you must activate the correct virtual environment that's in the helleys5 directory. Otherwise, the script may throw errors and may not start at all (depending on your Python installation).
2. I believe that your license URI is wrong. I haven't used all that stuff for a longer time now, but I eventually remember that the license URI usually contains a lot of parameters and thus is several hundreds of characters long. In contrast, your URI is just a URL without any parameters. I may be wrong, so it would probably a good idea to learn how to extract the license URI the correct way.
Have fun, and a nice Sunday!Last edited by 4L7zHhiyQO3Thui6; 14th Sep 2025 at 07:37.
-
Hi 4L7zHhiyQO3Thui6,
thanks for the hint, it's working now. You were right, the problem was the url of the licence.
I will play around with it a little more and then come back and give an update.
Thanks again and have a nice rest of the sunday
-
Is the right url for widevine.Code:
https://rtlplus-widevine.streamingtech.de/index/rtlplus
No idea about the python code above. -
you only need to pass x-auth-token in pywidevine script
Code:def decrypt_content(pssh, license_url, token): try: pssh_obj = PSSH(pssh) device = Device.load(DEVICE_PATH) cdm = Cdm.from_device(device) session_id = cdm.open() challenge = cdm.get_license_challenge(session_id, pssh_obj) headers = { 'x-auth-token': token, } session = requests.Session() licence_response = session.post( license_url, data=challenge, headers=headers ) licence_response.raise_for_status() licence = licence_response.content cdm.parse_license(session_id, licence) returned_keys = [] print("\nKeys :") for key in cdm.get_keys(session_id): if key.type != "SIGNING": key_string = f"{key.kid.hex}:{key.key.hex()}" returned_keys.append(key_string) print(f" --key {key_string}") cdm.close(session_id) -
Hello, when I follow the instructions below, I get an mkv file with a size of 1.648 GB if I want the highest resolution (7154 Kbps). I found the same episode available for download in a forum with a size of 2.359 GB. What do I need to change to get the larger file?
N_m3u8DL-RE.exe "https://vodnowusoawsdash-cf.tvnow.de/pgrn/cves/sd/rtlplus/1000194422/2-1-1d-1-1-1-12.ism/v1.mpd" --key 6d06654db43724723bd7063e2cb626c9:e828144e116d09f82 214d814b355e273 --save-dir "media\plus_rtl_de" --save-name "Die Geissens Spezial: Der Überfall - Teil 1" -M format=mkv --check-segments-count false
15:00:17.886 INFO : N_m3u8DL-RE (Beta version) 20251029
15:00:17.887 INFO : Loading URL: https://vodnowusoawsdash-cf.tvnow.de/pgrn/cves/sd/rtlplus/1000194422/2-1-1d-1-1-1-12.ism/v1.mpd
15:00:18.171 INFO : Content Matched: Dynamic Adaptive Streaming over HTTP
15:00:18.172 INFO : Parsing streams...
15:00:18.222 WARN : Writing meta json
15:00:18.240 INFO : Extracted, there are 8 streams, with 6 basic streams, 1 audio streams, 1 subtitle streams
15:00:18.241 INFO : Vid *CENC 1920x1080 | 7154 Kbps | video=7154000 | avc1.4D4028 | 1487 Segments | Main | ~47m35s
15:00:18.242 INFO : Vid *CENC 1920x1080 | 4467 Kbps | video=4467000 | avc1.4D4028 | 1487 Segments | Main | ~47m35s
15:00:18.244 INFO : Vid *CENC 1280x720 | 2898 Kbps | video=2898000 | avc1.4D401F | 1487 Segments | Main | ~47m35s
15:00:18.246 INFO : Vid *CENC 960x540 | 1667 Kbps | video=1667000 | avc1.4D401F | 1487 Segments | Main | ~47m35s
15:00:18.251 INFO : Vid *CENC 768x432 | 866 Kbps | video=866000 | avc1.4D401E | 1487 Segments | Main | ~47m35s
15:00:18.251 INFO : Vid *CENC 640x360 | 442 Kbps | video=442000 | avc1.4D401E | 1487 Segments | Main | ~47m35s
15:00:18.252 INFO : Aud *CENC audio_1=130000 | 130 Kbps | mp4a.40.2 | de | 2CH | 1487 Segments | Main | ~47m35s
15:00:18.252 INFO : Sub textstream_1=2000 | de | stpp.ttml.im1t | 1487 Segments | Subtitle | ~47m35s
Please select what you want to download:
> [ ] Basic
[X] Vid *CENC 1920x1080 | 7154 Kbps | video=7154000 | avc1.4D4028 | 1487 Segments | Main | ~47m35s
[ ] Vid *CENC 1920x1080 | 4467 Kbps | video=4467000 | avc1.4D4028 | 1487 Segments | Main | ~47m35s
[ ] Vid *CENC 1280x720 | 2898 Kbps | video=2898000 | avc1.4D401F | 1487 Segments | Main | ~47m35s
[ ] Vid *CENC 960x540 | 1667 Kbps | video=1667000 | avc1.4D401F | 1487 Segments | Main | ~47m35s
[ ] Vid *CENC 768x432 | 866 Kbps | video=866000 | avc1.4D401E | 1487 Segments | Main | ~47m35s
[ ] Vid *CENC 640x360 | 442 Kbps | video=442000 | avc1.4D401E | 1487 Segments | Main | ~47m35s
[ ] Audio
[X] Aud *CENC audio_1=130000 | 130 Kbps | mp4a.40.2 | de | 2CH | 1487 Segments | Main | ~47m35s
[ ] Subtitle -
-
No 5.1 on RTL+ also 7800 is the CBR version which you don't get mostly on browsers.
-
@ListyDoM: The KID Key is: 6d06654db43724723bd7063e2cb626c9 and this is exactly correct in my first posting.
19:34:58.585 WARN : Type: cenc
19:34:58.587 WARN : PSSH(WV): CAESIDZkMDY2NTRkYjQzNzI0NzIzYmQ3MDYzZTJjYjYyNmM5Ig oxMDAwMTkzODk2KgJTRA==
19:34:58.589 WARN : KID: 6d06654db43724723bd7063e2cb626c9
19:34:58.590 WARN : Reading media info...
19:34:58.655 INFO : [0x1]: Video, h264 (avc1), 1920x1080
I have included the properties of both video files in the appendix.
Smaller file: codec: Main@L4 codec id: V_MPEG4/ISO/AVC, Overall bit rate : 4 992 kb/s
Bigger file: codec High@L4 codec id: V_MPEG4/ISO/AVC, Overall bit rate : 7 364 kb/s
From the bitrates offered, it looks to me as if the version “Vid *CENC 1920x1080 | 7154 Kbps | video=7154000 | avc1.4D4028” is selected, but the "Vid * CENC 1920x1080 | 4467 Kbps | video=4467000 | avc1.4D4028" is ultimately stored on the disk.Last edited by Dagobert1; 2nd Jan 2026 at 14:04.
-
To obtain the video keys, you can proceed as follows (in simplified form):
Sorry if it's in French, you'll have to translate it into English.Code:import os import requests import pyfiglet from base64 import b64encode from pywidevine.L3.decrypt.wvdecryptcustom import WvDecrypt from pywidevine.L3.cdm import deviceconfig # Couleurs terminal RED = "\x1b[38;5;160m" GREEN = "\x1b[38;5;46m" CYAN = "\x1b[38;5;14m" YELLOW = "\x1b[38;5;226m" END = "\x1b[0m" def print_title(): title = pyfiglet.figlet_format("Widevine Decryptor Keys", font="slant", width=150) print(f"{CYAN}{title}{END}") def validate_pssh(pssh: str) -> bool: if len(pssh) >= 150: print(f"{RED}❌ PSSH invalide{END}") return False return True def get_widevine_keys(pssh: str, headers: str, LICENCE_URL: str): wvdecrypt = WvDecrypt(init_data_b64=pssh, device=deviceconfig.device_android_generic) try: response = requests.post(LICENCE_URL, data=wvdecrypt.get_challenge(), headers=headers, timeout=10) response.raise_for_status() except requests.RequestException as e: print(f"{RED}Erreur licence Widevine : {e}{END}") return [] wvdecrypt.update_license(b64encode(response.content)) success, keys = wvdecrypt.start_process() return keys if success else [] def main(): print_title() pssh = input(f"{RED}PSSH:{END} {YELLOW}").strip() if not validate_pssh(pssh): return token = input(f"{RED}x-Auth-Token:{END} {YELLOW}").strip() if not token: print(f"{RED}❌ Le token ne peut pas être vide{END}") return headers = {"x-Auth-Token": token} licence_url = "https://rtlplus-widevine.streamingtech.de/index/rtlplus" keys = get_widevine_keys(pssh, headers, licence_url) if not keys: print(f"{RED}❌ Aucune clé trouvée{END}") return for key in keys: print(f"{GREEN}--key{END} {RED}{key}{END}") input("\nAppuyez sur Entrée pour quitter...") if __name__ == "__main__": main() -
Very strange, but this pair doesn't work for me (see screenshot)
MediaInfo the first file that is downloaded me
Code:General Unique ID : 94111294009829145784661975841026478590 (0x46CD2D0958888E930780FEAAE62611FE) Complete name : Die Geissens Spezial_ Der Überfall - Teil 1.mkv Format : Matroska Format version : Version 4 File size : 1.57 GiB Duration : 47 min 33 s Overall bit rate : 4 732 kb/s Frame rate : 25.000 FPS Encoded date : 2026-01-02 22:38:23 UTC Writing application : mkvmerge 96.0 ('It's My Life') 64-bit Writing library : libebml v1.4.5 + libmatroska v1.7.1 Video ID : 1 Format : AVC Format/Info : Advanced Video Codec Format profile : Main@L4 Format settings : CABAC / 4 Ref Frames Format settings, CABAC : Yes Format settings, Reference frames : 4 frames Codec ID : V_MPEG4/ISO/AVC Duration : 47 min 33 s Bit rate : 4 601 kb/s Width : 1 920 pixels Height : 1 080 pixels Display aspect ratio : 16:9 Frame rate mode : Constant Frame rate : 25.000 FPS Color space : YUV Chroma subsampling : 4:2:0 (Type 2) Bit depth : 8 bits Scan type : Progressive Bits/(Pixel*Frame) : 0.089 Stream size : 1.53 GiB (97%) Writing library : x264 core 164 Encoding settings : cabac=1 / ref=4 / deblock=1:0:0 / analyse=0x1:0x111 / me=hex / subme=7 / psy=1 / psy_rd=1.00:0.00 / mixed_ref=1 / me_range=16 / chroma_me=1 / trellis=1 / 8x8dct=0 / cqm=0 / deadzone=21,11 / fast_pskip=1 / chroma_qp_offset=-2 / threads=34 / lookahead_threads=8 / sliced_threads=0 / nr=0 / decimate=1 / interlaced=0 / bluray_compat=0 / constrained_intra=0 / bframes=4 / b_pyramid=2 / b_adapt=2 / b_bias=0 / direct=1 / weightb=1 / open_gop=0 / weightp=2 / keyint=48 / keyint_min=24 / scenecut=0 / intra_refresh=0 / rc_lookahead=48 / rc=crf / mbtree=1 / crf=21.0 / qcomp=0.60 / qpmin=0 / qpmax=69 / qpstep=4 / vbv_maxrate=8000 / vbv_bufsize=8000 / crf_max=0.0 / nal_hrd=none / filler=0 / ip_ratio=1.40 / aq=1:1.00 Default : Yes Forced : No Color range : Limited Color primaries : BT.709 Transfer characteristics : BT.709 Matrix coefficients : BT.709 Audio ID : 2 Format : AAC LC Format/Info : Advanced Audio Codec Low Complexity Codec ID : 2 / A_AAC-2 Duration : 47 min 33 s Bit rate : 128 kb/s Channel(s) : 2 channels Channel layout : L R Sampling rate : 48.0 kHz Frame rate : 46.875 FPS (1024 SPF) Compression mode : Lossy Delay relative to video : -43 ms Stream size : 43.5 MiB (3%) Language : German Default : Yes Forced : No Text ID : 3 Format : UTF-8 Codec ID : S_TEXT/UTF8 Codec ID/Info : UTF-8 Plain Text Duration : 47 min 26 s Bit rate : 113 b/s Frame rate : 0.353 FPS Count of elements : 1004 Stream size : 39.3 KiB (0%) Language : German Default : No Forced : NoLast edited by ListyDoM; 2nd Jan 2026 at 19:27.
Similar Threads
-
Downloading videos from RTL
By Data2006 in forum Video Streaming DownloadingReplies: 17Last Post: 30th Jul 2024, 01:32 -
DOWNLOAD protected DRM video separated video and audio from (learnyst)
By yassin in forum Video Streaming DownloadingReplies: 4Last Post: 8th Jan 2024, 05:36 -
First try with RTL+/TVNow
By resonator79 in forum Video Streaming DownloadingReplies: 3Last Post: 23rd Feb 2023, 07:41 -
How can I download videos from play.rtl.hr?
By Nintendo Custom in forum Video Streaming DownloadingReplies: 23Last Post: 24th May 2022, 13:51 -
Download HLS video using FFMPEG with separate video and audio URLs?
By oschrndz in forum Video Streaming DownloadingReplies: 2Last Post: 15th Dec 2020, 14:53


Quote
