]> code.delx.au - webdl/blobdiff - common.py
Fix for avprobe
[webdl] / common.py
index cabfd936c30f65e8fb11df8758888f455ac14222..ead72c645216692195eb2284c258e70ea29f0c30 100644 (file)
--- a/common.py
+++ b/common.py
@@ -77,9 +77,18 @@ def sanify_filename(filename):
     assert len(filename) > 0
     return filename
 
+def ensure_scheme(url):
+    parts = urllib.parse.urlparse(url)
+    if parts.scheme:
+        return url
+    parts = list(parts)
+    parts[0] = "http"
+    return urllib.parse.urlunparse(parts)
+
 cookiejar = http.cookiejar.CookieJar()
 urlopener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookiejar))
 def _urlopen(url, referrer=None):
+    url = ensure_scheme(url)
     req = urllib.request.Request(url)
     req.add_header("User-Agent", USER_AGENT)
     if referrer:
@@ -179,53 +188,77 @@ def exec_subprocess(cmd):
 
 def check_command_exists(cmd):
     try:
-        subprocess.check_output(cmd)
+        subprocess.check_output(cmd, stderr=subprocess.STDOUT)
         return True
     except Exception:
         return False
 
-def generate_remux_cmd(infile, outfile):
-    if check_command_exists(["avconv", "--help"]):
-        return [
-            "avconv",
-            "-i", infile,
-            "-bsf:a", "aac_adtstoasc",
-            "-acodec", "copy",
-            "-vcodec", "copy",
-            outfile,
-        ]
-
-    if check_command_exists(["ffmpeg", "--help"]):
-        return [
-            "ffmpeg",
-            "-i", infile,
-            "-bsf:a", "aac_adtstoasc",
-            "-acodec", "copy",
-            "-vcodec", "copy",
-            outfile,
-        ]
+def find_ffmpeg():
+    for ffmpeg in ["avconv", "ffmpeg"]:
+        if check_command_exists([ffmpeg, "--help"]):
+            return ffmpeg
 
     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
+
+    raise Exception("You must install ffmpeg or libav-tools")
+
+def get_duration(filename):
+    ffprobe = find_ffprobe()
+
+    cmd = [
+        ffprobe,
+        filename,
+        "-show_format_entry", "duration",
+        "-v", "quiet",
+    ]
+    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
+
+    raise Exception("Unable to determine video duration of " + filename)
+
+def check_video_durations(flv_filename, mp4_filename):
+    flv_duration = get_duration(flv_filename)
+    mp4_duration = get_duration(mp4_filename)
+
+    if abs(flv_duration - mp4_duration) > 1:
+        logging.error(
+            "The duration of %s is suspicious, did the remux fail? Expected %s == %s",
+            mp4_filename, flv_duration, mp4_duration
+        )
+        return False
+
+    return True
+
 def remux(infile, outfile):
     logging.info("Converting %s to mp4", infile)
-    cmd = generate_remux_cmd(infile, outfile)
+
+    ffmpeg = find_ffmpeg()
+    cmd = [
+        ffmpeg,
+        "-i", infile,
+        "-bsf:a", "aac_adtstoasc",
+        "-acodec", "copy",
+        "-vcodec", "copy",
+        outfile,
+    ]
     if not exec_subprocess(cmd):
-        # failed, error has already been logged
         return False
-    try:
-        flv_size = os.stat(infile).st_size
-        mp4_size = os.stat(outfile).st_size
-        if abs(flv_size - mp4_size) < 0.1 * flv_size:
-            os.unlink(infile)
-            return True
-        else:
-            logging.error("The size of %s is suspicious, did the remux fail?", outfile)
-            return False
-    except Exception as e:
-        logging.error("Conversion failed! %s", e)
+
+    if not check_video_durations(infile, outfile):
         return False
 
+    os.unlink(infile)
+    return True
+
 def convert_to_mp4(filename):
     with open(filename, "rb") as f:
         fourcc = f.read(4)
@@ -247,7 +280,7 @@ def download_hds(filename, video_url, pvswf=None):
     filename = sanify_filename(filename)
     logging.info("Downloading: %s", filename)
 
-    video_url = video_url.replace("http://", "hds://")
+    video_url = "hds://" + video_url
     if pvswf:
         param = "%s pvswf=%s" % (video_url, pvswf)
     else:
@@ -266,7 +299,7 @@ def download_hds(filename, video_url, pvswf=None):
 
 def download_hls(filename, video_url):
     filename = sanify_filename(filename)
-    video_url = video_url.replace("http://", "hlsvariant://")
+    video_url = "hlsvariant://" + video_url
     logging.info("Downloading: %s", filename)
 
     cmd = [