VideoHelp Forum


Try StreamFab Downloader and download from Netflix, Amazon, Youtube! Or Try DVDFab and copy Blu-rays! or rip iTunes movies!


Try StreamFab Downloader and download streaming video from Youtube, Netflix, Amazon! Download free trial.


+ Reply to Thread
Page 3 of 4
FirstFirst 1 2 3 4 LastLast
Results 61 to 90 of 103
Thread
  1. .. And so we can add to the difficulties my bad English
    But I will follow your advice or at least I will try

    (Actually what I meant in my previous post is that not only do you have to find the scripts that work, but you also have to use the right information.
    So my fear is that the combination of these two points, seems to me difficult. But anyway, I continue...)
    Last edited by Gene; 1st Feb 2023 at 17:34.
    Quote Quote  
  2. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by Gene View Post
    (Actually what I meant in my previous post is that not only do you have to find the scripts that work, but you also have to use the right information.
    So my fear is that the combination of these two points, seems to me difficult. But anyway, I continue...)
    Image
    [Attachment 69008 - Click to enlarge]


    Image
    [Attachment 69009 - Click to enlarge]


    Image
    [Attachment 69010 - Click to enlarge]


    Image
    [Attachment 69011 - Click to enlarge]


    "I remember that I do not pay more attention to it" And that is the root cause of all your problems. Pollute some other thread, would you?.
    Quote Quote  
  3. I understand that you are angry with me, but as I said before, the explanations I received here also helped me since the answers are not the same and neither are those who answer them.
    And I thought the forums were independent but probably not.
    I wonder then why 2 forums instead of 1?
    And if you don't want to help me, maybe others do....
    Quote Quote  
  4. Originally Posted by Gene View Post
    I understand that you are angry with me, but as I said before, the explanations I received here also helped me since the answers are not the same and neither are those who answer them.
    And I thought the forums were independent but probably not.
    I wonder then why 2 forums instead of 1?
    And if you don't want to help me, maybe others do....
    Your hijacking an informative thread with bs mate !

    This is a reference thread for god's sake.

    If you want to post about your inadequacies, make a new thread of your own, don't clutter this one up with your bs, please.

    You are completely off-topic - read the thread title and read the first post. But as we get very little modding here, there's no one to pull you up for being off topic.
    Quote Quote  
  5. Member
    Join Date
    Dec 2021
    Location
    Scotland
    Search Comp PM
    Yes, back to being informative. Here's my solution for a rte downloader. Create it as the name rte.py and just drop it in the WKS-KEYS directory and to run: py rte.py. NOTE: Now updated, see end comment.
    You'll need to have had pip installed uncurl and pyperclip.
    It asks for mpd URL and then filter for wide (ie. the licence) and do a Copy as cURL(cmd) to clipboard, then at prompt just press Enter. NOTE: I said cURL(cmd), and NOT cURL(bash), even for Windows users. No, you don't have to use the cURL to Python convertor, I'm using the uncurl module instead.

    It's based on medvm's l3.py: https://github.com/medvm/widevine_keys/blob/main/l3.py, so a big thank you to medvm. I think I've stripped out most of the the redundant bits and I've shuffled things around.

    It now assumes just one set of KID:KEYs (rte used to have 5 sets).
    Code:
    # RTE downloader
    ####version (20230206-1)  strip more medvm script that doesn't appear to be applicable for RTE.
    ####version (20230205-1)  do checks for dupe filename and illegal characters
    #### version 2023-02-04/1
    # Place this in WKS-KEYS directory. To run: py rte.py
    
    
    import requests
    import json
    from pywidevine.L3.cdm import deviceconfig
    from base64 import b64encode
    from pywidevine.L3.decrypt.wvdecryptcustom import WvDecrypt
    from urllib.parse import urlparse
    import uncurl
    import pyperclip as PC
    import os
    import shutil, glob
    
    ##########useful when used within VS Code to tell it which directory you're in
    abspath = os.path.abspath(__file__)
    dname = os.path.dirname(abspath)
    os.chdir(dname)
    ##########
    
    def cls():
        # posix is os name for Linux or mac
        if(os.name == 'posix'):
            os.system('clear')  # clear is the bash command
        # else screen will be cleared for windows (os name is actually nt for Windows)
        else:
            os.system('cls')  # cls is the batch command
    
    def cURL_cmd():
        wait = '''\n\n\n   Filter for wide, do Copy as cURL(cmd)      NOT cURL(bash)\n   then press Enter to continue....'''
        input(wait)
        mycode = PC.paste()
        mycode = mycode.replace("^", "")
        context = uncurl.parse_context(mycode)
        lic_url = context.url
        myjson = json.loads(context.data)
        releasePID = (myjson['getWidevineLicense']['releasePid'])
        headers = dict(context.headers)  #this is an OrderedDict
        return lic_url, releasePID, headers
    
    def generate_pssh(mpd):
        division = mpd.split("cenc:pssh")
        for i in division:
            if i[1:5] == "AAAA":
                break
        pssh = i[1:-2]
        print(f"\nPSSH is {pssh}")
        return pssh
    
    def WV_Function(pssh, lic_url, cert_b64=None):
    	"""main func, emulates license request and then decrypt obtained license
    	fileds that changes every new request is signature, expirationTimestamp, watchSessionId, puid, and rawLicenseRequestBase64 """
    	wvdecrypt = WvDecrypt(init_data_b64=pssh, cert_data_b64=cert_b64, device=deviceconfig.device_android_generic)                   
    	raw_request = wvdecrypt.get_challenge()
    	request = b64encode(raw_request)
    	
        # rte.ie support
    	responses.append(requests.post(url=lic_url, headers = headers, params=params, 
    		json={
    		"getWidevineLicense": 
    			{
    			'releasePid': releasePID,
    			'widevineChallenge': str(request, "utf-8" )
    			}, 
    			}))
    
    	for idx, response in enumerate(responses):
    		if len(str(response.content, "utf-8")) > 500:
    			widevine_license = response
    			print(f'{chr(10)}license response status: {widevine_license}{chr(10)}')
    
    	lic_field_names = ['license', 'payload', 'getWidevineLicenseResponse']
    	lic_field_names2 = ['license']
    	
    	if str(widevine_license.content, 'utf-8').find(':'):
    		for key in lic_field_names:
    			try: 
    				license_b64 = json.loads(widevine_license.content.decode())[key]
    			except:
    				pass			
    			else:
    				for key2 in lic_field_names2:
    					try: 
    						license_b64 = json.loads(widevine_license.content.decode())[key][key2]
    					except:
    						pass
    	
    	wvdecrypt.update_license(license_b64)
    	Correct, keyswvdecrypt = wvdecrypt.start_process()
    	if Correct:
    		return Correct, keyswvdecrypt   
    
    
    def filename():
        output_name = input("What do you want to call your final file? (do not include file .extension like .mp4) ")
        output_name = f"{output_name}.mp4"
        path = f"./Completed/{output_name}"
        # look to see if duplicate filename
        if os.path.isfile(path):
            print(f"\nyou already have a file called {output_name}. Choose another name\n")
            return filename()
        #look to see if any illegal characters in filename
        illegals = "@$%&\/:*?\"'<>|~`#^+=\{\}[];!"
        any_illegals = (set(output_name) & set(illegals))
        if not any_illegals:
            return output_name
        else:
            list_illegals = ' '.join(any_illegals)
            print(f"\nyou have included the following which are not legal characters:       {list_illegals}\n")
            return filename()
    
    
    cls()
    MDP_URL = input("enter mpd URL: ")
    
    lic_url, releasePID, headers = cURL_cmd()
    print(f"\nlicense is {lic_url}\n\n")
    print(f"releasePid is {releasePID}")
    
    mpd = requests.get(MDP_URL, headers = headers).text
    pssh = generate_pssh(mpd)
    
    responses = []
    license_b64 = ''
    
    params = urlparse(lic_url).query
    correct, keys = WV_Function(pssh, lic_url)
    
    # for key in keys:
    # 	print('KID:KEY -> ' + key)
    
    print("KID:KEY found is " + (keys[0]))
    keys = str(keys[0])
    division = keys.find(":")
    key = (keys[division+1:])
    print(f"   KEY# is {key}")
    
    print("\n\n")
    
    os.system(f'yt-dlp --allow-u -f bestvideo -N 6 "{MDP_URL}" -o encryptVid.mp4')
    os.system(f'yt-dlp --allow-u -f bestaudio -N 6 "{MDP_URL}" -o encryptAud.m4a')
    
    
    print("==============================\n\n Decrypting\n\n==============================")
    
    os.system(f"mp4decrypt --show-progress --key 1:{key} encryptVid.mp4 video_decrypt.mp4")
    os.system(f"mp4decrypt --show-progress --key 1:{key} encryptAud.m4a audio_decrypt.m4a")
    
    if not os.path.exists("Throwaway"):
        os.makedirs("Throwaway")
    
    if not os.path.exists("Completed"):
        os.makedirs("Completed")
    
    cls()
    print("\n\n\n")
    
    output_name = filename()
    
    os.system(f"ffmpeg -i video_decrypt.mp4  -i audio_decrypt.m4a -c:v copy -c:a copy mux_file.mp4")
    os.rename("mux_file.mp4", f'{output_name}')
    
    shutil.move(f'{output_name}', "./Completed")
    
    for data in glob.glob("*_decrypt*.*"):
        shutil.move(data,"./Throwaway")
    for data in glob.glob("encrypt*.*"):
        shutil.move(data,"./Throwaway")
    shutil.rmtree("./Throwaway")
    
    print(f"All done.\n\n Your final file '{output_name}' is in 'Completed' folder")
    Since I wrote the original code, it's been updated considerably, stripping out large chunks of medvm's original l3.py. the above is this modified version.
    I have also included checks for ensuring you don't try to save a dupe file to the same directory and you don't include "illegal" characters in file name.

    I removed the chunks purely by experiment (using a bit of logic). I am very much the amateur and I certainly don't profess to understand fully the code associated with responses between browser and server regarding widevine decryption. The rest of the script is largely mine.
    Last edited by deccavox; 6th Feb 2023 at 05:27.
    Quote Quote  
  6. Member
    Join Date
    Dec 2022
    Location
    Lesotho
    Search Comp PM
    Nice one @deccavox!
    Quote Quote  
  7. Originally Posted by deccavox View Post
    Yes, back to being informative. Here's my solution for a rte downloader. Just drop it in the WKS-KEYS directory and to run: py rte.py
    It asks for mpd URL and then filter for wide (ie. the licence) and do a Copy as cURL(cmd) to clipboard, then at prompt just press Enter. NOTE: I said cURL(cmd), and NOT cURL(bash), even for Windows users. No, you don't have to use the cURL to Python convertor, I'm using the uncurl module instead.

    It's based on medvm's l3.py: https://github.com/medvm/widevine_keys/blob/main/l3.py, so a big thank you to medvm. I think I've stripped out most of the the redundant bits and I've shuffled things around.
    First of all - you are a LEGEND! Thank you for posting a working example. I have been struggling with the type of license generation sites like rte uses.

    In a few examples of some content I've been trying to grab, the initial license request is a 2 byte payload, usually /U8,/U4 which I believe are just 0x08 and 0x04.

    Do you know if your rte script can be adapted to use this model? I took a look at medvm's github but Im not sure if his "generic" code will handle this or if something custom needs to be done.

    If you're able to point me in the right direction I'd be very grateful, my PMs are always open if you need further details / logins Thank you for your time.
    Quote Quote  
  8. Member
    Join Date
    Dec 2021
    Location
    Scotland
    Search Comp PM
    Re: my above RTE downloader.
    Since I wrote the original code, it's been updated considerably, stripping out large chunks of medvm's original l3.py. the above is now this modified version.
    I have also included checks for ensuring you don't try to save a dupe file to the same directory and you don't include "illegal" characters in file name.

    I removed the chunks purely by experiment (using a bit of logic). I am very much the amateur and I certainly don't profess to understand fully the code associated with responses between browser and server regarding widevine decryption. The rest of the script is largely mine.

    And I notice that tonight's new series Smother on RTE has audio bitrate of around 128Kbps. Is this a sign of things to come?
    Quote Quote  
  9. Do not send me DM's
    Join Date
    Dec 2021
    Location
    Tˇrshavn
    Search Comp PM
    Smother is a bbc/rte joint co-production (or rather bbc/*treasure)
    But the version currently on the player is a broadcast capture, hence the 125kb/s bitrate.
    When they decide to tidy it up, you'll notice the bitrate will be 64kb/s
    Similar occurred with other joint productions, like Hidden Assets. (RTE/Viaplay co-production)
    Quote Quote  
  10. Trying to grab the smother episodes myself, and I'm getting this with that rte.py script :

    ```
    [...]
    Traceback (most recent call last):
    File "rte.py", line 131, in <module>
    correct, keys = WV_Function(pssh, lic_url)
    File "rte.py", line 79, in WV_Function
    if str(widevine_license.content, 'utf-8').find(':'):
    UnboundLocalError: local variable 'widevine_license' referenced before assignment
    ```

    I don't have a copy as curl(cmd), so I'm using posix, assuming it's the same but maybe not.
    It looks like the responses[0].text is `Widevine generateLicense call against [https://license.widevine.com/cenc/getlicense/theplatformrte] failed with status [INVALID_LICENSE_CHALLENGE]` response code 422
    Last edited by Ulrar; 11th Apr 2023 at 11:27.
    Quote Quote  
  11. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by Ulrar View Post
    Trying to grab the smother episodes myself, and I'm getting this with that rte.py script :
    If you are still out of luck this has appeared on UKTVplay. https://uktvplay.co.uk/shows/smother/watch-online

    And this will get it.

    Code:
    #!/usr/bin/env python3
    #
    # v 2.0
    #
    # A_n_g_e_l_a 03:02:2023
    # 
    '''
    This program is a generic boltdns.net downloader. 
    It takes only a SINGLE mpd url,  master.m3u8 or vmap -  as input as a 'media_url'  
    within 'Table Entry from The Stream Detector
    The program downloads, decodes and merges.
    
    Written for Linux systems using WKS-KEYS with a working CDM.
    For encrypted media, this program needs to be in WKS-KEYS folder to use your local CDM
    it will save to ./output/ from the WKS_KEYS folder and you need create the folder 'output' if it doesn't exist.
    
    N_m3u8DL-RE, shaka-packager, mkvmerge and ffmpeg need to be in Path.
    (Windows users may need to tack .exe on the end of the called programs in the code below)
    
    #not used currently
    #'pip install vtt_to_srt3' probably needed first;  installs a subtitle conversion that works better than N_m3u8DL-RE's
    
     'The Stream Detector' browser plugin (Chrome + Firefox) is required.
    Find here: Firefox version - https://addons.mozilla.org/en-US/firefox/addon/hls-stream-detector/
    Chrome version: https://github.com/rowrawer/stream-detector/releases  choose  hls_stream_detector-2.1X.XX.crx 
    and in chrome://extensions/  set Developer mode (top-right window) and drag and drop the crx file into the window to install
    
    Once installed configure with an additional filter set for 'vmap'.
    Under Options:
    'Detect additional file extensions:' set checkbox ticked and enter 'vmap' in box.
    
    working for :-
    STV.tv both encrypted and encryption free
    uktvplay.co.uk all encrypted.
    tptvencore.co.uk mainly unencrypted m3u8 but some encrypted vmap included too. Media_url may need to 
        be contained in single quotes if there are '&' characters present.
    tg4.ie  all encrypted
    and possibly other providers using boltdns.net for streaming
    
    The program is configured to use alternate inputs on the command line of media url and videoname.
    So without the Stream Detector just call
    'python boltdnsnet.py   https://manifest.prod.boltdns.net/manifest/v1/dash/live-baseurl/bccenc/1242911124001/86077ea5-b607-447a-9966-af53caf2b3ea/6s/manifest.mpd?fastly_token=NjQ2OGE4YjNfNjJhNDhhMWQwZjU4ODZmNzAwYzMyZWI4ZTMwOWI2NDQyNWFiMmFjY2JmMWY0Y2U2ZmU3ODlhMTNhNTk3YWQyYg%3D%3D  SmotherS01E06'   
    
    '''
    
    import requests 
    from pywidevine.L3.cdm import deviceconfig
    from base64 import b64encode
    from pywidevine.L3.decrypt.wvdecryptcustom import WvDecrypt
    import re
    import subprocess
    import pyfiglet as PF
    from termcolor import colored
    import pyperclip as PC
    import os
    import math
    
    
    ## globals
    headers = {
        'User-Agent': 'Dalvik/2.9.8 (Linux; U; Android 9.9.2; ALE-L94 Build/NJHGGF)',
        'Accept': '*/*',
        'Accept-Language': 'en-GB,en;q=0.9',
        'Connection': 'keep-alive',
    }
    
    # defs
    # regex search for pssh and license url
    def get_pssh_lic(mpd_url):
        mpd = requests.get(mpd_url, headers).text
        lines = mpd.split("\n")
        for line in lines:
            m = re.search('<cenc:pssh>(AAAA.+?)</cenc:pssh>', line)
            n = re.search('bc:licenseAcquisitionUrl=\"(http.+?)\" xmlns:bc=\"urn:brightcove:2015\"', line)
            if m:
                pssh = m.group(1)
            if n:
                lic_url = n.group(1)
        return pssh, lic_url
    
    ## pretty print screen divisions
    def divides(text):  
        #text = text
        l = len(text)
        count, lines = os.get_terminal_size()
        count = int(count)
        if count <= 78:
            count = int(count)
        else:
            count = int(math.ceil(count/2))
        count = count - l
        if text != 'null':   
            line = (chr(9601) * int(math.ceil(count/2)))
            #print("\n")
            print(colored(line, 'green'), " ",  text, " ",   colored(line, 'green'))  
        else:
            line = (chr(9601) * int(count + 10))
            print(colored(line, 'green'))
    
    # WKS-KEYS key fetch
    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)                   
        widevine_license = requests.post(url=lic_url, data=wvdecrypt.get_challenge(), headers=None)
        license_b64 = b64encode(widevine_license.content)
        wvdecrypt.update_license(license_b64)
        Correct, keyswvdecrypt = wvdecrypt.start_process()
        if Correct:
            mykeys = ''
            for key in keyswvdecrypt:
                mykeys += key + '--key'
        if mykeys.endswith('--key'):
            mykeys = mykeys[:-5]
        divides('Key(s)')
        print(mykeys)
        return mykeys 
    
    # find mpd/m3u8 in vmap
    def parse_vmap(content):
        lines = content.split("\n")
        for line in lines:
            m = re.search(r'contenturi="(https.+?)" contentlength=', line)
            if m:
                media_url = m.group(1)
                return(media_url)
        
        return None
    
    # add leading zero to series or episode
    def pad_number(match):
        number = int(match.group(1))
        return format(number, "02d")
    
    
    if __name__ == '__main__':
        #### main #### 
        divides("null")
        print()
        title = PF.figlet_format(' BoltDNS dot net ', font='smslant')
        print(colored(title, 'green'))
        divides('A Generic Boltdns.net single downloader')
        from sys import argv
        #print(argv)
        if argv and len(argv) > 1:
            media_url = argv[1]
            videoname = argv[2]
        else:
            print('\n\n[info] URLs may be of the form:- mpd, master.m3u8 or vmap from boltdns.net.')
            print('\n\n[info] Use Stream Detector "copy as Table Entry"')
            input("Ready for clipboard TSD Table Entry: ")
            line = PC.paste()
            if 'master.m3u8?behavior_id' in line: # keeps changing!!
                STV = True
            else:
                STV = False   
            linetuple = line.split('|')
            media_url = linetuple[0].replace('\n','').replace(' ', '')
            print(f"[info] downloading {media_url}")
            # collect videoname from table entry
            # each site has different naming conventions
            # this may need tweeking ...
            if STV:
                videoname1 = linetuple[1]
                videoname2 = linetuple[2].split(',')
                videoname2 = videoname2[0]
                videoname = (videoname1 + videoname2).replace(' ','_').replace('__','-')  
            else:
                videoname = linetuple[1].replace('\n','').replace(' ','_')\
                    .replace('_Watch_','').replace('_Online_','')
            if videoname.endswith('_'):
                videoname = videoname.rstrip(videoname[-1])
            if videoname.startswith('_'):
                videoname = videoname[1:]
            if not STV:
                videoname = videoname.replace('Series_','S').replace('_Episode_','E')\
                    .replace("'", '').replace('(','').replace(')','').replace(':','.')
                videoname = re.sub(r"(\d+)", pad_number, videoname)
            # ... or reverting
            #videoname = input("Enter Video name to save: (without mkv) : ") 
    
        #### decide type dash (mpd),  m3u8 or vmap
        dash = "dash" #encrypted
        m3u8 = 'm3u8'
        vmap = 'vmap' #encrypted or not
    
        if vmap in media_url:
            content = requests.get(media_url, headers).text
            media_url = parse_vmap(content)  # either m3u8 or dash
        if dash in media_url:
            pssh, lic = get_pssh_lic(media_url)
            # need keys
            mykeys = '' 
            mykeys = WV_Function(pssh, lic)
          
            divides("getting encrypted streams")
            command = [
                "N_m3u8DL-RE",
                media_url,
                "--auto-select",
                "-sv",
                "best",
                "-sa",
                "id='audio-0'",
                "-ss",
                "id='subtitles-0':for=all", 
                "--save-name",
                videoname,
                "--save-dir",
                "./output",
                "--tmp-dir",
                "./",
                "-mt",
                "--use-shaka-packager",
                "--key",
                mykeys,
                #"-M",
                #"format=mkv:muxer=mkvmerge",
                ]
            subprocess.run(command)
        elif m3u8 in media_url: 
            divides('Getting encryption free stream')
            command = [
            "N_m3u8DL-RE",
            media_url,
            "--binary-merge",
            "--auto-select",
            "-sv",
            "best",
            "-sa",
            "id='audio-0'",
            "-ss",
            "id='subtitles-0':for=all",
            "--save-name",
            videoname,
            "--save-dir",
            "./output/",
            "--tmp-dir",
            "./",
            "-mt",
            #"--use-shaka-packager",
            #"-M",
            #"format=mkv:muxer=mkvmerge",
            ]
            subprocess.run(command)
        if os.path.isfile(f"./output/{videoname}.en.srt"):
            os.system(f"perl -i -pe  's/<.*?>//gm' ./output/{videoname}.en.srt")
            # attempt a
            '''with open(f'./output/{videoname}.en.srt', 'r') as original: data = original.read()
            with open(f'./output/{videoname}.srt', 'w') as modified: modified.write("WEBVTT\n\n" + data)
            original.close()
            modified.close()'''
            os.system(f"mkvmerge -q --no-date -o ./output/'{videoname}'.mkv \
                  -S -B -M --language 0:en --default-duration 0:25000/1000p \
                  --fix-bitstream-timing-information 0:1 ./output/'{videoname}'.mp4 \
                  --language 0:en ./output/'{videoname}'.en.m4a --language 0:en \
                  --track-name 0:English --default-track 0:0 --forced-track 0:0 \
                   ./output/'{videoname}'.en.srt")
    
        elif os.path.isfile(f"./output/{videoname}.mp4"):
            os.system(f"mkvmerge -q --no-date -o ./output/'{videoname}'.mkv \
                    -S -B -M --language 0:en --default-duration 0:25000/1000p \
                    --fix-bitstream-timing-information 0:1 ./output/'{videoname}'.mp4 \
                    --language 0:en ./output/'{videoname}'.en.m4a")
        # tptvencore may have ts files
        elif os.path.isfile(f"./output/{videoname}.ts"):
            os.system(f"mkvmerge -q --no-date -o ./output/'{videoname}'.mkv \
                -S -B -M --language 0:en --default-duration 0:25000/1000p \
                --fix-bitstream-timing-information 0:1 ./output/'{videoname}'.ts \
                --language 0:en ./output/'{videoname}'.en.ts")
            
    
        os.system("rm -f ./output/*.m4a  ./output/*.srt ./output/*.mp4 ./output/*.ts") 
       
        exit(0)
    Image
    [Attachment 70480 - Click to enlarge]


    I've been having trouble with some subtitles showing markup language parts on playback. I play to my TV from an Enigma2 Satellite Box that doesn't handle subtitles too well. If you use a decent playback engine like VLC you can remove this line :-
    os.system(f"perl -i -pe 's/<.*?>//gm' ./output/{videoname}.en.srt")
    Last edited by A_n_g_e_l_a; 22nd Apr 2023 at 06:16.
    Quote Quote  
  12. I used the python script here for the boltsdns.net generic one for my site, which has mpd, drm protected with dash. It gives the key however it is not going forward with the download due to an error.

    Traceback (most recent call last):
    File "D:\Youtube dl\Python\Patreon try\WKS-KEYS\gnomon mpd.py", line 94, in <module>
    correct, keys = WV_Function(pssh, lic)
    ValueError: too many values to unpack (expected 2)

    How do I fix this? Any Idea?
    Quote Quote  
  13. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by Sadomasochist View Post
    I used the python script here for the boltsdns.net generic one for my site, which has mpd, drm protected with dash. It gives the key however it is not going forward with the download due to an error.

    Traceback (most recent call last):
    File "D:\Youtube dl\Python\Patreon try\WKS-KEYS\gnomon mpd.py", line 94, in <module>
    correct, keys = WV_Function(pssh, lic)
    ValueError: too many values to unpack (expected 2)

    How do I fix this? Any Idea?
    What was the mpd you had that gave this error?
    Quote Quote  
  14. Originally Posted by A_n_g_e_l_a View Post

    What was the mpd you had that gave this error?
    https://manifest.prod.boltdns.net/manifest/v1/dash/live-baseurl/bccenc/4276901731001/0...Y2OTc5Yw%3D%3D
    Quote Quote  
  15. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by Sadomasochist View Post
    Originally Posted by A_n_g_e_l_a View Post

    What was the mpd you had that gave this error?
    https://manifest.prod.boltdns.net/manifest/v1/dash/live-baseurl/bccenc/4276901731001/0...Y2OTc5Yw%3D%3D
    It downloads just fine. I think maybe the error you got was you were not giving it the proper clipboard of 'table Entry' from the stream detector.

    It looks like this mpd_url | video name | date
    thats three bits of information separated by a |
    But the program accepts calling from the command line -as indeed it was the method I used on this occasion as all I had was the mpd.

    So try
    Code:
    python boltdnsnet.py https://manifest.prod.boltdns.net/manifest/v1/dash/live-baseurl/bccenc/4276901731001/06deab6a-050c-4430-bb2a-c2fa06825c73/6s/manifest.mpd?fastly_token=NjQ0NjBjNzJfYmY1ZjIyOGIxYzkzNTFhMWIzZGE1NDYzNWU2ZGQ3NWZiZGE3ZDcyZDY5MzI3OGM5ZDJmYmMzNTNiM2Y2OTc5Yw%3D%3D  videoname
    So that's:-
    python script-name mpd_url videoname
    as shown in the screenshot
    Image
    [Attachment 70498 - Click to enlarge]


    Your video is here. I do hope you are not a reseller! https://anonfiles.com/6357hfnez4/unknown_mkv
    Quote Quote  
  16. Originally Posted by A_n_g_e_l_a View Post
    Originally Posted by Sadomasochist View Post
    Originally Posted by A_n_g_e_l_a View Post

    What was the mpd you had that gave this error?
    https://manifest.prod.boltdns.net/manifest/v1/dash/live-baseurl/bccenc/4276901731001/0...Y2OTc5Yw%3D%3D
    It downloads just fine. I think maybe the error you got was you were not giving it the proper clipboard of 'table Entry' from the stream detector.

    It looks like this mpd_url | video name | date
    thats three bits of information separated by a |
    But the program accepts calling from the command line -as indeed it was the method I used on this occasion as all I had was the mpd.

    So try
    Code:
    python boltdnsnet.py https://manifest.prod.boltdns.net/manifest/v1/dash/live-baseurl/bccenc/4276901731001/06deab6a-050c-4430-bb2a-c2fa06825c73/6s/manifest.mpd?fastly_token=NjQ0NjBjNzJfYmY1ZjIyOGIxYzkzNTFhMWIzZGE1NDYzNWU2ZGQ3NWZiZGE3ZDcyZDY5MzI3OGM5ZDJmYmMzNTNiM2Y2OTc5Yw%3D%3D  videoname
    So that's:-
    python script-name mpd_url videoname
    as shown in the screenshot
    Image
    [Attachment 70498 - Click to enlarge]


    Your video is here. I do hope you are not a reseller! https://anonfiles.com/6357hfnez4/unknown_mkv


    Thanks for the prompt reply. I do have copy stream url as Table entry in my mozilla firefox. I dont know if I have to copy the mpd from it in the clipboard for it work! But the code asks me to paste the mpd url anyways. So I dont know if it matters. But I did managed to fix it, it seems if I edit the code as 'keys = WV_Function(pssh, lic)'. It downloads fine. How do I do it for all the video, instead of single entry. Also, I never sell any courses. It is just for personal use.
    Quote Quote  
  17. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by Sadomasochist View Post

    Thanks for the prompt reply. I do have copy stream url as Table entry in my mozilla firefox. I dont know if I have to copy the mpd from it in the clipboard for it work! But the code asks me to paste the mpd url anyways. So I dont know if it matters. But I did managed to fix it, it seems if I edit the code as 'keys = WV_Function(pssh, lic)'. It downloads fine. How do I do it for all the video, instead of single entry. Also, I never sell any courses. It is just for personal use.
    Great you've fixed it. I didn't read your post carefully enough. What your result means is that there are versions of WKS-KEYS that are incompatible. I use WKS-KEYS from https://github.com/huliad2022/WKS-KEY/releases/tag/WKS-KEY which returns (Correct, keys) as a tuple. 'Correct' is either True or False, and is fairly pointless if keys has a value.

    As for pasting, there is no need. All you do is click on the mpd in The Stream Detector. That puts it into the clipboard. All you then do is just run the python script and click Enter when it waits before reading from the clipboard.

    You want a series downloader from boltdns? Easily done The Stream Detector can copy a whole load of table entries with mpds etc. And some of my code I've pasted for other sites does series.
    But remember - I'm about empowering you to do stuff. So your challenge for the week is...
    Last edited by A_n_g_e_l_a; 24th Apr 2023 at 04:45.
    Quote Quote  
  18. Originally Posted by A_n_g_e_l_a View Post

    Great you've fixed it. I didn't read your post carefully enough. What your result means is that there are versions of WKS-KEYS that are incompatible. I use WKS-KEYS from https://github.com/huliad2022/WKS-KEY/releases/tag/WKS-KEY which returns (Correct, keys) as a tuple. 'Correct' is either True or False, and is fairly pointless if keys has a value.

    As for pasting, there is no need. All you do is click on the mpd in The Stream Detector. That puts it into the clipboard. All you then do is just run the python script and click Enter when it waits before reading from the clipboard.

    You want a series downloader from boltdns? Easily done The Stream Detector can copy a whole load of table entries with mpds etc. And some of my code I've pasted for other sites does series.
    But remember - I'm about empowering you to do stuff. So your challenge for the week is...
    So I click multiple mpd and it will store in clipboard a series of mpd urls? The copy all button copies with time and some manifest strings, which was confusing. I want to download the entire course, with course title etc. Your other code has stuff pertaining to it and also about cookie n stuff , but I guess it is doable with some trial and error. As an empowered novice python learner, I will accept the challenge .
    Quote Quote  
  19. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by Sadomasochist View Post

    So I click multiple mpd and it will store in clipboard a series of mpd urls? The copy all button copies with time and some manifest strings, which was confusing. I want to download the entire course, with course title etc. Your other code has stuff pertaining to it and also about cookie n stuff , but I guess it is doable with some trial and error. As an empowered novice python learner, I will accept the challenge .
    You need to visit each video in your browser. Now here some sites only give up an mpd when you click play video, others when you load the page. Watch the number on The Stream Detector icon for change to see if TSD has captured it or not. STV as an example requires each video to be run. UKTVPlay just requires a page visit. TSD keeps all mpd seen from that browser tab.

    When you have yourn list, click on 'copy all visible URLs' in TSD and run the script. You can ignore any other stuff that TSD may have in its list - they do not get processed.
    Quote Quote  
  20. After adding and deleting stuff from the code, I managed to copy all entires from stream decdector and wrote code for it to ignore the other stuff besides the mpd. It also prints all the mpd, but it seems to download only the first entry. I dont know which part allows the script to start the batch process! instead of a single download.

    Also the video name part, How do I give video name for all the mpds, it is a user input, so I write 'test'. It only downloads the first video with the file name as test.
    Quote Quote  
  21. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    A table entry from Stream Detector may look like this:-
    The stuff you've ignored probably had the video name, series and episode - so above it is Smother, Series 1, Episode 1. I usually process that to become simplified as 'Smother_S01E01'.

    Only reading the first line means you haven't implemented a loop on the lines of mpd etc in your clipboard. First break the clipboard into discrete lines of text by using the .split('\n') function on your clipboard input.
    Then a for loop to process each line and call the whole download routine for each line. Look at the ITVXbatch.py that I posted to see one way of doing it.
    Last edited by A_n_g_e_l_a; 1st May 2023 at 05:58.
    Quote Quote  
  22. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Hi I have read your article and managed to have success with bitmovin and the other site tg4. I was wondering if you could help me learn more about finding the proper license url headers and mod. Each site seems different. Also though my phone is rooted it says CDM lvl1 but dumper puts files in lvl 3 folder? Any advice would be appreciated. Thank you again for your article.
    This is from @Iridule and is typical of PM requests I get. There is nothing in it that warrants a Private Message - so anyone else care to respond?
    Quote Quote  
  23. Member
    Join Date
    May 2023
    Location
    United States
    Search Comp PM
    Originally Posted by A_n_g_e_l_a View Post
    Hi I have read your article and managed to have success with bitmovin and the other site tg4. I was wondering if you could help me learn more about finding the proper license url headers and mod. Each site seems different. Also though my phone is rooted it says CDM lvl1 but dumper puts files in lvl 3 folder? Any advice would be appreciated. Thank you again for your article.
    This is from @Iridule and is typical of PM requests I get. There is nothing in it that warrants a Private Message - so anyone else care to respond?
    I had originally posted in the introductory section https://forum.videohelp.com/threads/409507-Advice-for-a-noob-CDM-bitmovin. Yet no answer. This is a fairly small forum, I guess that's to be expected. I would imagine you get these PM requests because of the small forum and people posting in the new introductory section getting no answer ... Not sure. Many of these topics go back to 2021 or even 2017 and even then some answers are not there. I was mostly just curious as to why people were saying l1 wouldn't work. Yet for me seems to.

    The other issues I think have been solved basically wrong headers. Once a more sophisticated page analyzer is used and whatever site is analyzed and their particular pattern has been identified. Using something like HttpToolkit. All should work and the "unable to parse license - check protobuf" error should go away? I hope. I suppose Not bad for somebody who never used Linux 2 months ago I think learning to compile the kernel really opened up quite a lot of options for me. Then I was able to root my phone and now have a CDM . Neat.
    Last edited by Iridule; 9th May 2023 at 15:16.
    Quote Quote  
  24. Member
    Join Date
    May 2023
    Location
    United States
    Search Comp PM
    still not sure what is wrong here I am using HttpToolkit and it is giving various errors depending on headers/license URL.
    I am getting "too many requests error" if I use License URL https://blahURLblahblah----widevine/getlicense? ...if I add the entire license URL with Content ID and other strings I get "bad gateway" appending ?specConform=true to the end of the URL seems to make no difference. I've spent about 28 hours straight going over this forum ...I don't really even care about the content of these videos lol I just was bored and wanted a project.
    Quote Quote  
  25. @Iridule:

    I think you need to be more clear about what you're trying to achieve. If you keep masking every URL, no one will be able to give specific advice.

    Here's some general advice:

    1. The license will be a POST request(method:POST) and very rarely does the URL need to be manipulated. "?specConform=true" is only a feature for drmtoday, not something you add to any license.

    2. Using tools like httptoolkit is complete overkill unless monitoring traffic from a second device. Dev tools will give you everything you need. Don't overcomplicate things in the beginning.

    3. What headers are needed for what sites come with experience and experimenting. But as a general rule, if there's a token of some kind, that is typically the only header that should be used. They are often time-sensitive and sometimes even IP-restricted. Many sites only need generic ones, though, if any is required at all.

    4. If there's extra payload in the Payload tab of the license, that means you'll need to customize your script to handle the request in json format. This will require basic Python knowledge and some understanding of how the pywidevine module works in order to properly send a license request and parsing the response.
    Quote Quote  
  26. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by stabbedbybrick View Post
    @Iridule:

    I think you need to be more clear about what you're trying to achieve. If you keep masking every URL, no one will be able to give specific advice.

    Here's some general advice:

    1. The license will be a POST request(method:POST) and very rarely does the URL need to be manipulated. "?specConform=true" is only a feature for drmtoday, not something you add to any license.

    2. Using tools like httptoolkit is complete overkill unless monitoring traffic from a second device. Dev tools will give you everything you need. Don't overcomplicate things in the beginning.

    3. What headers are needed for what sites come with experience and experimenting. But as a general rule, if there's a token of some kind, that is typically the only header that should be used. They are often time-sensitive and sometimes even IP-restricted. Many sites only need generic ones, though, if any is required at all.

    4. If there's extra payload in the Payload tab of the license, that means you'll need to customize your script to handle the request in json format. This will require basic Python knowledge and some understanding of how the pywidevine module works in order to properly send a license request and parsing the response.
    Excellent answer.
    Quote Quote  
  27. Member
    Join Date
    May 2023
    Location
    United States
    Search Comp PM
    I'm thinking it's the json problem which if that's the case I don't have any programming knowledge. If it is a headers issue I guess I'm doing something wrong I can get the encrypted strain by downloading the MPD using stream detector and sending it to N_m3u8DL-RE. So I assume that same MPD is the headers I need? Although when I try to view it in the developer menu it shows up as an ad. I found the license by typing ott in the developer menu. That's one reason I like using HTTP tool kit it was much easier to find the license I just had to type license. I'll spend a few more days. I've already spent about 4 days on this project from morning to night I guess I'll keep trying I'll check for payload and json if it's there I guess I'll try a different site.
    Quote Quote  
  28. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by Iridule View Post
    I'm thinking it's the json problem which if that's the case I don't have any programming knowledge. If it is a headers issue I guess I'm doing something wrong I can get the encrypted strain by downloading the MPD using stream detector and sending it to N_m3u8DL-RE. So I assume that same MPD is the headers I need? Although when I try to view it in the developer menu it shows up as an ad. I found the license by typing ott in the developer menu. That's one reason I like using HTTP tool kit it was much easier to find the license I just had to type license. I'll spend a few more days. I guess I'll keep trying I'll check for payload and json if it's there I guess I'll try a different site.
    Observations:
    1. Eventually when you are fully proficient you will be able to download almost everything but you'll watch almost nothing.
    2. Are you telling me that you've come through the US Education System without finding out how to program? If you can read you can program.
    3. No-one can help if you do not give a video link. If you are unable to give a video link because it is a pay site, then you shouldn't be asking - Hairless-Richard gets upset if you do.
    I'm thinking it's the json problem
    You should know. Does httpToolkit show a json exchange?
    So I assume that same MPD is the headers I need?
    You assume wrong. Licence headers are to get the license from the license server - not the same as the mpd server - look at the URLs. It is not usual for the mpd to need headers, but some might. Widevine makes getting the license hard, and the mpd -> video easy, because, without the license, downloading an encrypted video will be useless to you.
    Although when I try to view it in the developer menu it shows up as an ad.
    Wait to do your data collecting until the video plays and adverts stop.
    I've already spent about 4 days on this project from morning to night
    Is that all? Sit on it; think about it. It is a thoughtful process not one to hack at. And from the wrong assumptions you are so readily making it might be a good idea to go back and read over the stuff you thought helpful, and get the facts clear in your mind. It is not easy for the first few attempts; start off on easy sites - is the general recommendation.
    Quote Quote  
  29. Member
    Join Date
    May 2023
    Location
    United States
    Search Comp PM
    Are you telling me that you've come through the US Education System without finding out how to program?
    I dropped out of school in 9th grade maybe that's the problem ... Well I won't give up just yet (it did take me 45 hours to learn to compile linux kernel and I was about to give up yet here I am...) I have had success with bitmovin and tg4.ie
    I am 98% sure I have the correct PSSH and Lic URL...I'll keep studying the site patterns and re read the forum posts which I was doing in bed at 4am One question I do have specifics for is since my phone is l1 should I magisk module to force l3 or are my CDM dumps correct since they worked with those two test sites?

    also regarding
    4. If there's extra payload in the Payload tab of the license, that means you'll need to customize your script to handle the request in json format. This will require basic Python knowledge and some understanding of how the pywidevine module works in order to properly send a license request and parsing the response.
    There is data in the response tab of the license beside response payload. Which script would I need to customize? l3.py?
    Last edited by Iridule; 10th May 2023 at 11:16.
    Quote Quote  
  30. Member
    Join Date
    May 2023
    Location
    United States
    Search Comp PM
    so an update. I can't seem to get the proper audio. /N_m3u8DL-RE shows many audio options they all look identical, however each one seems garbled and even after decryption trying to merge with ffmpegI get AAC bitstream and incorrect timestamp errors. Video plays fine however audio shows correct length but only plays a few seconds then is garbled more.

    UPDATE#2. I got all the audio files but they all have time lengths that are not accurate for example lets say they all show 45 minutes in vlc yet the first one is 12 minutes long the second starts where that one ends and so on until the end of the video and there are 4 separate files. What is the best way to join them along with the video? I was only able to get these properly with yt-dlp -f which was a pain because I had to rename each of them. Guess it was a good day I got the key and decrypted the video & audio now if I can only figure how to join them.
    Image
    [Attachment 70927 - Click to enlarge]
    Last edited by Iridule; 10th May 2023 at 21:34.
    Quote Quote  



Similar Threads

Visit our sponsor! Try DVDFab and backup Blu-rays!