Code:0ac9b1e16a3430ff892e1cac24748219:77973da183d8964e91e782e2474b88dd
+ Reply to Thread
Results 31 to 60 of 60
-
thanks, but I asked how did you get it, what path should I take to find it
video link: https://www.raiplay.it/video/2022/12/Mondiali-di-calcio-Qatar-2022---Finale-Argentina-...56f66aac1.html
thanksLast edited by polcorelli; 6th Jun 2023 at 03:52.
-
The key for that video is cached on cdrm-project.com, so you should be able to use that for other videos as well. Put in pssh, license url, and the authorization token as your only header. The token expires in a minute or so, so you need to be fast.
-
Hello, thanks for the reply but I still struggle to understand, please can you be more specific?
I'm on https://cdrm-project.com, in the pssh field I write.. the url? And what do I write in the license?
can you paste here exactly what you wrote? Thank you -
This is what I put in:
[Attachment 71521 - Click to enlarge]
The key is cached, so presumable it should work for other videos as well.
If you don't know what any of those things are, you have some reading to do. There are thousands of posts in this forum talking about these things. -
Ok thank you so much. I can imagine where you found license key and headers (chrome network panel), may you tell me where to find pssh value or link me some useful urls of this forum? really thanks
-
@polcorelli
pssh is located in the mpd
[Attachment 72891 - Click to enlarge]
updated raiplay: try getting 1080p
Code:from pathlib import Path import subprocess import requests import json import re import os from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) files_to_delete = ["key.txt"] for file_name in files_to_delete: if os.path.exists(file_name): os.remove(file_name) print(f"{file_name} file successfully deleted.") m3u8DL_RE = 'N_m3u8DL-RE.exe' def replace_invalid_chars(title: str) -> str: invalid_chars = {'<': '\u02c2', '>': '\u02c3', ':': '\u02d0', '"': '\u02ba', '/': '\u2044', '\\': '\u29f9', '|': '\u01c0', '?': '\u0294', '*': '\u2217'} return ''.join(invalid_chars.get(c, c) for c in title) print(f'\ntest link: https://www.raiplay.it/video/2023/02/Mare-fuori-S3E10-Le-regole-dell-amicizia-989f9b77-c4f5-4088-952d-c8c02ce7925f.html\ntest link: https://www.raiplay.it/video/2017/10/the-tourist-5e39a1fe-71ad-44a6-bb13-aa986670bce3.html\n') link = input('link: ') link_id = re.findall(r'(https://.*).html', link)[0].strip() headers00 = { 'Referer': 'https://www.raiplay.it/', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', 'X-Caller-Version': '', 'x-ua-token': 'null', } response00 = requests.get(''+link_id+'.json',headers=headers00, verify=False).json() name_title = response00['program_info']['name'] toptitle = response00['toptitle'] title = f'{name_title} - {toptitle}' title = replace_invalid_chars(title) print(f'\ntitle:\n{title}\n') content_url = response00['video']['content_url'] relink_cont = re.findall(r'cont=(.*)', content_url)[0].strip() import requests headers02 = { 'authority': 'mediapolisvod.rai.it', 'origin': 'https://www.raiplay.it', 'referer': 'https://www.raiplay.it/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36', } params02 = { 'cont': relink_cont, 'output': '64', } response02 = requests.get('https://mediapolisvod.rai.it/relinker/relinkerServlet.htm', params=params02, headers=headers02, verify=False).text try: mpd = re.findall(r'CDATA\[(https.*?mpd.*?)\]', response02)[0].strip() print(f'original mpd:\n{mpd}\n') mpd = re.sub(r',filter=.*\)', r')', mpd) print(f'modified mpd:\n{mpd}\n') except IndexError: m3u8 = re.findall(r'\[(https://.*m3u8.*?)\]', response02)[0].strip() print(f'original m3u8:\n{m3u8}\n') m3u8 = re.sub(r'qual_.*/', r'qual_,1200,1800,2400,3600,5000/', m3u8) print(f'modified m3u8:\n{m3u8}\n') print() subprocess.run([m3u8DL_RE, '-M', 'format=mkv:muxer=ffmpeg', '--concurrent-download', '--auto-select', '--del-after-done', '--log-level', 'INFO', '--save-name', 'video', m3u8]) try: Path('video.mkv').rename(''+title+'.mkv') print(f'{title}.mkv \nall done!\n') except FileNotFoundError: print("[ERROR] no mkv file") for file_name in files_to_delete: if os.path.exists(file_name): os.remove(file_name) print(f"{file_name} file successfully deleted.") ex_it = input('\nPress Enter to Exit...') exit() import requests headers03 = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36', } response03 = requests.get(mpd, headers=headers03, verify=False).text pssh = re.findall(r'<cenc:pssh>(.{20,170})</cenc:pssh>', response03)[0].strip() print(f'\n{pssh}') lic_url = re.findall(r'licenceUrl\":\"(.*?)\"', response02)[0].strip() print(f'\n{lic_url}\n') try: nv_authorizations = re.findall(r'Authorization=(.*)', lic_url)[0].strip() print(f'\n{nv_authorizations}\n') except IndexError: nv_authorizations = re.findall(r'token=(.*)', lic_url)[0].strip() print(f'\n{nv_authorizations}\n') import requests headers_clone = { 'Connection': 'keep-alive', 'Content-Type': 'application/json', 'Origin': 'https://wvclone.fly.dev', 'Referer': 'https://wvclone.fly.dev/', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36', } json_data_clone = { 'password': 'password', 'license': lic_url, 'headers': f'Connection: keep-alive\nnv-authorizations: "{nv_authorizations}"', 'pssh': pssh, 'buildInfo': '', 'cache': True, } clone_resp = requests.post('https://wvclone.fly.dev/wv', headers=headers_clone, json=json_data_clone, verify=False).text from bs4 import BeautifulSoup soup = BeautifulSoup(clone_resp, 'html.parser') li_s = soup.find_all('li') keys = [] for li in li_s: keys.append(li.text.strip()) key_s = ' '.join(['--key ' + key for key in keys]) print(f'\nkey(s):\n{key_s}') print(key_s, file=open("key.txt", "w")) with open("key.txt", "r") as fs: ke_ys = fs.readlines() ke_ys = ke_ys[0].strip().split() print() subprocess.run([m3u8DL_RE, '-M', 'format=mkv:muxer=ffmpeg', '--concurrent-download', '--auto-select', '--del-after-done', '--log-level', 'INFO', '--save-name', 'video', mpd, *ke_ys]) try: Path('video.mkv').rename(''+title+'.mkv') print(f'{title}.mkv \nall done!\n') except FileNotFoundError: print("[ERROR] no mkv file") for file_name in files_to_delete: if os.path.exists(file_name): os.remove(file_name) print(f"{file_name} file successfully deleted.")
Last edited by sk8ordi3; 4th Aug 2023 at 01:33. Reason: updated..
-
@sk8ordi3 I tried to make this work. It seems like python code and the script is run from commandprompt.
However the italian links are not working (outdated/removed) and so does the script doesn't work. If i take another link from the italian website the paramaters are different and can't get the mpd, pssh and keys to load in the cmd.
If i inspect a new video it doesnt show at inspect, network (F12) on search any .mpd file, i don't know if this happens because the video is build up from .ts segmented parts.
https://www.raiplay.it/video/2023/07/Mondiali-di-Nuoto-2023---Oro-per-Thomas-Ceccon-ne...47709b365.html
Can you update the script please so it gives me some insight how it works.
----------------------------------------------------------------------------------------------------------
On other side i'm trying to make the script work for another site, a dutch (holland) series website.
https://www.kijk.nl/programmas/chateau-meiland/psGh9E9D80v
The webbrowser page doesn't end with ".html.
The script specifies in the beginning code with "link_id = re.findall(r'(https://.*).html', link)[0].strip()". If i simply remove the .html it does not work.
On inspect F12:
The webpage uses an .mpd file but the video and audio is separated and segmented in around 1000 files.
With yt-dlp I can see the amout of segmented files and can select a video/audio quality. I can download the files but after i open the file it doesn't load the video (.mp4) because it is in my opinion encrypted.
If i try to decrypt it with mp4decrypt.exe it doesnt work, I think I need the keys or pssh to decrypt the encryption.
Can someone help me to advise in the decryption from the downloaded video so i can play the downloaded video.
yt-dlp code with .mpd link to download the video with audio and make it in a .mp4:
C:\Users\Gino>
The downloaded video will be placed in your map: C:\Users\Gino>
If you paste the tekst in command prompt REMOVE the copied "spacebars/spaces" within the .mpd link else you get an error in the output!
The official website can change/update the requestURL, you need to update the .mpd link in the code beneath.
Place yt-dlp.exe just in case in the map you run the script fromat CMD, the download will be placed in the map you run yt-dlp.exe from.
With this code you get a list what qualities are available:
C:\Users\Gino>
Code:yt-dlp bestvideo -F --allow-unplayable-formats "https://vod-ww.prd1.talpatvcdn.nl/kijk/psGh9E9D80v/10f936693b554996b6284027dcc5aeb8/ba94badf69954f2b80c8016e0ccaad3d/f04bf2ba4ada4d28b0267d65f574f32e/index.mpd?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL3ZvZC13dy5wcmQxLnRhbHBhdHZjZG4ubmwva2lqay9wc0doOUU5RDgwdi8xMGY5MzY2OTNiNTU0OTk2YjYyODQwMjdkY2M1YWViOC9iYTk0YmFkZjY5OTU0ZjJiODBjODAxNmUwY2NhYWQzZC9mMDRiZjJiYTRhZGE0ZDI4YjAyNjdkNjVmNTc0ZjMyZS9pbmRleC5tcGQqIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjkwNDc0Njk0fX19XX0_&Key-Pair-Id=K1QF421Y6TW7LS&Signature=jZ6NHkxdQ3VQqGNS23qhYKE6-grnJ84WMdpZqfgtCi-tND9VYps4TXKpIAY7KI8k0lX8sTJNVIjL6u6d9mOPCXDXHSKha5spm3lTW1b34u8NIwZLeuGKWX6n30FtV6SVVeA8MbvhSCOvsG1GxkK1JcvBpU6pqd606PUzFPCkz5oGUhsN7fhLfpMtqLuB60f-4dPGW~zXic-f9milwf8bd6be~5XM~FBi61eEeQ6dOcvtMvOh2CtDv5Ye6fQeJ1ixYynzRcmfXIstTcpoJJcB6xYvQlKf~Bvk-adEdK5lj9Hij9J9-wLIn4yXQSBz5GoFw8mPuX60ap0CFEuWtVUJkQ__"
C:\Users\Gino>
Code:yt-dlp -f 6 --allow-unplayable-formats "https://vod-ww.prd1.talpatvcdn.nl/kijk/psGh9E9D80v/10f936693b554996b6284027dcc5aeb8/ba94badf69954f2b80c8016e0ccaad3d/f04bf2ba4ada4d28b0267d65f574f32e/index.mpd?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL3ZvZC13dy5wcmQxLnRhbHBhdHZjZG4ubmwva2lqay9wc0doOUU5RDgwdi8xMGY5MzY2OTNiNTU0OTk2YjYyODQwMjdkY2M1YWViOC9iYTk0YmFkZjY5OTU0ZjJiODBjODAxNmUwY2NhYWQzZC9mMDRiZjJiYTRhZGE0ZDI4YjAyNjdkNjVmNTc0ZjMyZS9pbmRleC5tcGQqIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjkwNDc0Njk0fX19XX0_&Key-Pair-Id=K1QF421Y6TW7LS&Signature=jZ6NHkxdQ3VQqGNS23qhYKE6-grnJ84WMdpZqfgtCi-tND9VYps4TXKpIAY7KI8k0lX8sTJNVIjL6u6d9mOPCXDXHSKha5spm3lTW1b34u8NIwZLeuGKWX6n30FtV6SVVeA8MbvhSCOvsG1GxkK1JcvBpU6pqd606PUzFPCkz5oGUhsN7fhLfpMtqLuB60f-4dPGW~zXic-f9milwf8bd6be~5XM~FBi61eEeQ6dOcvtMvOh2CtDv5Ye6fQeJ1ixYynzRcmfXIstTcpoJJcB6xYvQlKf~Bvk-adEdK5lj9Hij9J9-wLIn4yXQSBz5GoFw8mPuX60ap0CFEuWtVUJkQ__" --no-part -o episode1.m4a
C:\Users\Gino>
Code:yt-dlp -f 1 --allow-unplayable-formats "https://vod-ww.prd1.talpatvcdn.nl/kijk/psGh9E9D80v/10f936693b554996b6284027dcc5aeb8/ba94badf69954f2b80c8016e0ccaad3d/f04bf2ba4ada4d28b0267d65f574f32e/index.mpd?Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiKjovL3ZvZC13dy5wcmQxLnRhbHBhdHZjZG4ubmwva2lqay9wc0doOUU5RDgwdi8xMGY5MzY2OTNiNTU0OTk2YjYyODQwMjdkY2M1YWViOC9iYTk0YmFkZjY5OTU0ZjJiODBjODAxNmUwY2NhYWQzZC9mMDRiZjJiYTRhZGE0ZDI4YjAyNjdkNjVmNTc0ZjMyZS9pbmRleC5tcGQqIiwiQ29uZGl0aW9uIjp7IkRhdGVMZXNzVGhhbiI6eyJBV1M6RXBvY2hUaW1lIjoxNjkwNDc0Njk0fX19XX0_&Key-Pair-Id=K1QF421Y6TW7LS&Signature=jZ6NHkxdQ3VQqGNS23qhYKE6-grnJ84WMdpZqfgtCi-tND9VYps4TXKpIAY7KI8k0lX8sTJNVIjL6u6d9mOPCXDXHSKha5spm3lTW1b34u8NIwZLeuGKWX6n30FtV6SVVeA8MbvhSCOvsG1GxkK1JcvBpU6pqd606PUzFPCkz5oGUhsN7fhLfpMtqLuB60f-4dPGW~zXic-f9milwf8bd6be~5XM~FBi61eEeQ6dOcvtMvOh2CtDv5Ye6fQeJ1ixYynzRcmfXIstTcpoJJcB6xYvQlKf~Bvk-adEdK5lj9Hij9J9-wLIn4yXQSBz5GoFw8mPuX60ap0CFEuWtVUJkQ__" --no-part -o episode1.mp4
Last edited by gino92; 25th Aug 2023 at 07:37.
-
Run the script, it will ask for PSSH, Authorization (header in the request to the license server) and the ReleasePid
[Attachment 72716 - Click to enlarge]
https://files.videohelp.com/u/303646/Kijk.zip -
this video not have any encryption. search simply m3u8" link then download with N_m3u8DL-RE
Code:https://streamcdng19-b70cb04c54ab478189e9d8ee45637b13.msvdn.net/dom6/podcastcdn/raidue/Mondiali_Nuoto/20586089_,1800,2400,.mp4.csmil/playlist.m3u8?auth=daEdAd--(cut)--zxyHr&aifp=V001
-
@karoolus Thanks for your reply.
I am trying to get a working download for the kijk.nl video (https://www.kijk.nl/programmas/chateau-meiland/psGh9E9D80v).
How could I make the script work and can you show me what the output from the script should look like so I can recreate it.
With the search function "method:POST" on the kijk.nl video I found the exact printscreen you delivered.
ModularDrm?releasePid=DWCchwveO2ct&form=json&schem a=1.0
Upon using the script kijk.py from the kijk.zip file I cannot get the output I should, can you provide advise on how to get the output.
I get several errors for not installing libaries such as pywidevine and protobuf, described below.
Using "pip install pywidevine" and "pip install protobuf" only the pywidevine cdm import error stays.
C:\Users\Gino\AppData\Local\Programs\Python\Python 310\Scripts>python kijk.py
Traceback (most recent call last):
File "C:\Users\Gino\AppData\Local\Programs\Python\Pytho n310\Scripts\kijk.py", line 4, in <module>
from pywidevine.cdm import cdm, deviceconfig
ImportError: cannot import name 'cdm' from 'pywidevine.cdm' (C:\Users\Gino\AppData\Local\Programs\Python\Pytho n310\lib\site-packages\pywidevine\cdm.py)
Where should i place the folders "__pycache__" and the "pywidevine" ?
In the lib\site-packages folder or in the scripts folder?
C:\Users\Gino\AppData\Local\Programs\Python\Python 310\Scripts -
-
@Karoolus
I have tried serveral times to run the kijk.py script, from the desktop and within the python scripts folder.
As you stated it should just run and take the libraries from the folder but it doesn't work for me.
In my opinion the script cannot find the libraries you put into the folder.
Upon searching the cdm.py and deviceconfig.py files are indeed in the kijk folder.
For example I think the import should reference to a local librarie within the folder.
Where pywidevine stands for librarie, cdm for the folder within the librarie, cdm/deviceconfig for the actual .py file and Cdm/DeviceConfig for the class within the cdm/deviceconfig file.
- from pywidevine.cdm.cdm import Cdm
- from pywidevine.cdm.deviceconfig import DeviceConfig
import sys
#sys.path.append(r'/Users/Gino/Desktop/Kijk')
sys.path.append('C:\\Users\\Gino\\Desktop\\Kijk')
Keep in mind that there could be something wrong with the environment variables from system such as PATH and PYTHONPATH.
PATH:C:\Python310\ AND C:\Users\Gino\AppData\Local\Programs\Python\Python 310
PYTHONPATH: C:\Users\Gino\Desktop\KijkLast edited by gino92; 2nd Aug 2023 at 17:17.
-
That's weird, it works just fine on my PC.
[Attachment 72827 - Click to enlarge] -
-
@piaohua Thanks, that set me on the right track.
The protobuf version has indeed effect on the output, you need to have protobuf installed and not the newest version, version 3.20.3 is a working version.
With the "pip list" command I checked the installations on different computers I have tried the script on.
I did made the mistake to install "pycryptodome" instead of "pycryptodomex", mark the letter "X".
This happens if you response on resolving the occuring import error while you install "pywidevine".
Check for the following installations being listed in "pip list", this command shows your installed packages.
pip 23.2.1
pycryptodomex 3.15.0
protobuf 3.20.3
requests 2.28.1
You need to uninstall protobuf and install version 3.20.3.
You need pycryptodomex installed, it will return a ModuleNotFoundError if not installed.
You need requests installed, it will return a ModuleNotFoundError if not installed.
You can remove pycryptodome, it has no impact being installed.
DO NOT INSTALL: “pywidevine” with pip!
Then your “protobuf, pycryptodome and pywidevine” will upgrade to "protobuf-4.21.6, pycryptodome-3-18.0, pywidevine-1.6.0".
Upon upgrading you will receive an Importerror for pywidevine and cdm at "python kijk.py" which you do not want.
When unstalling all packages the following is needed to install correctly:
First you get asked for ModuleNotFoundError "request" so install requests "pip install requests".
Now when you run the script again you get an google.protobuf ModuleNotFoundError, so install protobuf "pip install protobuf==3.20.3".
You also get an pywidevine error but ignore this for now.
If you run the script again you will get an "cryptodome" Module NotFoundError, so "pip install pycryptodomex", not pywidevine else you update to newer versions.
If you run the script, it will work.Last edited by gino92; 3rd Aug 2023 at 08:26.
-
@Karoolus Can you help me in advising to get the correct outcome.
https://www.kijk.nl/programmas/chateau-meiland/psGh9E9D80v
F12, Network tab, search on .mpd file, index.mpd
Complete link Request URL:
https://vod-ww.prd1.talpatvcdn.nl/kijk/psGh9E9D80v/10f936693b554996b6284027dcc5aeb8/ba...PqfBZ7VM9AZA__
Seperated link to .mpd file:
https://vod-ww.prd1.talpatvcdn.nl/kijk/psGh9E9D80v/10f936693b554996b6284027dcc5aeb8/ba...f32e/index.mpd
Upon opening the .mpd file in Excel shows me the PSSH for video and audio:
I sorted the excel file from a-z and it shows me an identical PSSH number.
As following I inserted the information in the python kijk.py file within commandprompt.
PSSH: (From .mpd file in excel)
Code:AAAATHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAACwiJDU4MmY0MThhLWNlOTMtNGQzOS1hYTFlLTY2ODM0YjkyNTUzN0jj3JWbBg==
I selected the file with Request Headers on the "Access-Control-Allow-Origin: https://www.kijk.nl".
Authorization:
Code:aHR0cDovL2FjY2Vzcy5hdXRoLnRoZXBsYXRmb3JtLmNvbS9kYXRhL0FjY291bnQvMjcwNzQ5MTQzNTpleUpoYkdjaU9pSlNVelV4TWlKOS5leUp6ZFdJaU9pSnJhV3ByTWw5d2NtOWtYM1J5ZFhOMEwxVnVjbVZuYVhOMFpYSmxaRVJTVFZWelpYSWlMQ0pwYzNNaU9pSXhJaXdpWlhod0lqb3hOamt4TURJMk1UWXdMQ0pwWVhRaU9qRTJPVEV3TWpJMU5qQXhPRFFzSW1wMGFTSTZJamRrTkdOallURmpMVEEwWlRFdE5ESmlaQzFpWWpSaUxUWXhaRFk0TjJWa09USmtOQ0lzSW1ScFpDSTZJbXRwYW1zeVgzQnliMlJmZEhKMWMzUWlMQ0oxYm0waU9pSlZibkpsWjJsemRHVnlaV1JFVWsxVmMyVnlJaXdpWTNSNElqb2llMXdpZFhObGNrNWhiV1ZjSWpwY0lsVnVjbVZuYVhOMFpYSmxaRVJTVFZWelpYSmNJaXhjSW1sa1hDSTZYQ0pWYm5KbFoybHpkR1Z5WldSRVVrMVZjMlZ5WENKOVhHNGlMQ0p2YVdRaU9pSXlOekF5TnpJd09EazFJbjAuQmZ5aUZpSDdhWW5ib29mdWVhVVRWOHpfRW1SMHRBZnBwMnZFWFpkY2ozdXR2d09CeXBfNmM2c3QzbE44endGSnBxRHhLQmtJaGQtSTFOWDViclpaS0lJTnR3TkdHR19LdGxlOVJjUDVYVnJyTlRqc0lVY2VrQktwSmRqQ3c0M1lLQ0hSa2VpbGRyUjNsRnk2WUJjYXBiWVI4YlZ5SDh1MENTVmpaMFhzVGJ6S05DOWZMNEQ1OVEyUTVmMDRuOFJFUUJqc0R6YTlOWkRkbjM0UWVxV0ZzZmNhYTFTVkgwUFRqWnVvSUhsS2RiZk1ramt0eC1YU2FKNklSTlNpYTk3dU9VT29aQzdlcWlGMkJkWXBsWkxXdG1QWnczU0h6WFZxZHFsS0RaWE5sekt2bjZRUXNCVU9felNjZnNNWWhMa3A2bHJWdlZreVdJekFaTnc4TXpkOTdR
https://widevine.entitlement.theplatform.eu/wv/web/ModularDrm?releasePid=DWCchwveO2ct&...son&schema=1.0
ReleasePID:
Code:DWCchwveO2ct&
unable to parse license - check protobufsLast edited by gino92; 3rd Aug 2023 at 08:42.
-
Code:
KID:KEY -> 0037b8d3deda5a8096439f5b2b15e76d:a81a702c35a7b8c8e95256d8822e309d KID:KEY -> 8dd05790926d51abbe87d17e8fa7b64f:30aea9d5deb78ef44046cf0399ee25dd KID:KEY -> 239126604d2a54e6b791676d33dd878c:da4fb2d79a7f8db5c9399b8098102c2a KID:KEY -> dbbca27a2e8e5a3aa0a0d46142f9cb72:6f05fb6b20ca988a63cafc73d29229ec
There's json data in the request payload that needs to be added to l3.py
Oh, there was already a script... -
ughh, thats was chaotic...
it's been a long time since I practiced so much with several different json's..
(WKS needed)
just give the link the other is automatic..
[Attachment 72877 - Click to enlarge]
kijk.nl
movies & series
Code:from pathlib import Path import subprocess import requests import urllib import json import re import os from requests.packages.urllib3.exceptions import InsecureRequestWarning requests.packages.urllib3.disable_warnings(InsecureRequestWarning) print('\ntest link: https://www.kijk.nl/programmas/chateau-meiland/psGh9E9D80v\ntest link: https://www.kijk.nl/films/it-takes-two/5fiqVrjbAEB\n') link = input('link: ') link_id = re.findall(r'.*/(.*)', link)[0].strip() print(f'id: {link_id}\n') m3u8DL_RE = 'N_m3u8DL-RE.exe' files_to_delete = ["key.txt"] for file_name in files_to_delete: if os.path.exists(file_name): os.remove(file_name) print(f"{file_name} file successfully deleted.") def replace_invalid_chars(title: str) -> str: invalid_chars = {'<': '\u02c2', '>': '\u02c3', ':': '\u02d0', '"': '\u02ba', '/': '\u2044', '\\': '\u29f9', '|': '\u01c0', '?': '\u0294', '*': '\u2217'} return ''.join(invalid_chars.get(c, c) for c in title) import requests headers = { 'authority': 'www.kijk.nl', 'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', } response = requests.get(link, headers=headers).text get_json = re.findall(r'({\"props\":{.*)</script>', response)[0].strip() get_json = json.loads(get_json) try: programs_data = get_json.get('props', {}).get('apolloState', {}).get('ROOT_QUERY', {}).get(f'programs({{"guid":"{link_id}"}})', {}) if programs_data: items = programs_data.get("items", []) if len(items) > 0: ref_id = items[0]["__ref"] full_info_data = get_json.get('props', {}).get('apolloState', {}).get(ref_id, {}) try: ep_title = full_info_data['title'] ser_name = full_info_data['metadata']['media_program_name'] season_num = full_info_data['metadata']['media_program_season'] ep_num = full_info_data['metadata']['media_program_episodenumber'] title = f'{ser_name} - S{season_num:02d}E{ep_num:02d} - {ep_title}' except: title = full_info_data['title'] title = f'{title}' # vtt for track_to_vtt in full_info_data.get("tracks", []): if track_to_vtt.get("kind") == "captions": vtt_link = track_to_vtt['file'] vtt_label = track_to_vtt['label'] try: urllib.request.urlretrieve(vtt_link, ''+title+'.'+vtt_label+'.vtt') print(f'vtt download: {title}.{vtt_label}.vtt') except urllib.error.URLError: pass except TypeError: video_data = get_json.get("props", {}).get("pageProps", {}).get("formatDataInitial", {}).get("video", {}) if video_data.get("guid") == link_id: ser_title = video_data['series']['title'] ep_title = video_data['episodeNumberDetails'] title = f'{ser_title} - {ep_title}' # vtt for track_to_vtt in video_data.get("tracks", []): if track_to_vtt.get("kind") == "captions": vtt_link = track_to_vtt['file'] vtt_label = track_to_vtt['label'] try: urllib.request.urlretrieve(vtt_link, ''+title+'.'+vtt_label+'.vtt') print(f'vtt download: {title}.{vtt_label}.vtt') except urllib.error.URLError: pass title = replace_invalid_chars(title) print(f'\n{title}') def process_video_data(json_data): video_sources = [] programs = json_data.get("data", {}).get("programs", {}).get("items", []) for program in programs: sources = program.get("sources", []) for source in sources: video_type = source.get("type") file_url = source.get("file") drm = source.get("drm", {}) drm_type = None release_pid = None if "widevine" in drm: drm_type = "widevine" release_pid = drm["widevine"].get("releasePid") if video_type == "dash" and drm_type == "widevine" and file_url: video_sources.append({ "file_url": file_url, "release_pid": release_pid }) return video_sources def process_video_data_from_dict(json_dict): video_sources = [] programs = json_dict.get("guid", {}).get("sources", {}).get("items", []) for program in programs: sources = program.get("sources", []) for source in sources: video_type = source.get("type") file_url = source.get("file") drm = source.get("drm", {}) drm_type = None release_pid = None if "widevine" in drm: drm_type = "widevine" release_pid = drm["widevine"].get("releasePid") if video_type == "dash" and drm_type == "widevine" and file_url: video_sources.append({ "file_url": file_url, "release_pid": release_pid }) return video_sources def extract_widevine_info(json_response): if "data" in json_response and "programs" in json_response["data"]: video_data = process_video_data(json_response) else: video_data = process_video_data_from_dict(json_response) if video_data: mpd = video_data[0]["file_url"] releasePid = video_data[0]["release_pid"] return mpd, releasePid else: return None, None headers0 = { 'authority': 'api.prd.video.talpa.network', 'content-type': 'application/json', 'origin': 'https://www.kijk.nl', 'referer': 'https://www.kijk.nl/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', } response0 = requests.get( 'https://api.prd.video.talpa.network/graphql?query=query sources($guid:[String]){programs(guid:$guid){items{guid sources{type file drm __typename}__typename}__typename}}&operationName=sources&variables={"guid":"'+link_id+'"}', headers=headers0, ).json() mpd, releasePid = extract_widevine_info(response0) import requests headers03 = { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36', } response03 = requests.get(mpd, headers=headers03, verify=False).text pssh = re.findall(r'<cenc:pssh.*>(.{20,170})</cenc:pssh>', response03)[0].strip() print(f'\n{pssh}') ########### import requests headers_token = { 'authority': 'api.prd.video.talpa.network', 'accept': 'application/json, text/plain, */*', 'origin': 'https://www.kijk.nl', 'referer': 'https://www.kijk.nl/', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', } response_token = requests.get('https://api.prd.video.talpa.network/graphql?query=%7B%20drmToken%20%7B%20token%20%7D%20%7D', headers=headers_token).json() drm_token = response_token['data']['drmToken']['token'] #old_style_WKS import base64, requests, sys, xmltodict from pywidevine.L3.cdm import cdm, deviceconfig from base64 import b64encode from pywidevine.L3.getPSSH import get_pssh from pywidevine.L3.decrypt.wvdecryptcustom import WvDecrypt lic_url = f'https://widevine.entitlement.theplatform.eu/wv/web/ModularDrm?releasePid={releasePid}&form=json&schema=1.0' headers_wv = { 'Connection': 'keep-alive', 'Origin': 'https://www.kijk.nl', 'Referer': 'https://www.kijk.nl/', 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.0.0 Safari/537.36', 'authorization': f'Basic {drm_token}', 'content-type': 'application/json', } def WV_Function(pssh, lic_url, cert_b64=None): wvdecrypt = WvDecrypt(init_data_b64=pssh, cert_data_b64=cert_b64, device=deviceconfig.device_android_generic) challengeb64 = str(b64encode(wvdecrypt.get_challenge()),"utf-8") json_data = { "getRawWidevineLicense": { "releasePid": releasePid, "widevineChallenge": challengeb64 } } widevine_license = requests.post(url=lic_url, json=json_data, headers=headers_wv) license_b64 = b64encode(widevine_license.content) wvdecrypt.update_license(license_b64) Correct, keyswvdecrypt = wvdecrypt.start_process() if Correct: return Correct, keyswvdecrypt correct, keys = WV_Function(pssh, lic_url) st='' for key in keys: st+=' --key '+key with open("key.txt","w+") as f: f.write(st[1:]+'\n') with open("key.txt", "r") as f2: datas = f2.read() print('\n'+datas) with open("key.txt", "r") as fs: ke_ys = fs.readlines() ke_ys = ke_ys[0].strip().split() subprocess.run([m3u8DL_RE, '-M', 'format=mp4:muxer=ffmpeg', '--auto-select', '--concurrent-download', '--log-level', 'INFO', '--save-name', 'video', mpd, *ke_ys]) try: Path('video.mp4').rename(''+title+'.mp4') print(f'{title}.mp4 \nall done!\n') except FileNotFoundError: print("[ERROR] no mp4 file") for file_name in files_to_delete: if os.path.exists(file_name): os.remove(file_name) print(f"{file_name} file successfully deleted.")
-
@sk8ordi3 Thanks for the script you wrote!
Can you show me a "pip list" output or something similair.
Im not sure wich packages are needed, like updating to newer versions or keeping the previous versions.
There is an issue on the L3, I think this is just a folder.
[Attachment 72882 - Click to enlarge]
The error is on line 212, I just deleted the "L3" tekst, and I have no error.
https://stackoverflow.com/questions/74586258/python-no-module-named-pywidevine-l3
The error is correct there is no module called L3 in pywidevine.
When I run the script after removing the L3 text, within the python folder or on the desktop I get the following error.
[Attachment 72883 - Click to enlarge]
Code:Traceback (most recent call last): File "C:\Users\Gino\AppData\Local\Programs\Python\Python310\Scripts\Kijk\1.py", line 214, in <module> from pywidevine.getPSSH import get_pssh ModuleNotFoundError: No module named 'pywidevine.getPSSH'
This github repository shows an getPSSH.py file with an get_pssh class within.
https://github.com/medvm/widevine_keys
If I download the zip file cand copy the getPSSH file in the pywidevine folder the error disapears.
If I rerun the script I get an error on decrypt folder and from the zip folder I paste the wvdecryptcustoms.py in the decrypt folder.
I have to edit the wvdecryptcustoms.py file on line 6 because it cant reach the cdm. With the following code: "from pywidevine.cdm import cdm, deviceconfig".
Notice in the following picture I receive 4 keys and an error message.
[Attachment 72884 - Click to enlarge]
I downloaded N_m3u8DL-RE as stated in the picture in the previous post.
https://github.com/nilaoda/N_m3u8DL-RE
Go to the release page on the same github page.
https://github.com/nilaoda/N_m3u8DL-RE/releases
Download the version: N_m3u8DL-RE_Beta_win-x64_20230628.zip
Place the "N_m3u8DL-RE.exe" file in the main folder where you run the python script from.
Also put a copy of the "ffmpeg.exe" AND "mp4decrypt.exe" file in the same folder else you get an error.
https://ffmpeg.org/download.html
https://www.bento4.com/downloads/
Download example:
[Attachment 72885 - Click to enlarge]
While downloading it creates a map and puts all the segmented files to download in it and later combines all the m4s files and combines it with the audio.
The combined .mp4 file is placed in the folder the script runs in.
[Attachment 72886 - Click to enlarge]
[Attachment 72887 - Click to enlarge]Last edited by gino92; 3rd Aug 2023 at 20:44.
-
raiplay updated
by the way what you linked is not drm protected.. -
-
-
I help all that ask.
-
-
Similar Threads
-
Vdocipher decryption key retrieval
By Diazole in forum Video Streaming DownloadingReplies: 98Last Post: 13th May 2024, 21:40 -
Widevine Content Key Decryption
By vfa1 in forum Video Streaming DownloadingReplies: 26Last Post: 12th Jan 2024, 05:23 -
Cannot get decryption key from Channel 4...
By hedgehog90 in forum Video Streaming DownloadingReplies: 2Last Post: 7th Nov 2022, 06:46 -
Am I doing this right? (requesting decryption key from license server)
By rajhlinux in forum Video Streaming DownloadingReplies: 56Last Post: 1st Apr 2022, 17:36 -
How do I get the decryption key
By Bakekalu in forum Video Streaming DownloadingReplies: 6Last Post: 5th Jul 2021, 01:25