Hi! As the title suggests, I was wondering if there was a way to get the PSSH from init mp4 file without using mp4dump.exe/axiomtools website just using pure python and bento4 sdk somehow. I tried reading their code but I could not understand an easy way to use mp4_dump.py or any other python scripts directly to get init.mp4's KID for the video, which in turn can be used with get_pssh.py file to convert KID into pssh.
Edit: Solution: https://forum.videohelp.com/threads/405001-How-to-get-the-widevine-pssh-from-init-mp4-...pt#post2650501
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 1 to 15 of 15
-
Last edited by ancientbanana; 4th Mar 2022 at 14:13. Reason: Thanks zackmark29 for the solution!
-
In case someone here is still wondering, for windows this is how I figured to do it:
Download the zip file, replace the mp4dump.exe if needed, make changes on do.py file as necessary (if at all needed), place the init mp4 files into init folder, and then run the do.py file. As far as I remember, you won't need to install any dependencies for running the python script. Please let me know if you have any questions. -
-
Currently, while using mp4dump, for certain init mp4s, we just get default KID out of it. And once, we do get the KID, we need to remove the spaces and then use the axiomtools website so as to generate the PSSH corresponding to it. And so, that may be a hassle for some of us who are trying to automate most of the things, and therefore I wanted to have an easier solution for guys like me who like "one touch" solutions to their problems
However, if you do have an idea that's simpler than this, please do let me know, I would definitely love to learn something new!
Sample init which does not have pssh data already: -
Since you tried it first, here's the simplest way without using mp4dump
Code:def find_wv_pssh_offset(raw: bytes) -> str: print('Searching pssh offset') offset = raw.rfind(b'pssh') return raw[offset - 4:offset - 4 + raw[offset - 1]] def to_pssh(content: bytes) -> str: wv_offset = find_wv_pssh_offset(content) return base64.b64encode(wv_offset).decode() def from_file(file_path: str) -> str: print('Extracting PSSH from init file:', file_path) return to_pssh(Path(file_path).read_bytes())
Well you can use that to_pssh for like downloading the init url and reading the response content.
So same as "from_file" function
Code:def from_init_url(init_url: str) -> str: # your code here # and then when returning, use to_pssh(response.content)
Last edited by zackmark29; 4th Mar 2022 at 14:25.
-
-
Init to pssh is smaller than eme logger pssh. Only eme logger pssh gives the key. So why init to pssh gives smaller pssh.
https://cdn.class101.net/videos/447d9e6d-3dae-4d3b-b7e1-c1a3f541168e/cmaf/video/avc1/1/init.mp4
Pssh from init to pssh :- AAAAIHBzc2gAAAAAKXAf5DzHSjSMW66Qx0OaRwAAAAA=
Pssh from eme logger:- AAAAbHBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAAEwSEDQGzo/zboUj5s5B5NpAMb8aDGlua2FlbnR3b3JrcyIkNDQ3ZDllNmQtM 2RhZS00ZDNiLWI3ZTEtYzFhM2Y1NDExNjhlSPPGiZsG -
put them both into https://tools.axinom.com/decoders/PsshBox and see for yourself
the longer one is a widevine pssh and it contains both kid and content id in it - correct.
the short one is not a widevine pssh and doesnt look complete either.
after looking at the init.mp4 you pasted, it contains 3 different psshs - widevine, playready and fairplay and the script seems to be incorrectly grabbing the fairplay pssh data.
the correct widevine pssh can be grabbed from that init.mp4 file -
I need a script which shows all 3 scripts, do you have one? I am writing a script which will decrypt and download, if I can get the proper pssh. It would be helpful!
-
thanks zackmark29,
changeing a little to getting the all pssh's from init and filter with characters limit 70 to 190
and write just filtered in pssh.txt file
Code:import base64 from pathlib import Path def find_wv_pssh_offsets(raw: bytes) -> list: print('Searching pssh offsets') offsets = [] offset = 0 while True: offset = raw.find(b'pssh', offset) if offset == -1: break size = int.from_bytes(raw[offset-4:offset], byteorder='big') pssh_offset = offset - 4 offsets.append(raw[pssh_offset:pssh_offset+size]) offset += size return offsets def to_pssh(content: bytes) -> list: wv_offsets = find_wv_pssh_offsets(content) return [base64.b64encode(wv_offset).decode() for wv_offset in wv_offsets] def from_file(file_path: str) -> list: print('Extracting PSSHs from init file:', file_path) return to_pssh(Path(file_path).read_bytes()) pssh_list = from_file('init.mp4') target_pssh = None for pssh in pssh_list: if 70 < len(pssh) < 190: target_pssh = pssh print(f'\n{target_pssh}\n') print(target_pssh, file=open("pssh.txt", "w"))
[Attachment 70739 - Click to enlarge] -
Thanks for this! but init.mp4 should be in the folder for it to work! It is good enough! I will find a way for it to extract init.mp4 from the site and find the pssh.
-
I usually download a veeeery small test file using yt-dlps --test option and then use this on it:
Code:def construct_pssh(): mymp4dump = subprocess.Popen( [const.mp4dumpexe, '--verbosity', '3', '--format', 'json', 'temp/test.mp4'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL) dump = (mymp4dump.stdout.read()) json_info = json.loads(dump.decode("utf-8")) for temp in json_info: if (temp['name'] == 'moov'): for child in temp['children']: if ('system_id' in child and child['system_id'] == '[ed ef 8b a9 79 d6 4a ce a3 c8 27 dc d5 1d 21 ed]'): pssh_data = child['data'] pssh_data_size_dec = child['data_size'] break break pssh_data = pssh_data.replace('[', '').replace(']', '').replace(' ', '') pssh_size_dec = pssh_data_size_dec + 32 pssh_data_size_hex = (str(hex(pssh_data_size_dec))).replace('0x', '') pssh_size_hex = (str(hex(pssh_size_dec))).replace('0x', '') pssh_hex = f'{pssh_size_hex:0>8}7073736800000000edef8ba979d64acea3c827dcd51d21ed{pssh_data_size_hex:0>8}{pssh_data}' return (base64.b64encode(bytes.fromhex(pssh_hex))).decode('utf-8')
-
-
-
--[----->+<]>.++++++++++++.---.--------.
[*drm mass downloader: widefrog*]~~~~~~~~~~~[*how to make your own mass downloader: guide*]
Similar Threads
-
script widevine
By teosaurus45 in forum Video Streaming DownloadingReplies: 14Last Post: 26th Sep 2023, 06:14 -
Found an awesome script to download widevine content (mpd) and decrypt it
By royjeon215 in forum Latest Video NewsReplies: 8Last Post: 11th Nov 2021, 15:26 -
how to pipe:/// through a .sh or Python script, or use some sort of setting
By netspud2k in forum LinuxReplies: 1Last Post: 4th Mar 2020, 19:48 -
Help Needed With Python ffprobe Script
By chris319 in forum ProgrammingReplies: 11Last Post: 28th Jun 2019, 10:15 -
how to combine init.mp4 and seg-*.m4s files?
By yulsimi in forum Video Streaming DownloadingReplies: 4Last Post: 12th Jan 2019, 14:02