VideoHelp Forum
+ Reply to Thread
Results 1 to 14 of 14
Thread
  1. Hi , I am trying to stream tv channels from nydus.org with exoplayer or vlc , however streams are encrypted strongly , I tried do it with AES-128 decryptor but not success . can someone help me to do this?
    Last edited by mohi1980; 30th Sep 2024 at 07:14.
    Quote Quote  
  2. Feels Good Man 2nHxWW6GkN1l916N3ayz8HQoi's Avatar
    Join Date
    Jan 2024
    Location
    Pepe Island
    Search Comp PM
    Video URL?
    --[----->+<]>.++++++++++++.---.--------.
    [*drm mass downloader: widefrog*]~~~[*how to make your own mass downloader: guide*]
    Quote Quote  
  3. Feels Good Man 2nHxWW6GkN1l916N3ayz8HQoi's Avatar
    Join Date
    Jan 2024
    Location
    Pepe Island
    Search Comp PM
    I have no idea. This looks interesting
    --[----->+<]>.++++++++++++.---.--------.
    [*drm mass downloader: widefrog*]~~~[*how to make your own mass downloader: guide*]
    Quote Quote  
  4. Member aqzs's Avatar
    Join Date
    Mar 2024
    Location
    Paris
    Search Comp PM
    Originally Posted by 2nHxWW6GkN1l916N3ayz8HQoi View Post
    I have no idea. This looks interesting
    Indeed, stream does't seems to be encrypted but I can't download using N_m3u8DL-RE or play it using shaka or jwplayer.
    I never dealt with Clappr before, I used source code from their js to get the exact configuration and setup a proxy but couldn't get playback working, I'm may be missing something..
    Quote Quote  
  5. Feels Good Man 2nHxWW6GkN1l916N3ayz8HQoi's Avatar
    Join Date
    Jan 2024
    Location
    Pepe Island
    Search Comp PM
    Originally Posted by aqzs View Post
    I'm may be missing something
    https://s5.tv24livestream.de/clappr.newZ2.min.js

    Code:
    e.loadsuccess = function(t, e, r, i) {
                                void 0 === i && (i = null);
                                var n = t.data
                                  , a = r.frag;
                                a.loader = void 0,
                                this.loaders[a.type] = void 0,
                                this.hls.trigger(x.default.FRAG_LOADED, {
                                    payload: n,
                                    frag: a,
                                    stats: e,
                                    networkDetails: i
                                })
                            }
    If you inject code there to download locally just 1 random fragment from the t.data variable, it plays fine in VLC. Which may imply that for some fragment, from the moment of its browser request, up to that indicated line of code, some editing steps are applied to it. Either decrypting, or decoding, no idea.
    --[----->+<]>.++++++++++++.---.--------.
    [*drm mass downloader: widefrog*]~~~[*how to make your own mass downloader: guide*]
    Quote Quote  
  6. it's not as complicated as you might have thought:
    Code:
    file = "mysqlcrypt-backup-134519-3694.tsl.csv"
        
    with open(file + ".ts", "wb") as writer:
        with open(file, "r") as reader:
            for line in reversed(reader.readlines()):
                if line == "secret,crypt,key,a,b,c,d,e,f":
                    continue
                lines = reversed(line.split(","))
                writer.write(base64.b64decode(''.join(lines)))
    https://github.com/DevLARLEY
    Keys from just the License URL: WidevineFetch
    Quote Quote  
  7. Feels Good Man 2nHxWW6GkN1l916N3ayz8HQoi's Avatar
    Join Date
    Jan 2024
    Location
    Pepe Island
    Search Comp PM
    Nice job @larley. So the fragments are indeed modified. I suppose it could work with streamlink to be streamed to VLC using custom plugins/addons
    By the way, how would you handle fragments like this?
    https://s5.sql24backup.de/conv/go/rtl1/mysqlcrypt-backup-134519-3774.tsl.bmp

    Edit: take a fresh csv fragment URL and edit to bmp
    --[----->+<]>.++++++++++++.---.--------.
    [*drm mass downloader: widefrog*]~~~[*how to make your own mass downloader: guide*]
    Quote Quote  
  8. I'm getting a 404 on that ...
    I'll try to add the "decoding" to a version of N_m3u8DL-RE (as I always do)
    https://github.com/DevLARLEY
    Keys from just the License URL: WidevineFetch
    Quote Quote  
  9. Feels Good Man 2nHxWW6GkN1l916N3ayz8HQoi's Avatar
    Join Date
    Jan 2024
    Location
    Pepe Island
    Search Comp PM
    I added an edit to my previous comment. Basically replace csv with bmp. I think streamlink addon might be better for what OP wants cause you can't use N_m3u8DL-RE for vlc streaming, only downloading. But that's up to you.

    You should really publish a tutorial one day for how to add custom decoders to N_m3u8DL-RE, kinda like what you did with wingfox extension.
    --[----->+<]>.++++++++++++.---.--------.
    [*drm mass downloader: widefrog*]~~~[*how to make your own mass downloader: guide*]
    Quote Quote  
  10. the .bmp version simple has heck, it just stores the video as hex:
    Code:
    file = "mysqlcrypt-backup-134519-3907.tsl.bmp"
    
    with open(file + ".ts", "wb") as writer:
        video = open(file, "r").read()[54:]
        writer.write(bytes.fromhex(video))
    I'll create a tutorial for N_m3u8DL-RE if I have the time. I won't do streamlink because I don't want to learn the inner workings of yet another downloader. I just don't have the time for that.
    https://github.com/DevLARLEY
    Keys from just the License URL: WidevineFetch
    Quote Quote  
  11. Feels Good Man 2nHxWW6GkN1l916N3ayz8HQoi's Avatar
    Join Date
    Jan 2024
    Location
    Pepe Island
    Search Comp PM
    Nice. I asked about the bmp because when I first looked, the stream only loaded fragments of this kind. So it probably has a rotation mechanism as well with at least 2 fragment types that we know of.

    Thanks for taking into consideration the tutorial. Of course one day in the future when you have time. It'd be nice to know the basic steps for adding decoders.
    --[----->+<]>.++++++++++++.---.--------.
    [*drm mass downloader: widefrog*]~~~[*how to make your own mass downloader: guide*]
    Quote Quote  
  12. Member aqzs's Avatar
    Join Date
    Mar 2024
    Location
    Paris
    Search Comp PM
    Nice !! Great job @Larley !
    As Pepe said it would be nice when you have time to make a short tutorial on how to add parser/decoder to N_m3u8DL-RE ! I don't know C# though
    Quote Quote  
  13. Feels Good Man 2nHxWW6GkN1l916N3ayz8HQoi's Avatar
    Join Date
    Jan 2024
    Location
    Pepe Island
    Search Comp PM
    This isn't meant as a solution. Was more of a challenge to prove base streamlink can be used without any addons/plugins for VLC streaming with no downloading

    Code:
    import base64
    import re
    import sys
    import urllib
    from urllib.parse import urljoin, urlparse
    
    import m3u8
    from bs4 import BeautifulSoup
    from curl_cffi import requests as requests_cf
    from flask import Flask, request
    
    app = Flask(__name__)
    
    MASTER_M3U8_URL = None
    LOCAL_PORT = 5432
    LOCAL_URL = f"http://127.0.0.1:{LOCAL_PORT}"
    IMPERSONATE = "chrome120"
    
    
    def clean_url(url):
        return url.split("?")[0].split("#")[0].rstrip("/")
    
    
    def get_base_url(url):
        parsed_url = urlparse(url)
        base_url = f"{parsed_url.scheme}://{parsed_url.netloc}"
        return base_url
    
    
    def modify_m3u8(origin_url, endpoint):
        m3u8_content = requests_cf.get(origin_url, impersonate=IMPERSONATE).content.decode()
        base_url = clean_url(origin_url).split("/")
        del base_url[-1]
        base_url = "/".join(base_url)
    
        m3u8_content = m3u8.loads(m3u8_content)
        for segment in m3u8_content.playlists + m3u8_content.media + m3u8_content.segments:
            if not segment.uri.startswith("http"):
                if segment.uri.startswith("/"):
                    segment.uri = ".." + segment.uri
    
                dots = segment.uri.count("../")
                temp_base_url = base_url.split("/")
                temp_base_url = temp_base_url[0:len(temp_base_url) - dots]
                temp_base_url = "/".join(temp_base_url)
    
                segment.uri = segment.uri.replace("../", "")
                if not segment.uri.startswith("/"):
                    segment.uri = "/" + segment.uri
                segment.uri = temp_base_url + segment.uri
                segment.uri = f"{LOCAL_URL}/{endpoint}?url=" + urllib.parse.quote(segment.uri)
    
        return m3u8_content.dumps()
    
    
    @app.route('/master.m3u8')
    def serve_master_m3u8():
        m3u8_content = modify_m3u8(MASTER_M3U8_URL, "playlist.m3u8")
        return m3u8_content, 200
    
    
    @app.route('/playlist.m3u8')
    def serve_playlist():
        playlist_url = request.args.get('url')
        m3u8_content = modify_m3u8(playlist_url, "fragment.ts")
        return m3u8_content, 200
    
    
    def custom_fragment_edit(fragment_url):
        fragment_url = fragment_url.split(".")
        del fragment_url[-1]
        fragment_url = ".".join(fragment_url)
        fragment_url += ".json"
        fragment_content = requests_cf.get(fragment_url, impersonate=IMPERSONATE).content
        return fragment_content
    
    
    @app.route('/fragment.ts')
    def serve_fragment():
        fragment_url = request.args.get('url')
        fragment_content = custom_fragment_edit(fragment_url)
        return fragment_content, 200
    
    
    def extract_b64_str(page_content, regex):
        b64_str = re.findall(regex, page_content)
        b64_str = sorted(b64_str, key=len, reverse=True)[0]
        b64_str = base64.b64decode(str(b64_str))
        b64_str = b64_str.decode()
        return b64_str
    
    
    def get_master_m3u8_url(live_url):
        response = requests_cf.get(live_url, impersonate=IMPERSONATE).content.decode()
        b64_str = extract_b64_str(response, r'"([^"]+)"')
        soup = BeautifulSoup(b64_str, 'html5lib')
        iframe_nodes = soup.find_all('iframe', attrs={
            'id': 'player',
            'src': True
        })
        embed_url = iframe_nodes[0]["src"]
        response = requests_cf.get(embed_url, impersonate=IMPERSONATE).content.decode()
        embed_url = extract_b64_str(response, r'= "([^"]+)";')
    
        embed_url = extract_b64_str(embed_url, r"'([^']+)'")
        base_url = get_base_url(embed_url)
        response = requests_cf.get(embed_url, impersonate=IMPERSONATE).content.decode()
    
        b64_str = extract_b64_str(response, r'= "([^"]+)";')
        b64_str = extract_b64_str(b64_str, r"'([^']+)'")
    
        if b64_str[0] != "/":
            b64_str = "/" + b64_str
        master_m3u8_url = base_url + b64_str
        return master_m3u8_url
    
    
    if __name__ == '__main__':
        if len(sys.argv) < 2:
            exit("input url needed")
    
        input_url = sys.argv[1]
        if "/stream/live/" in input_url:
            MASTER_M3U8_URL = get_master_m3u8_url(input_url)
        elif "/conv/conv.php" in input_url:
            MASTER_M3U8_URL = input_url
        else:
            exit("bad url")
    
        print(f'\n-->> streamlink "{LOCAL_URL}/master.m3u8" best <<--\n')
        app.run(debug=True, port=LOCAL_PORT)
    Usage, input page URL or conv.php (the master.m3u8 equivalent of their site)
    Code:
    python host.py "https://nydus.org/stream/live/rtl/"
    python host.py "https://s5.mysqlcryptnow.de/conv/conv.php?start=1&p=sat1-gold"
    python host.py "https://nydus.org/stream/live/rtl-nitro/"
    Code:
    streamlink "http://127.0.0.1:5432/master.m3u8" best
    Image
    [Attachment 82570 - Click to enlarge]

    Image
    [Attachment 82571 - Click to enlarge]

    Image
    [Attachment 82572 - Click to enlarge]


    The fragment URLs are edited to point directly to their unaltered ts content.
    --[----->+<]>.++++++++++++.---.--------.
    [*drm mass downloader: widefrog*]~~~[*how to make your own mass downloader: guide*]
    Quote Quote  



Similar Threads

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