VideoHelp Forum
+ Reply to Thread
Results 1 to 18 of 18
Thread
  1. Code:
    import requests
    import re 
    import os
    
    ## 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',
    }
    
    def get_pssh_lic(mpd_url):
        pssh = None
        lic_url = None
    
        mpd = requests.get(mpd_url, headers).text
        lines = mpd.split("\n")
        print(f"MPD Request Response:\n{mpd}") #Debug to manually inspect MPD
        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
    
    if __name__ == "__main__":
    
        #mpd_url = "https://manifest-viki.viki.io/v1/1197630v/limelight/main/mpd/normal/viki/high/hd/ww/dt2_dt3/manifest.mpd?h_host=playback-streams-7bcb9d6669-9zj4m&h_timestamp=1690468718&tag=mpdhd%3Ahigh%3Aww%3AsourceVIKI%3Ampd%3Acached%3Adt2_dt3&app=100000a&u=79387002u&h_country=us&token=ex1OE4EXVURPIJVKLLKA3IDIWUXBJEYA_2u0079387002uti00n7r2oO100000_djA0&h_data_center=iowa-2&sig=1c10784a884526bfeb929e8dc61b99e502b5df99"
        mpd_url = "https://www.viki.com/videos/1080865v-nirvana-in-fire-episode-1"
        pssh,lic_url = get_pssh_lic(mpd_url)
        print(f"pssh: {pssh}")
        print(f"lic_url: {lic_url}")
    I extracted a portion of Angela's script from another post that I lost track of now to achieve what Im looking for. I want to be able to send a request to the url and retrieve the pssh/license url. I'm not doing this correctly, please help.
    Quote Quote  
  2. Search, Learn, Download! Karoolus's Avatar
    Join Date
    Oct 2022
    Location
    Belgium
    Search Comp PM
    Your MPD URL does not look like an MPD but just a regular video url.
    Quote Quote  
  3. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    You won't get a license like that unfortunately. The script you've copied is for an unusual case where the site's mpd contains the license link as well as the pssh.
    Normally the mpd will give the pssh and you have to find other ways to get a the license.

    Good that you are trying though

    Maybe start inputting the mpd and the license. Extract the pssh. Get the key. Have the the script download. You will also need a filename. You could stop for input. Or you could use stream detector table entry -parse that for videoname as well as mpd.

    Good luck.
    Quote Quote  
  4. Thanks, I did use an accurate mpd and was able to retrieve the pssh but yeah did not see the license in there as you indicated. I have limited programming knowledge and have only learned Python a few weeks ago. I did semi automate the process by having selenium do all the clicking and saving the network har's file for me along with the pssh from tamper monkey's eme logger. It's faster than doing it alone but not an ideal solution.

    Still searching but so far I only come across ways to get keys but nothing regarding python ways to capture license url/pssh. The keys itself is more simple after getting approval for getkeys.cc and its api (at least it's easy for my need which is viki.) My search phrases for the license url/pssh automation are probably not worded correctly or something? Either that or people are that secretive about it. Was hoping I could get an advice or tips on what I can use.
    Quote Quote  
  5. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by InfinitiX2 View Post
    ..... ways to capture license url/pssh. The keys itself is more simple after getting approval for getkeys.cc and its api (at least it's easy for my need which is viki.) My search phrases for the license url/pssh automation are probably not worded correctly or something? Either that or people are that secretive about it. Was hoping I could get an advice or tips on what I can use.
    httptoolkit will allow you to see the interactions as the web page loads, more readily than using 'developer options' in a browser. The text string used for filtering for license varies, but it will be a method=POST request. In httptoolkit set a that as a filter and watch interactions.

    Finding the licence by program can be difficult and time consuming and there isn't a one-size-fits-all solution.
    I have found four styles.
    1. The licence carries a unique identifier which cannot be guessed or constructed from data already known. The most difficult (TogetherTV)
    2. The licence is formulaic. So from data already given the licence may be readily constructed. (ITVX)
    3. The licence is always is the same for all videos over the whole site (bitmovin)
    4. The licence is inside the mpd. (STV)
    There may be others but that is all I've seen.

    Now, as a web page loads it is not a single event. The browser goes on to download other things as a whole 'bundle - javascript and json'. And it may not do it at the start - it may wait until you activate the video-player before it requests a licence and everything else to prepare to play the video. It is all these interactions that must contain information to find the license url.

    In a way you are a detective searching for clues; Look for POSTs to locate the licence ( check responses to be sure) then you know earlier interactions will have provided the URL - it may be in obfuscated javascript that the browser uses to 'construct' the url - I haven't found ways round that - yet. It may be a json package that is returned from an earlier request. Use httptoolkit and filter for json - look in and read all the json responses. Then your task is to find a way to request the page with the json packet and parse it for the licence.

    That is a start. Remember it is a slow, thoughtful and deliberate process. Hacking around won't do it. While you are consolidating your skills do not be too proud to use 'hybrid' methods - where you automate as much as you can, with the knowledge you have, and input other bits by hand.

    I wouldn't be planning on using any key getting site by this stage; having your own CDM is easy now. Constructing a get keys method in python is also easy; just follow l3.py or one of my scripts.

    Just learning python? - that was me about 18 months ago and I'm still leaning.

    This will be of use if you haven't already studied it https://forum.videohelp.com/threads/407216-Decryption-The-Dungeon-of-Despair

    Good luck.
    Last edited by A_n_g_e_l_a; 28th Jul 2023 at 06:27. Reason: spelling
    Quote Quote  
  6. As an addition to A_n_g_e_l_a's already excellent post: Whenever you're trying to fetch the license and PSSH programatically, you'll in most cases need to go through the API of the service. The API handles all data in regards to series, episodes, movies among other things. Investigating the calls made in Dev Tools or httpToolkit or similar, you can almost always locate the one that holds all the data.

    After a quick search, I found one way to get the episodic data is through "https://www.viki.com/api/videos/{video_id}".

    You'll send a GET request to it with the correct headers and get back all relevant data:

    Code:
    "streams":{
          "dash":{
             "type":"application/dash+xml",
             "url":"https://0.viki.io/b/e-stream-url?stream=aHR0cHM6Ly(shortened)"
          }
       }
    
    "drm":"eyJkdDEiOiJodHRwc(shortened)
    Parse the "stream= " and "drm":" " and you'll have both MPD and license, with correct signatures and everything. You can get the PSSH by parsing the MPD, creating one from the KID, or by reading the init. That's up to you.

    That should be a good start for you to build on.
    Quote Quote  
  7. Member
    Join Date
    Feb 2022
    Location
    Search the forum first!
    Search PM
    Originally Posted by stabbedbybrick View Post

    That should be a good start for you to build on.
    An excellent start, I would say. You've almost left no work to do!
    Quote Quote  
  8. Nah, there's plenty of work to be done. Finding the API data takes a couple of minutes. Actually writing a fully working script is what's going to give them a headache
    Quote Quote  
  9. Thank you guys, I will be looking at httptoolkit and stabbedbybrick's advice and report back.
    Quote Quote  
  10. httptoolkit was helpful in intercepting and providing me with the data I needed to figure out the correct header. I was able to send it to the api, parse+mock some data I needed and generated a valid license url to get the correct key. I'm still struggling a little bit with the PSSH. I have the KID, i dont know what "drm" data is, it is quite long.
    Quote Quote  
  11. Originally Posted by InfinitiX2 View Post
    httptoolkit was helpful in intercepting and providing me with the data I needed to figure out the correct header. I was able to send it to the api, parse+mock some data I needed and generated a valid license url to get the correct key. I'm still struggling a little bit with the PSSH. I have the KID, i dont know what "drm" data is, it is quite long.
    I take that back, I did not generate the correct license_url, the key returned was from a cache.
    Quote Quote  
  12. Reading Angela’s dungeon of despair now, it’s giving me a lot of good info, just need to process it. This is exciting. Will not have much time on the weekend bc of family duties but will find some time to read more. Thanks guys
    Quote Quote  
  13. As general advice, I'd recommend using the dev tools in your browser when dealing with browser-based services. It's much easier to get an overview and trace the calls. HttpToolkit is a better fit for when intercepting traffic from devices.

    Originally Posted by InfinitiX2
    I was able to send it to the api, parse+mock some data I needed and generated a valid license url to get the correct key. I'm still struggling a little bit with the PSSH. I have the KID, i dont know what "drm" data is, it is quite long.
    The drm string is what's known as a JSON web token and you''ll find the license inside. It's essentially another base64 string but with a different structure.

    As for PSSH, there are several ways to go about it. If it's already stated inside the MPD, you could simply parse it and use regex to extract it. The most "robust" way of getting it would be through the initialization, since you can be 100% sure it'll be correct.
    Quote Quote  
  14. Originally Posted by stabbedbybrick View Post
    As general advice, I'd recommend using the dev tools in your browser when dealing with browser-based services. It's much easier to get an overview and trace the calls. HttpToolkit is a better fit for when intercepting traffic from devices.

    Originally Posted by InfinitiX2
    I was able to send it to the api, parse+mock some data I needed and generated a valid license url to get the correct key. I'm still struggling a little bit with the PSSH. I have the KID, i dont know what "drm" data is, it is quite long.
    The drm string is what's known as a JSON web token and you''ll find the license inside. It's essentially another base64 string but with a different structure.

    As for PSSH, there are several ways to go about it. If it's already stated inside the MPD, you could simply parse it and use regex to extract it. The most "robust" way of getting it would be through the initialization, since you can be 100% sure it'll be correct.
    Thanks for your help, I finally understand what you're saying about drm now and was able to decode it with the base64 python library and found the license inside it. This has been a big step for me to be able to send the correct request/header and getting the data back.

    Still trying to figure out the init data, I can see thats what the eme logger tamper monkey script is also doing but is that a totally different url/data than the episode's api?
    Last edited by InfinitiX2; 29th Jul 2023 at 13:25.
    Quote Quote  
  15. Originally Posted by stabbedbybrick View Post
    As an addition to A_n_g_e_l_a's already excellent post: Whenever you're trying to fetch the license and PSSH programatically, you'll in most cases need to go through the API of the service. The API handles all data in regards to series, episodes, movies among other things. Investigating the calls made in Dev Tools or httpToolkit or similar, you can almost always locate the one that holds all the data.

    After a quick search, I found one way to get the episodic data is through "https://www.viki.com/api/videos/{video_id}".

    You'll send a GET request to it with the correct headers and get back all relevant data:

    Code:
    "streams":{
          "dash":{
             "type":"application/dash+xml",
             "url":"https://0.viki.io/b/e-stream-url?stream=aHR0cHM6Ly(shortened)"
          }
       }
    
    "drm":"eyJkdDEiOiJodHRwc(shortened)
    Parse the "stream= " and "drm":" " and you'll have both MPD and license, with correct signatures and everything. You can get the PSSH by parsing the MPD, creating one from the KID, or by reading the init. That's up to you.

    That should be a good start for you to build on.
    Lets use video_id 1080865v as an example. I got

    'streams': {'dash': {'type': 'application/dash+xml', 'url': 'https://0.viki.io/b/e-stream-url?stream=aHR0cHM6Ly9tLWNvbnRlbnQzLXZpa2kucy5sbG5 3aS5uZXQvMTE5MzEyOXYvZGFzaC9tcGRoZF8zMTU5OWVfMjIxM DA2MDg1My5tcGQ='}}

    that url doesn't seem to be a valid mpd url?
    Quote Quote  
  16. Originally Posted by InfinitiX2 View Post
    Originally Posted by stabbedbybrick View Post
    As an addition to A_n_g_e_l_a's already excellent post: Whenever you're trying to fetch the license and PSSH programatically, you'll in most cases need to go through the API of the service. The API handles all data in regards to series, episodes, movies among other things. Investigating the calls made in Dev Tools or httpToolkit or similar, you can almost always locate the one that holds all the data.

    After a quick search, I found one way to get the episodic data is through "https://www.viki.com/api/videos/{video_id}".

    You'll send a GET request to it with the correct headers and get back all relevant data:

    Code:
    "streams":{
          "dash":{
             "type":"application/dash+xml",
             "url":"https://0.viki.io/b/e-stream-url?stream=aHR0cHM6Ly(shortened)"
          }
       }
    
    "drm":"eyJkdDEiOiJodHRwc(shortened)
    Parse the "stream= " and "drm":" " and you'll have both MPD and license, with correct signatures and everything. You can get the PSSH by parsing the MPD, creating one from the KID, or by reading the init. That's up to you.

    That should be a good start for you to build on.
    Lets use video_id 1080865v as an example. I got

    'streams': {'dash': {'type': 'application/dash+xml', 'url': 'https://0.viki.io/b/e-stream-url?stream=aHR0cHM6Ly9tLWNvbnRlbnQzLXZpa2kucy5sbG5 3aS5uZXQvMTE5MzEyOXYvZGFzaC9tcGRoZF8zMTU5OWVfMjIxM DA2MDg1My5tcGQ='}}

    that url doesn't seem to be a valid mpd url?

    Decode Base64


    Code:
    aHR0cHM6Ly9tLWNvbnRlbnQzLXZpa2kucy5sbG53aS5uZXQvMTE5MzEyOXYvZGFzaC9tcGRoZF8zMTU5OWVfMjIxMDA2MDg1My5tcGQ=

    Output:

    Quote Quote  
  17. Originally Posted by zackmark29 View Post
    Originally Posted by InfinitiX2 View Post
    Originally Posted by stabbedbybrick View Post
    As an addition to A_n_g_e_l_a's already excellent post: Whenever you're trying to fetch the license and PSSH programatically, you'll in most cases need to go through the API of the service. The API handles all data in regards to series, episodes, movies among other things. Investigating the calls made in Dev Tools or httpToolkit or similar, you can almost always locate the one that holds all the data.

    After a quick search, I found one way to get the episodic data is through "https://www.viki.com/api/videos/{video_id}".

    You'll send a GET request to it with the correct headers and get back all relevant data:

    Code:
    "streams":{
          "dash":{
             "type":"application/dash+xml",
             "url":"https://0.viki.io/b/e-stream-url?stream=aHR0cHM6Ly(shortened)"
          }
       }
    
    "drm":"eyJkdDEiOiJodHRwc(shortened)
    Parse the "stream= " and "drm":" " and you'll have both MPD and license, with correct signatures and everything. You can get the PSSH by parsing the MPD, creating one from the KID, or by reading the init. That's up to you.

    That should be a good start for you to build on.
    Lets use video_id 1080865v as an example. I got

    'streams': {'dash': {'type': 'application/dash+xml', 'url': 'https://0.viki.io/b/e-stream-url?stream=aHR0cHM6Ly9tLWNvbnRlbnQzLXZpa2kucy5sbG5 3aS5uZXQvMTE5MzEyOXYvZGFzaC9tcGRoZF8zMTU5OWVfMjIxM DA2MDg1My5tcGQ='}}

    that url doesn't seem to be a valid mpd url?

    Decode Base64


    Code:
    aHR0cHM6Ly9tLWNvbnRlbnQzLXZpa2kucy5sbG53aS5uZXQvMTE5MzEyOXYvZGFzaC9tcGRoZF8zMTU5OWVfMjIxMDA2MDg1My5tcGQ=

    Output:

    Thank you zack, thought that was an actual url and didnt extract the base64 to decode.
    Quote Quote  
  18. Thank you, you guys are awesome!
    Quote Quote  



Similar Threads

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