Last active 1648499347

A script to download game vods, condensed vods, or highlights from nbl.com.au without an account

nbl_dl.py Raw
1#!/usr/bin/env python3
2from requests import get, post
3from subprocess import Popen
4from os import remove
5from datetime import datetime
6
7class Category:
8 HIGHLIGHTS = 71361
9 CONDENSED = 71377
10 FULL = 71385
11
12def get_vods(category = None, filter_name = None, filter_date_after = None):
13 if not category:
14 category = Category.HIGHLIGHTS
15 data = get("https://apicdn.nbl.com.au/nbl/custom/api/sportradar", params={
16 "route": "content",
17 "status_id": "2,3",
18 "cat3_id": "11191",
19 "limit": "200",
20 "page": "1",
21 "content_type_id": category,
22 "sort_direction": "desc",
23 "content_source_id": "81387",
24 "filter[tenant]": "nbl"
25 }).json()["data"]
26 matches = data
27 if filter_name:
28 matches = [match for match in matches if filter_name.lower() in match["editorial"]["translations"]["en"]["title"].lower()]
29 if filter_date_after:
30 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")]
31 return matches
32
33def get_vod(vod_id, resolution=None):
34 stream_url = post(f"https://ott.nbl.com.au/api/v2/content/{vod_id}/access/hls", headers={
35 "Referer": f"https://ott.nbl.com.au/en-int/embed/{vod_id}",
36 "Origin": "https://ott.nbl.com.au",
37 "Content-Length": "0"
38 }).json()["data"]["stream"]
39 if not resolution:
40 return stream_url
41 m3u8 = get(stream_url).text.split("\n")
42 for n,line in enumerate(m3u8):
43 if line[0] == "#" and f",RESOLUTION={resolution}" in line:
44 return m3u8[n+1]
45 raise Exception("No stream urls matching resolution found")
46
47def main():
48 from argparse import ArgumentParser
49 parser = ArgumentParser()
50 parser.add_argument("--name", default="perth wildcats")
51 parser.add_argument("--category", default="highlights")
52 parser.add_argument("--resolution", default="1280x720")
53 parser.add_argument("--date-after", default="2021-07-01")
54 args = parser.parse_args()
55 category = getattr(Category, args.category.upper()) if args.category else None
56 matches = get_vods(category=category, filter_name=args.name, filter_date_after=args.date_after)
57 for match in matches:
58 fn = match['startTime'] + " - " + match['editorial']['translations']['en']['title'] + (f" ({args.resolution.split('x')[1]}p)" if args.resolution else "") + f".{match['id']}.mp4"
59 print(fn)
60 try:
61 # skip existing files
62 with open(fn) as f:
63 continue
64 except FileNotFoundError:
65 pass
66 proc = Popen(["ffmpeg", "-v", "quiet", "-stats", "-n", "-i", get_vod(match['id'], resolution=args.resolution), "-c", "copy", "file:" + fn])
67 try:
68 proc.communicate()
69 finally:
70 # delete incomplete files
71 if proc.returncode != 0:
72 remove(fn)
73
74if __name__ == "__main__":
75 main()