X-Git-Url: https://code.delx.au/webdl/blobdiff_plain/c2dadfb9cda3761184a33eb38b3c2ab711114bea..bfaf019987c47406335b61c5825cabe21cafa107:/common.py diff --git a/common.py b/common.py index f0886c8..e90bbf7 100644 --- a/common.py +++ b/common.py @@ -1,4 +1,5 @@ import hashlib +import io import json import logging import lxml.etree @@ -67,8 +68,8 @@ def load_root_node(): import sbs sbs.fill_nodes(root_node) - import brightcove - brightcove.fill_nodes(root_node) + import ten + ten.fill_nodes(root_node) return root_node @@ -99,7 +100,7 @@ def grab_html(url): logging.debug("grab_html(%r)", url) request = http_session.prepare_request(requests.Request("GET", url)) response = http_session.send(request, stream=True) - doc = lxml.html.parse(response.raw, lxml.html.HTMLParser(encoding="utf-8", recover=True)) + doc = lxml.html.parse(io.BytesIO(response.content), lxml.html.HTMLParser(encoding="utf-8", recover=True)) response.close() return doc @@ -107,7 +108,7 @@ def grab_xml(url): logging.debug("grab_xml(%r)", url) request = http_session.prepare_request(requests.Request("GET", url)) response = http_session.send(request, stream=True) - doc = lxml.etree.parse(response.raw, lxml.etree.XMLParser(encoding="utf-8", recover=True)) + doc = lxml.etree.parse(io.BytesIO(response.content), lxml.etree.XMLParser(encoding="utf-8", recover=True)) response.close() return doc @@ -148,19 +149,35 @@ def check_command_exists(cmd): return False def find_ffmpeg(): - for ffmpeg in ["avconv", "ffmpeg"]: - if check_command_exists([ffmpeg, "--help"]): - return ffmpeg + if check_command_exists(["ffmpeg", "--help"]): + return "ffmpeg" + + if check_command_exists(["avconv", "--help"]): + logging.warn("Detected libav-tools! ffmpeg is recommended") + return "avconv" raise Exception("You must install ffmpeg or libav-tools") def find_ffprobe(): - for ffprobe in ["avprobe", "ffprobe"]: - if check_command_exists([ffprobe, "--help"]): - return ffprobe + if check_command_exists(["ffprobe", "--help"]): + return "ffprobe" + + if check_command_exists(["avprobe", "--help"]): + logging.warn("Detected libav-tools! ffmpeg is recommended") + return "avprobe" raise Exception("You must install ffmpeg or libav-tools") +def find_streamlink(): + if check_command_exists(["streamlink", "--help"]): + return "streamlink" + + if check_command_exists(["livestreamer", "--help"]): + logging.warn("Detected livestreamer! streamlink is recommended") + return "livestreamer" + + raise Exception("You must install streamlink or livestreamer") + def get_duration(filename): ffprobe = find_ffprobe() @@ -172,12 +189,37 @@ def get_duration(filename): ] output = subprocess.check_output(cmd).decode("utf-8") for line in output.split("\n"): - if line.startswith("duration="): - return float(line.split("=")[1]) # ffprobe - if re.match(R'^[0-9.]*$', line): - return float(line) # avprobe + m = re.search(R"([0-9]+)", line) + if not m: + continue + duration = m.group(1) + if duration.isdigit(): + return int(duration) + - raise Exception("Unable to determine video duration of " + filename) + logging.debug("Falling back to full decode to find duration: %s % filename") + + ffmpeg = find_ffmpeg() + cmd = [ + ffmpeg, + "-i", filename, + "-vn", + "-f", "null", "-", + ] + output = subprocess.check_output(cmd, stderr=subprocess.STDOUT).decode("utf-8") + duration = None + for line in re.split(R"[\r\n]", output): + m = re.search(R"time=([0-9:]*)\.", line) + if not m: + continue + [h, m, s] = m.group(1).split(":") + # ffmpeg prints the duration as it reads the file, we want the last one + duration = int(h) * 3600 + int(m) * 60 + int(s) + + if duration: + return duration + else: + raise Exception("Unable to determine video duration of " + filename) def check_video_durations(flv_filename, mp4_filename): flv_duration = get_duration(flv_filename) @@ -232,6 +274,8 @@ def convert_to_mp4(filename): def download_hds(filename, video_url, pvswf=None): + streamlink = find_streamlink() + filename = sanify_filename(filename) logging.info("Downloading: %s", filename) @@ -242,7 +286,7 @@ def download_hds(filename, video_url, pvswf=None): param = video_url cmd = [ - "livestreamer", + streamlink, "-f", "-o", filename, param, @@ -254,12 +298,33 @@ def download_hds(filename, video_url, pvswf=None): return False def download_hls(filename, video_url): + streamlink = find_streamlink() + filename = sanify_filename(filename) video_url = "hlsvariant://" + video_url logging.info("Downloading: %s", filename) cmd = [ - "livestreamer", + streamlink, + "-f", + "-o", filename, + video_url, + "best", + ] + if exec_subprocess(cmd): + return convert_to_mp4(filename) + else: + return False + +def download_mpd(filename, video_url): + streamlink = find_streamlink() + + filename = sanify_filename(filename) + video_url = "dash://" + video_url + logging.info("Downloading: %s", filename) + + cmd = [ + streamlink, "-f", "-o", filename, video_url,