forked from fcode/delarte
💥 Convert line endings to LF (unix)
This commit is contained in:
parent
e3791e847e
commit
e98417e4e9
232
delarte.py
232
delarte.py
|
@ -1,116 +1,116 @@
|
|||
#!/usr/bin/env python3
|
||||
# coding:utf-8
|
||||
|
||||
"""delarte.
|
||||
|
||||
Retrieve video stream in a local file, including sub-titles
|
||||
|
||||
Licence: GNU AGPL v3: http://www.gnu.org/licenses/
|
||||
|
||||
This file is part of [`delarte`](https://git.afpy.org/fcode/delarte)
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
import io
|
||||
import subprocess
|
||||
|
||||
from http import HTTPStatus
|
||||
from os import environ
|
||||
from typing import cast
|
||||
from urllib.parse import urlparse
|
||||
from urllib.request import urlopen
|
||||
|
||||
import m3u8
|
||||
import webvtt
|
||||
|
||||
FFMPEG = environ.get("PATH_FFMPEG", "ffmpeg path not found")
|
||||
|
||||
|
||||
def call_api(api_url):
|
||||
"""Retrieve subtitles versions available for a given URL."""
|
||||
http_response = urlopen(api_url)
|
||||
|
||||
if http_response.status != HTTPStatus.OK:
|
||||
raise RuntimeError("API request failed")
|
||||
|
||||
config = json.load(http_response)["data"]["attributes"]
|
||||
|
||||
title = config["metadata"]["title"]
|
||||
|
||||
versions = {
|
||||
s["versions"][0]["eStat"]["ml5"]: (s["url"], s["versions"][0]["label"])
|
||||
for s in config["streams"]
|
||||
}
|
||||
|
||||
return (title, versions)
|
||||
|
||||
|
||||
def write_subtitles(m3u8_url, base_name):
|
||||
"""Convert distant vtt subtitles to local srt."""
|
||||
main = m3u8.load(m3u8_url)
|
||||
|
||||
sub_m3u8_urls = [
|
||||
(m.base_uri + "/" + m.uri, m.language)
|
||||
for m in main.media
|
||||
if m.type == "SUBTITLES"
|
||||
]
|
||||
|
||||
for sub_m3u8_url, sub_lang in sub_m3u8_urls:
|
||||
|
||||
sub_m3u8 = m3u8.load(sub_m3u8_url)
|
||||
sub_urls = [cast(str, sub_m3u8.base_uri) + "/" + f for f in sub_m3u8.files]
|
||||
|
||||
if not sub_urls:
|
||||
raise ValueError("No subtitle files")
|
||||
|
||||
if len(sub_urls) > 1:
|
||||
raise ValueError("Multiple subtitle files")
|
||||
|
||||
http_response = urlopen(sub_urls[0])
|
||||
if http_response.status != HTTPStatus.OK:
|
||||
raise RuntimeError("Subtitle request failed")
|
||||
|
||||
buffer = io.StringIO(http_response.read().decode("utf8"))
|
||||
|
||||
with open(f"{base_name}.{sub_lang}.srt", "w", encoding="utf8") as f:
|
||||
for i, caption in enumerate(webvtt.read_buffer(buffer), 1):
|
||||
print(i, file=f)
|
||||
print(
|
||||
re.sub(r"\.", ",", caption.start)
|
||||
+ " --> "
|
||||
+ re.sub(r"\.", ",", caption.end),
|
||||
file=f,
|
||||
)
|
||||
print(caption.text + "\n", file=f)
|
||||
return f.name
|
||||
|
||||
|
||||
# command line 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")
|
||||
|
||||
TITLE, VERSIONS = call_api(
|
||||
f"https://api.arte.tv/api/player/v2/config/{UI_LANG}/{STREAM_ID}"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
subprocess.run(
|
||||
[FFMPEG, "-i", M3U8_URL, "-c", "copy", "-bsf:a", "aac_adtstoasc", f"{FILENAME}.mp4"]
|
||||
)
|
||||
#!/usr/bin/env python3
|
||||
# coding:utf-8
|
||||
|
||||
"""delarte.
|
||||
|
||||
Retrieve video stream in a local file, including sub-titles
|
||||
|
||||
Licence: GNU AGPL v3: http://www.gnu.org/licenses/
|
||||
|
||||
This file is part of [`delarte`](https://git.afpy.org/fcode/delarte)
|
||||
"""
|
||||
|
||||
|
||||
import json
|
||||
import sys
|
||||
import re
|
||||
import io
|
||||
import subprocess
|
||||
|
||||
from http import HTTPStatus
|
||||
from os import environ
|
||||
from typing import cast
|
||||
from urllib.parse import urlparse
|
||||
from urllib.request import urlopen
|
||||
|
||||
import m3u8
|
||||
import webvtt
|
||||
|
||||
FFMPEG = environ.get("PATH_FFMPEG", "ffmpeg path not found")
|
||||
|
||||
|
||||
def call_api(api_url):
|
||||
"""Retrieve subtitles versions available for a given URL."""
|
||||
http_response = urlopen(api_url)
|
||||
|
||||
if http_response.status != HTTPStatus.OK:
|
||||
raise RuntimeError("API request failed")
|
||||
|
||||
config = json.load(http_response)["data"]["attributes"]
|
||||
|
||||
title = config["metadata"]["title"]
|
||||
|
||||
versions = {
|
||||
s["versions"][0]["eStat"]["ml5"]: (s["url"], s["versions"][0]["label"])
|
||||
for s in config["streams"]
|
||||
}
|
||||
|
||||
return (title, versions)
|
||||
|
||||
|
||||
def write_subtitles(m3u8_url, base_name):
|
||||
"""Convert distant vtt subtitles to local srt."""
|
||||
main = m3u8.load(m3u8_url)
|
||||
|
||||
sub_m3u8_urls = [
|
||||
(m.base_uri + "/" + m.uri, m.language)
|
||||
for m in main.media
|
||||
if m.type == "SUBTITLES"
|
||||
]
|
||||
|
||||
for sub_m3u8_url, sub_lang in sub_m3u8_urls:
|
||||
|
||||
sub_m3u8 = m3u8.load(sub_m3u8_url)
|
||||
sub_urls = [cast(str, sub_m3u8.base_uri) + "/" + f for f in sub_m3u8.files]
|
||||
|
||||
if not sub_urls:
|
||||
raise ValueError("No subtitle files")
|
||||
|
||||
if len(sub_urls) > 1:
|
||||
raise ValueError("Multiple subtitle files")
|
||||
|
||||
http_response = urlopen(sub_urls[0])
|
||||
if http_response.status != HTTPStatus.OK:
|
||||
raise RuntimeError("Subtitle request failed")
|
||||
|
||||
buffer = io.StringIO(http_response.read().decode("utf8"))
|
||||
|
||||
with open(f"{base_name}.{sub_lang}.srt", "w", encoding="utf8") as f:
|
||||
for i, caption in enumerate(webvtt.read_buffer(buffer), 1):
|
||||
print(i, file=f)
|
||||
print(
|
||||
re.sub(r"\.", ",", caption.start)
|
||||
+ " --> "
|
||||
+ re.sub(r"\.", ",", caption.end),
|
||||
file=f,
|
||||
)
|
||||
print(caption.text + "\n", file=f)
|
||||
return f.name
|
||||
|
||||
|
||||
# command line 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")
|
||||
|
||||
TITLE, VERSIONS = call_api(
|
||||
f"https://api.arte.tv/api/player/v2/config/{UI_LANG}/{STREAM_ID}"
|
||||
)
|
||||
|
||||
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)
|
||||
|
||||
subprocess.run(
|
||||
[FFMPEG, "-i", M3U8_URL, "-c", "copy", "-bsf:a", "aac_adtstoasc", f"{FILENAME}.mp4"]
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue