This TV channel from Ecuador previously used the VuStream platform but recently it has switched platform, and the stream links are no longer .m3u8, now it's .mpd links, and I don't know how to download them.
The links I get with The Stream Detector.
I used FFmpeg on Windows to download video from .m3u8 links.Code:https://us-b4-p-e-qg12.cdn.mdstrm.com/live-stream-gdai/6a233703aa86429263ce17ec/linear/dash/pa/event/Z8uMUTUBSC6R09A92EKh1g/stream/1c4c6d47-4e7a-4f28-b114-efce56079b92:TUL/manifest.mpd?pid=5QQZEwhHoRN47YeyhdZ0Vxvc3QJe75iq&sid=G8PIyKncDwVav4Fy37dyb4EMqB5eFjTB&uid=LFoAadgdq5ui0OfK6zhfUBF8H1T06Okm&aid=693c80acf445d8c957fb250d&access_token=c7bdQ2YQWTEHsV96bfj0VPy4TBTjndvVfJ4decuci9KmGflz4GrHEDSm4lK4NkHrsXP5WFaApgh&ot=ekT5x80JzJe7SVUkwvMf0g&ote=1791623816659&proto=https&es=us-b4-p-e-qg12.cdn.mdstrm.com https://mdstrm.com/live-stream-playlist/6a233703aa86429263ce17ec.mpd?_=1791537454242&dnt=true&dual_render=1&player=6945b9bca18f515cff51c75b&access_token=c7bdQ2YQWTEHsV96bfj0VPy4TBTjndvVfJ4decuci9KmGflz4GrHEDSm4lK4NkHrsXP5WFaApgh&uid=LFoAadgdq5ui0OfK6zhfUBF8H1T06Okm&sid=G8PIyKncDwVav4Fy37dyb4EMqB5eFjTB&pid=5QQZEwhHoRN47YeyhdZ0Vxvc3QJe75iq&an=lightning-player&at=web-app&av=v1.0.109&sc=0&ref=mdstrm.com&res=1920x1080&ext_pb=0 https://mdstrm.com/live-stream-playlist/6a0dedcb6c7d568efdc8e0d9.mpd?_=1791537454278&dnt=true&dual_render=1&player=6945b9bca18f515cff51c75b&access_token=zgyI3CtDAAMJ9cfcCZnukNbhDee6FmEp3i9srcVB1TNpymIzbPcFb8IwYh1u5UT4OeeXX6JEFUb&uid=LFoAadgdq5ui0OfK6zhfUBF8H1T06Okm&sid=G8PIyKncDwVav4Fy37dyb4EMqB5eFjTB&pid=yVDbOrf1fnFMKCXfnFnc3dSyo1noW1re&an=lightning-player&at=web-app&av=v1.0.109&sc=0&ref=mdstrm.com&res=1920x1080&ext_pb=0
+ Reply to Thread
Results 1 to 26 of 26
-
Last edited by naoto89; 9th Oct 2026 at 09:19.
-
-
"https://www.teleamazonas.com/actualidad/24horas/estelar/noticias-jueves-8-octubre-2026-24-horas-ecuador-estelar-130059/"
yt-dlp "https://mdstrm.com/video/6ac8475b334a12f2722aef14.m3u8?uid=OT5bQUsWlL1nvA1d MJkhLr6W71YvUGAd&sid=FbzASGZ7GJ4wZOBra4kDz4ILwQOWl aFW&pid=yEif7bhpffx9IJBBD6h9aVr11qfSX0LF&pid_dvr=j QMfk74KTFRAlQGO6lu1ienYTR4MpIYH&an=screen&at=web-app&av=v7.0.124&ref=https%3A%2F%2Fwww.teleamazonas .com%2F&res=751x423&without_cookies=false&listener id=&dnt=true&CMCD=cid%3D%226ac8475b334a12f2722aef1 4%22%2Cmtp%3D500%2Cot%3Dm%2Csf%3Dh%2Csid%3D%22yEif 7bhpffx9IJBBD6h9aVr11qfSX0LF%22%2Csu" -o video.mp4
[generic] Extracting URL: https://mdstrm.com/video/6ac8475b334a12f2722aef14.m3u8?uid=OT5bQUsWlL1nvA1dMJkhLr6W71Y...fSX0LF%22%2Csu
[generic] 6ac8475b334a12f2722aef14.m3u8?uid=OT5bQUsWlL1nvA1d MJkhLr6W71YvUGAd&sid=FbzASGZ7GJ4wZOBra4kDz4ILwQOWl aFW&pid=yEif7bhpffx9IJBBD6h9aVr11qfSX0LF&pid_dvr=j QMfk74KTFRAlQGO6lu1ienYTR4MpIYH&an=screen&at=web-app&av=v7.0.124&ref=https://www.teleamazonas: Downloading webpage
[generic] 6ac8475b334a12f2722aef14.m3u8?uid=OT5bQUsWlL1nvA1d MJkhLr6W71YvUGAd&sid=FbzASGZ7GJ4wZOBra4kDz4ILwQOWl aFW&pid=yEif7bhpffx9IJBBD6h9aVr11qfSX0LF&pid_dvr=j QMfk74KTFRAlQGO6lu1ienYTR4MpIYH&an=screen&at=web-app&av=v7.0.124&ref=https://www.teleamazonas: Downloading m3u8 information
[generic] 6ac8475b334a12f2722aef14.m3u8?uid=OT5bQUsWlL1nvA1d MJkhLr6W71YvUGAd&sid=FbzASGZ7GJ4wZOBra4kDz4ILwQOWl aFW&pid=yEif7bhpffx9IJBBD6h9aVr11qfSX0LF&pid_dvr=j QMfk74KTFRAlQGO6lu1ienYTR4MpIYH&an=screen&at=web-app&av=v7.0.124&ref=https://www.teleamazonas: Checking m3u8 live status
[info] 6ac8475b334a12f2722aef14.m3u8?uid=OT5bQUsWlL1nvA1d MJkhLr6W71YvUGAd&sid=FbzASGZ7GJ4wZOBra4kDz4ILwQOWl aFW&pid=yEif7bhpffx9IJBBD6h9aVr11qfSX0LF&pid_dvr=j QMfk74KTFRAlQGO6lu1ienYTR4MpIYH&an=screen&at=web-app&av=v7.0.124&ref=https://www.teleamazonas: Downloading 1 format(s): 5000
[hlsnative] Downloading m3u8 manifest
WARNING: Live HLS streams are not supported by the native downloader. If this is a livestream, please add "--downloader ffmpeg --hls-use-mpegts" to your command
[hlsnative] Total fragments: 337
[download] Destination: video.mp4
[download] 2.4% of ~ 895.02MiB at 1.39MiB/s ETA 11:09 (frag 8/337)
... -
-
use this command (you can change the duration in red)
Code:n_m3u8dl-re "https://dai.google.com/linear/dash/pa/event/Z8uMUTUBSC6R09A92EKh1g/stream/bfe53670-3a82-4b10-a8e0-a4e1cf4b61b3:DLS/manifest.mpd" --key aeb0e7ae0feb4dae87c9859bc0e0d239:3c6df9213b350a19371cc1b3fea59a70 --use-shaka-packager -M mkv --live-real-time-merge --live-pipe-mux --live-wait-time 5 --live-record-limit 00:30:00 --save-name "filename"
-
-
yes its possible (but it expires fast)
https://dai.google.com/linear/dash/pa/event/Z8uMUTUBSC6R09A92EKh1g/stream/dfa7da58-b7f...L/manifest.mpd
I've uploaded the manifest just in case
https://files.videohelp.com/u/315200/manifest.mpd
the HAR object too
https://files.videohelp.com/u/315200/www.teleamazonas.com_HAR.har -
I still don't know everything I should do in this case, including the decryption key, which was the last thing I said. Can only N_m3u8DL-RE be used, and not another tool like Streamlink?
-
use this script
Code:#!/usr/bin/env python3 """ recorder.py — Teleamazonas en vivo recorder Fetches a fresh Google DAI (SSAI) DASH session and records with N_m3u8DL-RE. Usage: python recorder.py Requires: - Python 3.10+ - pip install requests - N_m3u8DL-RE on PATH (https://github.com/nilaoda/N_m3u8DL-RE/releases) - ffmpeg on PATH (for finalize / remux after stop) - Optional: shaka-packager on PATH (recommended; --use-shaka-packager) Controls: Ctrl+C — stop recording early, then finalize + cleanup (script keeps going) Widevine: This stream is DRM-protected. The default KEY/KID pair below worked for the same event id. If decryption fails, refresh the key (browser CDM / your own extract) and pass --key KID:KEY or set TELEAMAZONAS_KEY. """ from __future__ import annotations import argparse import os import random import re import shutil import signal import subprocess import sys import time import uuid from datetime import datetime from pathlib import Path import requests # Stable Google DAI event for Teleamazonas linear stream (from HAR / live page) EVENT_ID = "Z8uMUTUBSC6R09A92EKh1g" SSAI_URL = f"https://pubads.g.doubleclick.net/ssai/event/{EVENT_ID}/streams" # Default content key observed working for this event (KID:KEY, no dashes) # Override with env TELEAMAZONAS_KEY or --key DEFAULT_KEY = "aeb0e7ae0feb4dae87c9859bc0e0d239:3c6df9213b350a19371cc1b3fea59a70" UA = ( "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/155.0.0.0 Safari/537.36" ) PAGE_REF = "https://www.teleamazonas.com/teleamazonas-en-vivo/" MEDIA_EXTS = {".mkv", ".mp4", ".ts", ".m4s", ".cmfv", ".cmfa", ".mp4a", ".h264"} MANIFEST_EXTS = {".mpd", ".m3u8"} def eprint(*args, **kwargs): print(*args, file=sys.stderr, **kwargs) def find_n_m3u8dl() -> str: for name in ("N_m3u8DL-RE", "n_m3u8dl-re", "N_m3u8DL-RE.exe", "n_m3u8dl-re.exe"): path = shutil.which(name) if path: return path raise SystemExit( "N_m3u8DL-RE not found on PATH.\n" "Download a release for your OS from:\n" " https://github.com/nilaoda/N_m3u8DL-RE/releases\n" "Put the binary on PATH, then re-run." ) def find_ffmpeg() -> str | None: return shutil.which("ffmpeg") def prompt(text: str, default: str | None = None) -> str: if default is not None: suffix = f" [{default}]" else: suffix = "" while True: raw = input(f"{text}{suffix}: ").strip() if raw: return raw if default is not None: return default print(" (required)") def prompt_duration() -> str: """ Returns HH:MM:SS string for --live-record-limit. Accepts: 30m, 1h, 90, 01:30:00, etc. """ print("Duration examples: 30m | 1h | 90 (minutes) | 00:30:00") raw = prompt("Duration", "30m") raw = raw.strip().lower() if re.fullmatch(r"\d{1,2}:\d{2}:\d{2}", raw): return raw if raw.endswith("h") and raw[:-1].isdigit(): h = int(raw[:-1]) return f"{h:02d}:00:00" if raw.endswith("m") and raw[:-1].isdigit(): m = int(raw[:-1]) h, m = divmod(m, 60) return f"{h:02d}:{m:02d}:00" if raw.isdigit(): m = int(raw) h, m = divmod(m, 60) return f"{h:02d}:{m:02d}:00" return raw def prompt_format() -> str: print("Format: mkv | mp4 | ts") fmt = prompt("Container format", "mkv").lower() if fmt not in {"mkv", "mp4", "ts"}: print(" unknown format, using mkv") return "mkv" return fmt def safe_filename(name: str) -> str: name = re.sub(r'[<>:"/\\|?*\x00-\x1f]+', "_", name).strip(" .") return name or "teleamazonas" def fetch_stream_session(timeout: float = 30.0) -> dict: """POST Google DAI SSAI to get a fresh stream_manifest (MPD).""" correlator = str(random.randint(10**15, 10**16 - 1)) sid = str(uuid.uuid4()).upper() data = { "vpmute": "0", "api-key": "null", "auth-token": "null", "ctv": "0", "correlator": correlator, "ptt": "20", "osd": "2", "sdr": "1", "sdki": "445", "sdkv": "h.3.792.0", "ua": UA, "frm": "2", "sid": sid, "ssss": "gima", "ref": PAGE_REF, "url": "https://www.teleamazonas.com/", "gdpr": "0", "cookie_enabled": "1", "cdm": "mdstrm.com", "eoidce": "1", } headers = { "accept": "*/*", "content-type": "application/x-www-form-urlencoded;charset=utf-8", "origin": "https://mdstrm.com", "referer": "https://mdstrm.com/", "user-agent": UA, } r = requests.post(SSAI_URL, headers=headers, data=data, timeout=timeout) r.raise_for_status() js = r.json() if not js.get("stream_manifest"): raise RuntimeError(f"SSAI response missing stream_manifest: {js}") return js def normalize_key(key: str) -> str: """Accept KID:KEY with or without dashes; return lowercase no-dash form.""" key = key.strip().replace(" ", "") if ":" not in key: raise ValueError("key must be KID:KEY") kid, k = key.split(":", 1) kid = kid.replace("-", "").lower() k = k.replace("-", "").lower() if len(kid) != 32 or len(k) != 32: raise ValueError("KID and KEY must each be 32 hex chars (16 bytes)") return f"{kid}:{k}" def build_cmd( nre: str, mpd: str, key: str, save_name: str, duration: str, fmt: str, use_shaka: bool, save_dir: Path, tmp_dir: Path, ) -> list[str]: cmd = [ nre, mpd, "--key", key, # skip interactive stream picker (space/enter UI) "--auto-select", "-sv", "best", "-sa", "best", "-M", fmt, "--live-real-time-merge", "--live-pipe-mux", "--live-wait-time", "5", "--live-record-limit", duration, "--save-name", save_name, "--tmp-dir", str(tmp_dir), "--save-dir", str(save_dir), "--log-level", "INFO", ] has_shaka = bool(shutil.which("shaka-packager") or shutil.which("packager")) if use_shaka and has_shaka: cmd.append("--use-shaka-packager") elif use_shaka and not has_shaka: eprint("[!] shaka-packager not on PATH — continuing without --use-shaka-packager") cmd.extend( [ "--header", f"User-Agent: {UA}", "--header", f"Referer: {PAGE_REF}", "--header", "Origin: https://www.teleamazonas.com", ] ) return cmd def _kill_process_tree(proc: subprocess.Popen) -> None: """Hard-stop N_m3u8DL-RE and any children (Windows + Unix).""" if proc.poll() is not None: return pid = proc.pid try: if os.name == "nt": # /T = tree, /F = force — most reliable on Windows consoles subprocess.run( ["taskkill", "/PID", str(pid), "/T", "/F"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False, ) else: try: os.killpg(os.getpgid(pid), signal.SIGTERM) except Exception: proc.terminate() t0 = time.time() while proc.poll() is None and time.time() - t0 < 8: time.sleep(0.2) if proc.poll() is None: try: os.killpg(os.getpgid(pid), signal.SIGKILL) except Exception: proc.kill() except Exception: try: proc.kill() except Exception: pass def _poll_stop_key() -> bool: """ Non-blocking key check. True if user hit Q / S / Esc. Windows: msvcrt. Unix: select on stdin. """ try: if os.name == "nt": import msvcrt while msvcrt.kbhit(): ch = msvcrt.getch() # prefix for special keys — swallow second byte if ch in (b"\x00", b"\xe0"): if msvcrt.kbhit(): msvcrt.getch() continue if ch in (b"q", b"Q", b"s", b"S", b"\x1b", b"\x03"): return True return False else: import select if not sys.stdin.isatty(): return False r, _, _ = select.select([sys.stdin], [], [], 0) if r: ch = sys.stdin.read(1) if ch.lower() in {"q", "s", "\x1b", "\x03"}: return True return False except Exception: return False def run_recording(cmd: list[str]) -> tuple[bool, int]: """ Run N_m3u8DL-RE. Stop with: • Q or S key (no Enter) • Ctrl+C (or Ctrl+Break on Windows) Child stdin is DEVNULL so the keyboard stays with this script. Returns (user_stopped, returncode). """ stop_flag = {"set": False} prev_sigint = signal.getsignal(signal.SIGINT) prev_break = None def _request_stop(): stop_flag["set"] = True def _on_sigint(signum, frame): _request_stop() signal.signal(signal.SIGINT, _on_sigint) if hasattr(signal, "SIGBREAK"): try: prev_break = signal.getsignal(signal.SIGBREAK) # type: ignore[attr-defined] signal.signal(signal.SIGBREAK, _on_sigint) # type: ignore[attr-defined] except Exception: prev_break = None kwargs: dict = { # keep keyboard on the parent — child must not own stdin "stdin": subprocess.DEVNULL, } if os.name == "nt": kwargs["creationflags"] = subprocess.CREATE_NEW_PROCESS_GROUP # type: ignore[attr-defined] else: kwargs["start_new_session"] = True print("[*] recording…") print("[*] stop: press Q (or S) | Ctrl+C") proc = subprocess.Popen(cmd, **kwargs) user_stopped = False returncode = 0 try: while True: if stop_flag["set"] or _poll_stop_key(): user_stopped = True print("\n[*] stop requested — killing recorder, then finalizing…") _kill_process_tree(proc) try: returncode = proc.wait(timeout=15) except subprocess.TimeoutExpired: returncode = -9 time.sleep(1.0) break rc = proc.poll() if rc is not None: returncode = rc break time.sleep(0.12) finally: try: signal.signal(signal.SIGINT, prev_sigint) except Exception: pass if prev_break is not None and hasattr(signal, "SIGBREAK"): try: signal.signal(signal.SIGBREAK, prev_break) # type: ignore[attr-defined] except Exception: pass return user_stopped, returncode if returncode is not None else 0 def collect_media_files(root: Path, save_name: str) -> list[Path]: """Find media-ish files produced for this save_name under root (recursive).""" if not root.exists(): return [] found: list[Path] = [] for p in root.rglob("*"): if not p.is_file(): continue if save_name not in p.name and save_name not in str(p.relative_to(root)): # still allow exact prefix matches in name if not p.name.startswith(save_name): continue if p.suffix.lower() in MEDIA_EXTS or p.suffix.lower() in {".mkv", ".mp4", ".ts"}: found.append(p) # also direct non-recursive prefix in save dir for p in root.glob(f"{save_name}*"): if p.is_file() and p not in found: found.append(p) return found def pick_best_source(files: list[Path]) -> Path | None: """Prefer real containers; largest file wins. Ignore tiny/manifest junk.""" if not files: return None usable = [ p for p in files if p.exists() and p.suffix.lower() not in MANIFEST_EXTS and p.stat().st_size >= 64 * 1024 ] if not usable: return None preferred = [p for p in usable if p.suffix.lower() in {".mkv", ".mp4", ".ts"}] pool = preferred or usable return max(pool, key=lambda p: p.stat().st_size) def finalize_with_ffmpeg( source: Path, save_dir: Path, save_name: str, fmt: str, ) -> Path | None: """ Silent remux/finalize to a clean file. Returns final path or None. """ ffmpeg = find_ffmpeg() final = save_dir / f"{save_name}.{fmt}" # if source is already the desired container and looks complete, just move/rename if source.resolve() == final.resolve() and source.stat().st_size > 0: return final if not ffmpeg: # no ffmpeg — best-effort rename/copy if source.suffix.lower() == f".{fmt}": if source.resolve() != final.resolve(): shutil.move(str(source), str(final)) return final if final.exists() else source eprint("[!] ffmpeg not on PATH — leaving raw file as-is") return source # write to temp then replace tmp_out = save_dir / f".{save_name}.finalizing.{fmt}" cmd = [ ffmpeg, "-y", "-v", "error", "-i", str(source), "-c", "copy", "-movflags", "+faststart" if fmt == "mp4" else "none", str(tmp_out), ] # movflags none is invalid — fix for non-mp4 if fmt != "mp4": cmd = [ ffmpeg, "-y", "-v", "error", "-i", str(source), "-c", "copy", str(tmp_out), ] try: r = subprocess.run( cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False, ) except FileNotFoundError: eprint("[!] ffmpeg missing at run time") return source if r.returncode != 0 or not tmp_out.exists() or tmp_out.stat().st_size == 0: if tmp_out.exists(): tmp_out.unlink(missing_ok=True) # keep source if source.suffix.lower() == f".{fmt}" and source.resolve() != final.resolve(): try: shutil.move(str(source), str(final)) return final except Exception: return source return source if final.exists() and final.resolve() != tmp_out.resolve(): final.unlink(missing_ok=True) tmp_out.replace(final) return final def cleanup_junk(save_dir: Path, tmp_dir: Path, save_name: str, keep: Path | None) -> None: """Remove temp dirs and leftover fragments; never delete the keep file.""" keep_resolved = keep.resolve() if keep and keep.exists() else None # tmp dir for this recording if tmp_dir.exists(): try: shutil.rmtree(tmp_dir, ignore_errors=True) except Exception: pass # leftovers in save_dir matching name but not final if save_dir.exists(): for p in save_dir.glob(f"{save_name}*"): try: if keep_resolved and p.resolve() == keep_resolved: continue if p.is_file(): # drop sidecar / part / duplicate if p.suffix.lower() in {".part", ".tmp", ".bak"} or ".finalizing." in p.name: p.unlink(missing_ok=True) elif keep_resolved and p.resolve() != keep_resolved: # other partial containers for same name if p.suffix.lower() in MEDIA_EXTS: # only remove if clearly smaller fragment or different suffix junk if p.stat().st_size < 1024 * 64: p.unlink(missing_ok=True) elif p.is_dir(): shutil.rmtree(p, ignore_errors=True) except Exception: pass # empty top tmp_record top_tmp = Path("tmp_record") if top_tmp.exists(): try: if not any(top_tmp.iterdir()): top_tmp.rmdir() except Exception: pass def interactive() -> argparse.Namespace: print("=" * 60) print(" Teleamazonas en vivo — recorder") print(" Ctrl+C stops recording early, then finalizes") print("=" * 60) print() name = prompt("Recording name", f"teleamazonas_{datetime.now().strftime('%Y%m%d_%H%M%S')}") duration = prompt_duration() fmt = prompt_format() key_default = os.environ.get("TELEAMAZONAS_KEY", DEFAULT_KEY) print(f"DRM key default: {key_default[:8]}… (env TELEAMAZONAS_KEY or Enter to keep)") key_raw = prompt("KID:KEY", key_default) return argparse.Namespace( name=name, duration=duration, format=fmt, key=key_raw, yes=False, no_shaka=False, ) def parse_args() -> argparse.Namespace: p = argparse.ArgumentParser(description="Record Teleamazonas live (DAI DASH + Widevine key)") p.add_argument("-n", "--name", help="Output name (no extension)") p.add_argument("-d", "--duration", help="Limit HH:MM:SS or 30m / 1h") p.add_argument("-f", "--format", choices=["mkv", "mp4", "ts"], help="Container") p.add_argument("--key", help="Widevine KID:KEY (32hex:32hex)") p.add_argument("-y", "--yes", action="store_true", help="No confirm prompt") p.add_argument("--no-shaka", action="store_true", help="Do not pass --use-shaka-packager") args, _ = p.parse_known_args() if args.name and args.duration and args.format: if not args.key: args.key = os.environ.get("TELEAMAZONAS_KEY", DEFAULT_KEY) return args if len(sys.argv) == 1 or (not args.name and not args.duration): return interactive() if not args.name: args.name = prompt("Recording name", f"teleamazonas_{datetime.now().strftime('%Y%m%d_%H%M%S')}") if not args.duration: args.duration = prompt_duration() else: d = args.duration.lower() if d.endswith("m") and d[:-1].isdigit(): m = int(d[:-1]) h, m = divmod(m, 60) args.duration = f"{h:02d}:{m:02d}:00" elif d.endswith("h") and d[:-1].isdigit(): args.duration = f"{int(d[:-1]):02d}:00:00" elif d.isdigit(): m = int(d) h, m = divmod(m, 60) args.duration = f"{h:02d}:{m:02d}:00" if not args.format: args.format = prompt_format() if not args.key: args.key = os.environ.get("TELEAMAZONAS_KEY", DEFAULT_KEY) return args def main() -> int: args = parse_args() nre = find_n_m3u8dl() try: key = normalize_key(args.key) except ValueError as exc: eprint(f"bad key: {exc}") return 2 save_name = safe_filename(args.name) duration = args.duration fmt = args.format save_dir = Path("recordings") tmp_dir = Path("tmp_record") / save_name print() print("[*] requesting fresh DAI stream session…") try: session = fetch_stream_session() except Exception as exc: eprint(f"SSAI failed: {exc}") return 1 mpd = session["stream_manifest"] stream_id = session.get("stream_id", "?") print(f"[+] stream_id : {stream_id}") print(f"[+] manifest : {mpd}") print(f"[+] key : {key[:8]}…:{key.split(':')[1][:8]}…") print(f"[+] duration : {duration}") print(f"[+] format : {fmt}") print(f"[+] save name : {save_name}") print(f"[+] stop early: Ctrl+C (then auto-finalize)") print() if not args.yes: ok = input("Start recording? [Y/n] ").strip().lower() if ok in {"n", "no"}: print("aborted") return 0 save_dir.mkdir(parents=True, exist_ok=True) tmp_dir.mkdir(parents=True, exist_ok=True) cmd = build_cmd( nre, mpd, key, save_name, duration, fmt, use_shaka=not getattr(args, "no_shaka", False), save_dir=save_dir, tmp_dir=tmp_dir, ) print(" ", subprocess.list2cmdline(cmd) if os.name == "nt" else " ".join(cmd)) print() try: user_stopped, returncode = run_recording(cmd) except FileNotFoundError: eprint("failed to execute N_m3u8DL-RE") return 1 if user_stopped: print("[*] recorder stopped by user") elif returncode not in (0, None): eprint() eprint(f"N_m3u8DL-RE exit code {returncode}") eprint("Will still try to finalize any partial output…") eprint("If empty: KEY rotated, MPD died, or muxer missing.") # gather outputs from save + tmp candidates = collect_media_files(save_dir, save_name) + collect_media_files(tmp_dir, save_name) source = pick_best_source(candidates) final_path: Path | None = None if source and source.exists() and source.stat().st_size > 0: print("[*] finalizing (silent ffmpeg remux)…") final_path = finalize_with_ffmpeg(source, save_dir, save_name, fmt) if final_path and final_path.exists(): size_mb = final_path.stat().st_size / (1024 * 1024) print(f"[+] saved: {final_path} ({size_mb:.1f} MB)") else: eprint("[!] finalize produced nothing useful") else: eprint("[!] no media file found to finalize") print("[*] cleaning temp files…") cleanup_junk(save_dir, tmp_dir, save_name, final_path) if final_path and final_path.exists(): print(f"[*] done — {final_path}") return 0 return 1 if returncode not in (0, None) and not user_stopped else 0 if __name__ == "__main__": raise SystemExit(main()) -
I assume it's a Python script, but that just complicates things further.
On which operating system does the script run? As I mentioned earlier, I use Windows.
What is the download and tools paths? I handle everything on drives other than C:\, I use .bat scripts with variables to automate processes and custom paths.
This isn't going to help me, especially since I always have issues with Python and package installation. -
You don't have to install anything (only python should be installed in your pc)
https://files.videohelp.com/u/315187/teleamazons_recorder.exeHelp others the way you’d want to be helped. Don’t just take—learn to give back too. -
Can someone help me as well? I've tried with n_m3u8dl-re and xstreamdl but it just won't work:
-
"https://mrs.shift72.com/77444323-e95b-4351-8331-2cfb4a79f5ce.mpd?pt=eyJhbGciOiJIUzI1NiIsInR5cCI6Ik pXVCJ9.eyJhZ2UiOjMxLCJiaWQiOm51bGwsImNoa2R2YyI6dHJ 1ZSwiY2lkIjozMzEsImNvcmlkIjoiIiwiZGVscG9sIjoidXJuO nNoaWZ0NzIiLCJleHAiOjE3OTE5ODYzNDcsImZ3IjpudWxsLCJ naWQiOjIsImdyIjoiZGsiLCJpYXQiOjE3OTE4OTk5NDcsImlzc yI6Imh0dHA6Ly9zaGlmdDcyLmNvbS8iLCJsaWQiOjIyNDg3OTc xLCJtaWQiOjIyMTQyNCwib3duIjoicmVudCIsInBpZCI6MCwic GxheWlkIjoiYzFhOTAwZGUtMGRmOS00MmQ0LTgwZGQtYzZhYzY 3NGE1YzJjIiwicWlkIjoiaGQiLCJzNzJ1c3IiOnRydWUsInNrY XZhaWwiOmZhbHNlLCJzbHVnIjoiL2ZpbG0vMTc2ODM1Iiwic3V iIjoiNDIwNjE4NCIsInRsbXRyeSI6dHJ1ZSwidXNyIjoiNDIwN jE4NCIsIndhdGVybWFya2luZ19tZXRob2QiOjB9.MLYfrDTwet _2UuCnyoMGDeNTt-LzAE5lI-OwldeDJN8"
URL?This video is DRM protected -
URl of the video? Well its a rented film so of no use for you I assume https://www.ifiinternational.ie/play/#/film/176835?from=https%3A%2F%2Fwww.ifiinternati...orner%2F&t=445
-
I have Python installed on my Windows PC, but it doesn't work reliably for me; I can't wait until it runs correctly with every error that Python shows
Also, since I don't understand how that script works, I won't be able to customize it with things like the stream URLs (if you noticed, there are 2 streams on the same page, one called "Quito" and the other "Guayaquil"), get the keys (which I also don't know how to do), the save paths, and adding the run of a player that displays the stream at the same time as it downloads it. Previously, I used this batch script to download the video using FFmpeg and FFplay when the earlier stream had an m3u8 link.
Code:"%ffmpeg%" ^ -thread_queue_size 4096 ^ -user_agent "%UA%" ^ -referer "https://www.teleamazonas.com/" ^ -i "%URL%" ^ -map 0:p:3 ^ -c copy ^ -reconnect true ^ -reconnect_at_eof true ^ -reconnect_on_network_error true ^ -reconnect_on_http_error "4xx, 5xx" ^ -reconnect_streamed true ^ -reconnect_delay_max 4294 ^ -multiple_requests true "%OUTPUT%" ^ -f mpegts ^ - | "%ffplay%" - ^ -x 854 ^ -y 480 ^ -af "volume=3" ^ -window_title "%CSTFFP%"
Similar Threads
-
How to download mpd stream (DRM protected)?
By ddim in forum Video Streaming DownloadingReplies: 320Last Post: 23rd Jun 2024, 18:01 -
Unable to download stream from mpd link
By sarvo99 in forum Video Streaming DownloadingReplies: 2Last Post: 12th Aug 2023, 07:37 -
How download stream.mpd with the key i got??
By davidbdn1994 in forum Video Streaming DownloadingReplies: 23Last Post: 18th Jan 2023, 10:05 -
How To Play / Download a DRM Live Stream Protected MPD Manifest On Linux
By Rebanjulu in forum Video Streaming DownloadingReplies: 5Last Post: 2nd Nov 2022, 11:52 -
Download from stream mpd, using YoutubeDL
By danielias in forum Video Streaming DownloadingReplies: 10Last Post: 5th Jan 2022, 15:24


Quote