factor out the actual stream download

This commit is contained in:
Etienne Zind 2022-12-06 11:14:47 +01:00
parent 6401c25205
commit 2b9d8773bd
1 changed files with 38 additions and 27 deletions

View File

@ -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())