I used this code with login and password and it also gave the same error, how did you manually correct the PSHHHello I have tried to get this script to work but it gives this error:Here is the downloader for nba.com. It can only be used for free videos (with and without an account, and also both classic videos and game recaps).
Output:Code:import json import re import urllib.parse import requests from pywidevine.cdm import Cdm from pywidevine.device import Device from pywidevine.pssh import PSSH AZUKI_IMC = "IMC7.2.0_AN_D3.0.0_S0" DEVICE_PROFILE = "eyJtb2RlbCI6IkRlc2t0b3AiLCJvc1ZlcnNpb24iOiIxMCIsInZlbmRvck5hbWUiOiJNaWNyb3NvZnQiLCJvc05hbWUiOiJIVE1MNSIsInd2TGV2ZWwiOiJMMyIsImRldmljZVVVSUQiOiJkZXZpY2VVVUlEIn0=" EMAIL = 'YOUR_EMAIL' PASSWORD = 'YOUR_PASSWORD' NBA_PLAY_OPTIONS = 'https://ottapp-appgw-client.nba.com/S1/subscriber/{path}/{program_id}/play-options' NBA_ROLL = 'https://ottapp-appgw-amp.nba.com/v1/client/roll' NBA_API_STS = 'https://identity.nba.com/api/v1/sts' NBA_API_AUTH = 'https://identity.nba.com/api/v1/auth' LICENSE_URL = "https://ottapp-appgw-amp.nba.com/v1/client/get-widevine-license" WVD_FILE = "./device_wvd_file.wvd" def get_pssh_info(base_uri, manifest_uri): manifest = f"{base_uri}/{manifest_uri}" v_m3u8 = re.findall(r'^v.*?\.m3u8\?.*?$', requests.get(manifest).content.decode(), re.MULTILINE)[-1] v_m3u8 = f"{base_uri}/{manifest_uri.replace('index.m3u8', v_m3u8)}" pssh = re.search(r'base64,([^"]+)"', requests.get(v_m3u8).content.decode()).group(1) return manifest, pssh def get_program_info(source_url): if "/video/" in source_url: return "v3/programs", re.findall( r'"mediakindExternalProgramId":"([^"]*)"', requests.get(source_url).content.decode() )[0] if "/game/" in source_url: return "v2/events", max(re.findall(r'\d+', source_url), key=len) return None, None def get_auth_token(): for info in [EMAIL, PASSWORD]: if info is None or len(info) == 0: return json.loads(requests.get(NBA_API_STS).content.decode())["data"]["AccessToken"] response = json.loads(requests.post( NBA_API_AUTH, json={'email': EMAIL, 'password': PASSWORD} ).content.decode())["data"] nba_identity = urllib.parse.quote(json.dumps( {"jwt": response["jwt"], "refreshToken": response["refreshToken"]} )) return json.loads(requests.get( NBA_API_STS, cookies={'nbaidentity': nba_identity} ).content.decode())["data"]["AccessToken"] AUTH_TOKEN = get_auth_token() def get_video_data(source_url): path, program_id = get_program_info(source_url) response = requests.get( NBA_PLAY_OPTIONS.format(path=path, program_id=program_id), headers={'Authorization': f'OAUTH2 access_token="{AUTH_TOKEN}"'}, params={'IsexternalId': 'true'} ).content.decode() matches = re.findall(r'"Id":"([^"]*)"', response) vod_id = sorted( [r for r in matches if "VIDEO" in r] if "VIDEO" in str(matches) else matches, key=len, reverse=True )[0] response = json.loads(requests.post( NBA_ROLL, data="{}", params={'ownerUid': 'azuki', 'mediaId': vod_id, 'sessionId': 'sessionId'}, headers={'AuthorizationToken': AUTH_TOKEN, 'AzukiIMC': AZUKI_IMC, 'DeviceProfile': DEVICE_PROFILE}, ).content.decode()) manifest, pssh = get_pssh_info( response["response"]["cdns"]["cdn"][0]["base_uri"], response["response"]["manifest_uri"], ) return manifest, pssh, vod_id def get_keys(pssh_value, vod_id): if pssh_value is None or vod_id is None: return [] pssh = PSSH(pssh_value) device = Device.load(WVD_FILE) cdm = Cdm.from_device(device) cdm_session_id = cdm.open() challenge = cdm.get_license_challenge(cdm_session_id, pssh) licence = requests.post( LICENSE_URL, data=challenge, headers={"AuthorizationToken": AUTH_TOKEN, 'DeviceProfile': DEVICE_PROFILE, 'AzukiIMC': AZUKI_IMC}, params={"ownerUid": "azuki", "mediaId": vod_id, "sessionId": "sessionId"} ) licence.raise_for_status() cdm.parse_license(cdm_session_id, licence.content) keys = [] for key in cdm.get_keys(cdm_session_id): if "CONTENT" in key.type: keys += [f"{key.kid.hex}:{key.key.hex()}"] cdm.close(cdm_session_id) return keys def get_download_command(source_url): manifest, pssh_value, vod_id = get_video_data(source_url) keys = get_keys(pssh_value, vod_id) if len(keys) == 0: return f"N_m3u8DL-RE.exe {manifest} -M format=mkv" return f"N_m3u8DL-RE.exe {manifest} {' '.join([f'--key {k}' for k in keys])} -M format=mkv" SOURCE_URLS = [ # Without account "https://www.nba.com/watch/video/game-recap-lakers-120-timberwolves-109", "https://www.nba.com/watch/video/the-fast-break-mar-10-2", "https://www.nba.com/watch/video/game-recap-wizards-110-heat-108", "https://www.nba.com/game/hou-vs-ind-0022300719?watchRecap=true", "https://www.nba.com/game/mil-vs-lac-0022300924?watchRecap=true", "https://www.nba.com/game/ind-vs-orl-0022300928?watchRecap=true", # With (free) account "https://www.nba.com/watch/video/2016-dunk-contest-lavine-vs-gordon-best-ever", "https://www.nba.com/watch/video/2-27-2023-banchero-takes-over-in-clutch-vs-pels", "https://www.nba.com/watch/video/12-7-23-haliburton-shines-in-in-season-tournament", ] for s in SOURCE_URLS: print(get_download_command(s))
Their login functionality was implemented in a good way, which was a nice thing to see. The easy solution was to simply use the browser cookies to skip that. So if you want free videos that need a free account to watch, make one and log in using the Firefox browser (and make sure the browser cookies don't get deleted).Code:N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_202403110042NBA_____VIDEOS__NBAE_2730310/index.m3u8?addUserInfo=1 --key 5ebee3c8d5e10606e92be5bb4fad2dab:80f3b559dedfcba9092fff0abf666aad -M format=mkv N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_436C1F6E-DF62-11EE-967D-3CFDFEE7DB71/index.m3u8?addUserInfo=1 --key 843e4a9d08bab7caa44ba37d33b08201:b02e50d244af1e211edc730b15f56b6a -M format=mkv N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_202403102202NBA_____VIDEOS__NBAE_2730223/index.m3u8?addUserInfo=1 --key 13701f9eefda552a1dcb4043a14e899c:8096b4a869983f8fa775787fbda20669 -M format=mkv N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_202402062235NBA_____VIDEOS__NBAE_2719841/index.m3u8?addUserInfo=1 --key b8ab402803beb8e7bbcdca2b8e68f587:ecc693579cf87b70651843297a52b29e -M format=mkv N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_202403101839NBA_____VIDEOS__NBAE_2730064/index.m3u8?addUserInfo=1 --key a28f78780df93c40c3537bef7423b38e:b6436ef1665c8474d48c943440ee5303 -M format=mkv N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_202403102200NBA_____VIDEOS__NBAE_2730212/index.m3u8?addUserInfo=1 --key f81eb304966d19d02bd90d27522ff25d:11cfe5b53309cfb500c47db09ad7dc82 -M format=mkv N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_202301290937NBA_____VIDEOS__NBAE_2630941/index.m3u8?addUserInfo=1 --key 964f42e46638932b33427461f136459f:06ee868164f7d156637fde3fa500a671 -M format=mkv N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_202401301756NBA_____VIDEOS__NBAE_2717587/index.m3u8?addUserInfo=1 --key 6eb0a05cb4fe3dd565df106a02d2419c:eb8f629dc8354f593ce2059a12a75a0b -M format=mkv N_m3u8DL-RE.exe https://nbalpng.akamaized.net/vod-pz/a/hls-wvpr/NBA_202402121203NBA_____VIDEOS__NBAE_2721586/index.m3u8?addUserInfo=1 --key b7866579c32ff24d52882fe194a2ac99:f9fe7b15d02deca76749b80963e68252 -M format=mkv
Also, their API was kinda inconsistent in some responses so the script may not work for the rare video once in a while. Regardless, if there are problems, just leave a message here and I may take a look.
Edit: Seems I kinda praised their login functionality a bit too much. Now the script works fully programmatically without needing to check for existing browser cookies. If you have an account just fill in your email and password. If you just want videos without needing a free account, just make the EMAIL and PASSWORD variables empty strings (the script will obviously fail then if you attempt to download account-required videos).
Edit2: I've seen that some users needed a US VPN. So if something fails, I guess try with that.
in get_pssh_info
v_m3u8 = re.findall(r'^v.*?\.m3u8\?.*?$', requests.get(manifest).content.decode(), re.MULTILINE)[-1]
IndexError: list index out of range
I manually retrieved the pssh and I was able to get the key and download but I want the script to not fail.
[Attachment 78473 - Click to enlarge] to get the keys?
Support our site by donate $5 directly to us Thanks!!!
Try StreamFab Downloader and download streaming video from Netflix, Amazon!
Try StreamFab Downloader and download streaming video from Netflix, Amazon!
+ Reply to Thread
Results 61 to 62 of 62
-
I used this code with login and password and it also gave the same error, how did you manually correct the PSHH
[Attachment 78473 - Click to enlarge] to get the keys? -
Similar Threads
-
Can't decrypt widevine key
By Nethsara Devinda in forum Video Streaming DownloadingReplies: 3Last Post: 24th Sep 2023, 07:47 -
how to get widevine key? (for win11)
By Bobs47 in forum Video Streaming DownloadingReplies: 10Last Post: 13th Aug 2023, 13:27 -
Sincerely request for NBA League Pass download games Widevine Key obtain
By tmactalk in forum Video Streaming DownloadingReplies: 1Last Post: 30th Sep 2022, 04:20 -
Widevine key help
By jhynpls in forum Video Streaming DownloadingReplies: 11Last Post: 28th Jul 2022, 14:56 -
Widevine key not found
By DANNY14596 in forum Video Streaming DownloadingReplies: 15Last Post: 3rd Jun 2021, 23:54