#!/usr/bin/env python3 from requests import get, post from subprocess import Popen from os import remove from datetime import datetime class Category: HIGHLIGHTS = 71361 CONDENSED = 71377 FULL = 71385 def get_vods(category = None, filter_name = None, filter_date_after = None): if not category: category = Category.HIGHLIGHTS data = get("https://apicdn.nbl.com.au/nbl/custom/api/sportradar", params={ "route": "content", "status_id": "2,3", "cat3_id": "11191", "limit": "200", "page": "1", "content_type_id": category, "sort_direction": "desc", "content_source_id": "81387", "filter[tenant]": "nbl" }).json()["data"] matches = data if filter_name: matches = [match for match in matches if filter_name.lower() in match["editorial"]["translations"]["en"]["title"].lower()] if filter_date_after: matches = [match for match in matches if datetime.strptime(filter_date_after, "%Y-%m-%d") < datetime.strptime(match["startTime"].split("T",1)[0], "%Y-%m-%d")] return matches def get_vod(vod_id, resolution=None): stream_url = post(f"https://ott.nbl.com.au/api/v2/content/{vod_id}/access/hls", headers={ "Referer": f"https://ott.nbl.com.au/en-int/embed/{vod_id}", "Origin": "https://ott.nbl.com.au", "Content-Length": "0" }).json()["data"]["stream"] if not resolution: return stream_url m3u8 = get(stream_url).text.split("\n") for n,line in enumerate(m3u8): if line[0] == "#" and f",RESOLUTION={resolution}" in line: return m3u8[n+1] raise Exception("No stream urls matching resolution found") def main(): from argparse import ArgumentParser parser = ArgumentParser() parser.add_argument("--name", default="perth wildcats") parser.add_argument("--category", default="highlights") parser.add_argument("--resolution", default="1280x720") parser.add_argument("--date-after", default="2021-07-01") args = parser.parse_args() category = getattr(Category, args.category.upper()) if args.category else None matches = get_vods(category=category, filter_name=args.name, filter_date_after=args.date_after) for match in matches: fn = match['startTime'] + " - " + match['editorial']['translations']['en']['title'] + (f" ({args.resolution.split('x')[1]}p)" if args.resolution else "") + f".{match['id']}.mp4" print(fn) try: # skip existing files with open(fn) as f: continue except FileNotFoundError: pass proc = Popen(["ffmpeg", "-v", "quiet", "-stats", "-n", "-i", get_vod(match['id'], resolution=args.resolution), "-c", "copy", "file:" + fn]) try: proc.communicate() finally: # delete incomplete files if proc.returncode != 0: remove(fn) if __name__ == "__main__": main()