forked from fcode/delarte
factor out the actual stream download
This commit is contained in:
parent
6401c25205
commit
2b9d8773bd
65
delarte.py
65
delarte.py
|
@ -28,6 +28,7 @@ import webvtt
|
|||
|
||||
FFMPEG = environ.get("PATH_FFMPEG", "ffmpeg path not found")
|
||||
|
||||
|
||||
def api_root(url: str):
|
||||
"""Retrieve the root node (infamous "data") of an API call response."""
|
||||
http_response = urlopen(url)
|
||||
|
@ -35,20 +36,26 @@ def api_root(url: str):
|
|||
if http_response.status != HTTPStatus.OK:
|
||||
raise RuntimeError("API request failed")
|
||||
|
||||
if http_response.getheader("Content-Type") != "application/vnd.api+json; charset=utf-8":
|
||||
if (
|
||||
http_response.getheader("Content-Type")
|
||||
!= "application/vnd.api+json; charset=utf-8"
|
||||
):
|
||||
raise ValueError("API response not supported")
|
||||
|
||||
return json.load(http_response)["data"]
|
||||
|
||||
|
||||
class Config(NamedTuple):
|
||||
"""A structure representing a config API object."""
|
||||
|
||||
provider_id: str
|
||||
title: str
|
||||
subtitle: str
|
||||
versions: dict[str, tuple[str, str]]
|
||||
|
||||
|
||||
def api_config(lang: str, provider_id: str) -> Config:
|
||||
"""Retrieve a stream config from API."""
|
||||
|
||||
url = f"https://api.arte.tv/api/player/v2/config/{lang}/{provider_id}"
|
||||
root = api_root(url)
|
||||
|
||||
|
@ -67,11 +74,12 @@ def api_config(lang: str, provider_id: str) -> Config:
|
|||
{
|
||||
s["versions"][0]["eStat"]["ml5"]: (s["url"], s["versions"][0]["label"])
|
||||
for s in attrs["streams"]
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
def api_playlist(lang: str, provider_id: str):
|
||||
"""Retrieve a playlist from API."""
|
||||
url = f"https://api.arte.tv/api/player/v2/playlist/{lang}/{provider_id}"
|
||||
raise NotImplementedError
|
||||
|
||||
|
@ -116,29 +124,9 @@ def write_subtitles(m3u8_url, base_name):
|
|||
return f.name
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI function, options passed as arguments."""
|
||||
(ui_lang, _, stream_id, _slug) = urlparse(sys.argv[1]).path[1:-1].split("/")
|
||||
version = " ".join(sys.argv[2:])
|
||||
|
||||
if ui_lang not in ("fr", "de", "en", "es", "pl", "it") or _ != "videos":
|
||||
raise ValueError("Invalid URL")
|
||||
|
||||
config = api_config(ui_lang, stream_id)
|
||||
title = config.title
|
||||
versions = config.versions
|
||||
|
||||
filename = title.replace("/", "-")
|
||||
|
||||
if version not in versions:
|
||||
print(title)
|
||||
for v, (_, l) in versions.items():
|
||||
print(f"\t{v} : {l}")
|
||||
exit(1)
|
||||
|
||||
m3u8_url, _version_name = versions[version]
|
||||
|
||||
write_subtitles(m3u8_url, filename)
|
||||
def download_stream(m3u8_url: str, base_file: str):
|
||||
"""Download and writes the video and subtitles files."""
|
||||
write_subtitles(m3u8_url, base_file)
|
||||
|
||||
subprocess.run(
|
||||
[
|
||||
|
@ -149,10 +137,33 @@ def main():
|
|||
"copy",
|
||||
"-bsf:a",
|
||||
"aac_adtstoasc",
|
||||
f"{filename}.mp4",
|
||||
f"{base_file}.mp4",
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI function, options passed as arguments."""
|
||||
(ui_lang, _, stream_id, _slug) = urlparse(sys.argv[1]).path[1:-1].split("/")
|
||||
version = " ".join(sys.argv[2:])
|
||||
|
||||
if ui_lang not in ("fr", "de", "en", "es", "pl", "it") or _ != "videos":
|
||||
raise ValueError("Invalid URL")
|
||||
|
||||
config = api_config(ui_lang, stream_id)
|
||||
|
||||
base_file = config.title.replace("/", "-")
|
||||
|
||||
if version not in config.versions:
|
||||
print(f"{config.title} - {config.subtitle}")
|
||||
for version_code, (_, version_label) in config.versions.items():
|
||||
print(f"\t{version_code} : {version_label}")
|
||||
exit(1)
|
||||
|
||||
m3u8_url, _version_name = config.versions[version]
|
||||
|
||||
download_stream(m3u8_url, base_file)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
Loading…
Reference in New Issue