]> code.delx.au - webdl/commitdiff
support grabbing brightcove widevine videos - for channel 9
authorJames Bunton <jamesbunton@delx.net.au>
Sat, 30 May 2015 03:43:37 +0000 (13:43 +1000)
committerJames Bunton <jamesbunton@delx.net.au>
Sat, 30 May 2015 03:43:37 +0000 (13:43 +1000)
brightcove.py
common.py

index 082c92a0ad65991a952d32a0d90daa8bb7fb89a2..b34234a997bfbff5c5f2f20846de3966f2a11489 100644 (file)
@@ -2,7 +2,7 @@ import logging
 import re
 import sys
 
-from common import grab_json, download_hls, Node, append_to_qs
+from common import grab_json, download_hls, download_http, Node, append_to_qs
 
 CH9_TOKEN = "ogxhPgSphIVa2hhxbi9oqtYwtg032io4B4-ImwddYliFWHqS0UfMEw.."
 CH10_TOKEN = "lWCaZyhokufjqe7H4TLpXwHSTnNXtqHxyMvoNOsmYA_GRaZ4zcwysw.."
@@ -18,20 +18,54 @@ class BrightcoveVideoNode(Node):
         self.video_id = video_id
 
     def download(self):
+        f = None
+        try_streams = [self.try_widevine, self.try_hls]
+
+        while f is None and try_streams:
+            f = try_streams.pop()()
+
+        if f is None:
+            logging.error("No HLS or Widevine stream available for: %s", self.title)
+            return False
+
+        return f()
+
+    def try_hls(self):
         desc_url = append_to_qs(BRIGHTCOVE_API, {
             "token": self.token,
             "command": "find_video_by_id",
             "video_fields": "HLSURL",
             "video_id": self.video_id,
         })
+
         doc = grab_json(desc_url, 3600)
         video_url = doc["HLSURL"]
         if not video_url:
-            logging.error("No HLS stream available for: %s", self.title)
-            return False
+            return
+
+        filename = self.title + ".ts"
+        return lambda: download_hls(filename, video_url)
+
+    def try_widevine(self):
+        desc_url = append_to_qs(BRIGHTCOVE_API, {
+            "token": self.token,
+            "command": "find_video_by_id",
+            "video_fields": "WVMRenditions",
+            "video_id": self.video_id,
+        })
 
+        doc = grab_json(desc_url, 3600)
+
+        renditions = doc["WVMRenditions"]
+        if not renditions:
+            return
+
+        best_rendition = sorted(renditions, key=lambda r: r["frameHeight"])[-1]
+        video_url = best_rendition["url"]
         filename = self.title + ".ts"
-        return download_hls(filename, video_url)
+
+        return lambda: download_http(filename, video_url)
+
 
 class BrightcoveRootNode(Node):
     def __init__(self, title, parent, token):
index daede5643f8cf90179dd8e30200b2d90fa6dd023..cabfd936c30f65e8fb11df8758888f455ac14222 100644 (file)
--- a/common.py
+++ b/common.py
@@ -280,6 +280,21 @@ def download_hls(filename, video_url):
     else:
         return False
 
+def download_http(filename, video_url):
+    filename = sanify_filename(filename)
+    logging.info("Downloading: %s", filename)
+
+    cmd = [
+        "curl",
+        "--fail", "--retry", "3",
+        "-o", filename,
+        video_url,
+    ]
+    if exec_subprocess(cmd):
+        return convert_to_mp4(filename)
+    else:
+        return False
+
 def natural_sort(l, key=None):
     ignore_list = ["a", "the"]
     def key_func(k):