VideoHelp Forum





Try StreamFab Downloader and download streaming video from Netflix, Amazon!



+ Reply to Thread
Results 1 to 5 of 5
  1. Hello,
    i'm trying to download a videos from guruflix.biz that uses anti scrape by cloudflare. The page loads a file called drm.js and a wasm component. The manifest of .m3u8 is able to download only if you include the correct headers and cookies by cloudflare. The chunk in the playlist can be downloaded without this but are encripted. The .m3u8 says AES-128 but i think that the videos doesnt exist in .ts format

    for every chunck from the playlist the cdn response with something that seems base64 encoded, maybe a token for single fragment or info/key for the wasm.

    in drm.js i've found a function that calculate a key from my email and one of x-ray headers token but the key is too long for aes128

    i've have tried to inject the attached js code but after tests... i can only get the audio in the right sequence and the correct mpg header not the video


    i've run out of ideas and i need your help -_-"
    Image Attached Thumbnails Click image for larger version

Name:	Screenshot 2026-06-16 100942.png
Views:	36
Size:	55.1 KB
ID:	92727  

    Image Attached Files
    Quote Quote  
  2. nobody can help me ?
    Quote Quote  
  3. Originally Posted by sant0 View Post
    nobody can help me ?
    The website is either subscription or rental - so no one can help you without you supplying a login, and without one or the other no one can examine the API to see how its functioning.

    Plus, discussion of paid sites is against forum rules anyway.
    Quote Quote  
  4. I tried one course myself and it's using widevine for me
    Bypass HMACs, One-time-tokens and Lic.Wrapping: https://github.com/DevLARLEY/WidevineProxy2
    Quote Quote  
  5. Hello, I had a Python script to download a video from an Italian website using Cloudflare. I did it like this:

    Code:
    import re
    import base64
    import requests
    from Crypto.Cipher import AES
    from pathlib import Path
    import subprocess
    import time
    import sys
    
    # ==================================
    # SANITIZE INPUTS (fix unicode issues)
    # ==================================
    def sanitize(s: str) -> str:
        return s.replace("…", "").encode("utf-8", "ignore").decode("utf-8")
    
    # ==================================
    # CONFIG
    # ==================================
    M3U8_URL = input("Playlist URL or local m3u8 file: ").strip()
    
    TIMEOUT = 20
    MAX_RETRIES = 15
    DELAY_BETWEEN_SEGMENTS = 2.5
    
    SESSION_COOKIE = sanitize(input("PASTE_COOKIE : ").strip())
    Fingerprint = sanitize(input("PASTE_X-Fingerprint : ").strip())
    Token = sanitize(input("PASTE_X-Turnstile-Token : ").strip())
    
    OUT_DIR = Path("segments")
    OUT_DIR.mkdir(exist_ok=True)
    
    # ==================================
    # SESSION
    # ==================================
    session = requests.Session()
    session.headers.update({
        "Cookie": SESSION_COOKIE,
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
        "Referer": "https://guruflix.io/",
        "Origin": "https://guruflix.io",
        "X-Fingerprint": Fingerprint,
        "X-Turnstile-Token": Token,
    })
    
    # ==================================
    # UTILS
    # ==================================
    def unpad_pkcs7(data: bytes) -> bytes:
        pad = data[-1]
        if 1 <= pad <= 16:
            return data[:-pad]
        return data
    
    # ==================================
    # LOAD PLAYLIST
    # ==================================
    print("[+] Loading playlist")
    
    if M3U8_URL.startswith("http"):
        r = session.get(M3U8_URL, timeout=TIMEOUT)
        r.raise_for_status()
        lines = r.text.splitlines()
    else:
        lines = Path(M3U8_URL).read_text(encoding="utf-8").splitlines()
    
    # ==================================
    # PARSE PLAYLIST
    # ==================================
    segments = []
    next_key = None
    next_iv = None
    index = 0
    
    for line in lines:
        line = line.strip()
    
        if "EXT-X-KEY" in line:
            key_match = re.search(r'URI="key:([^"]+)"', line)
            iv_match  = re.search(r'IV=0x([0-9a-fA-F]+)', line)
    
            if not key_match or not iv_match:
                raise ValueError("Invalid EXT-X-KEY")
    
            next_key = base64.b64decode(key_match.group(1))
            next_iv  = bytes.fromhex(iv_match.group(1).zfill(32))
            continue
    
        if line.startswith("http"):
            if next_key is None or next_iv is None:
                raise ValueError(f"No key for segment {index}")
    
            segments.append({
                "index": index,
                "url": line,
                "key": next_key,
                "iv": next_iv,
            })
    
            next_key = None
            next_iv = None
            index += 1
    
    print(f"[+] {len(segments)} segments found")
    
    # ==================================
    # DOWNLOAD + DECRYPT
    # ==================================
    print("[+] Downloading segments (stable mode)")
    
    for seg in segments:
        idx = seg["index"]
        out_file = OUT_DIR / f"{idx:05d}.ts"
    
        if out_file.exists() and out_file.stat().st_size > 188:
            print(f"[→] Segment {idx} already exists, skipping")
            continue
    
        for attempt in range(1, MAX_RETRIES + 1):
            try:
                r = session.get(seg["url"], timeout=TIMEOUT)
                if r.status_code != 200:
                    raise RuntimeError(f"HTTP {r.status_code}")
    
                cipher = AES.new(seg["key"], AES.MODE_CBC, seg["iv"])
                decrypted = unpad_pkcs7(cipher.decrypt(r.content))
                out_file.write_bytes(decrypted)
                print(f"[✓] Segment {idx} OK")
                break
    
            except Exception as e:
                print(f"[!] Segment {idx} failed ({attempt}/{MAX_RETRIES}) → {e}")
                time.sleep(4)
    
        else:
            print(f"❌ Segment {idx} abandoned")
            sys.exit(1)
    
        time.sleep(DELAY_BETWEEN_SEGMENTS)
    
    print("✅ All segments downloaded")
    
    # ==================================
    # MERGE
    # ==================================
    print("[+] Merging TS → MP4")
    
    list_file = OUT_DIR / "list.txt"
    with list_file.open("w", encoding="utf-8") as f:
        for seg in segments:
            f.write(f"file '{(OUT_DIR / f'{seg['index']:05d}.ts').as_posix()}'\n")
    
    subprocess.run(["ffmpeg", "-y", "-f", "concat", "-safe", "0", "-i", str(list_file), "-c", "copy", "output.mp4"], check=True)
    
    print("🎬 output.mp4 created successfully")
    Quote Quote  



Similar Threads

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