]> code.delx.au - webdl/blobdiff - brightcove.py
sbs: always access release_url over http
[webdl] / brightcove.py
index 4933adc1645f548f0efd05edc68975803d80fcb7..efb961b0022f12391cf1968bbbe38eeffd866e1c 100644 (file)
@@ -1,13 +1,13 @@
+import logging
 import re
 import sys
 
-from common import grab_json, download_rtmp, Node, append_to_qs
+from common import grab_json, download_hls, download_hds, Node, append_to_qs
 
 CH9_TOKEN = "ogxhPgSphIVa2hhxbi9oqtYwtg032io4B4-ImwddYliFWHqS0UfMEw.."
-CH10_TOKEN = "lWCaZyhokufjqe7H4TLpXwHSTnNXtqHxyMvoNOsmYA_GRaZ4zcwysw.."
+CH10_TOKEN = "90QPG7lQuLJAc4s82qA-T_UoDhz_VBFK6SGstWDB0jZH8eu1SZQDFA.."
 
 BRIGHTCOVE_API = "http://api.brightcove.com/services/library?"
-HASH_URL = "http://admin.brightcove.com/viewer/us20130530.1140/connection/ExternalConnection_2.swf"
 
 
 class BrightcoveVideoNode(Node):
@@ -18,30 +18,49 @@ class BrightcoveVideoNode(Node):
         self.video_id = video_id
 
     def download(self):
+        f = None
+        try_streams = [self.try_hds, self.try_hls]
+
+        while f is None and try_streams:
+            f = try_streams.pop()()
+
+        if f is None:
+            logging.error("No HLS or HDS 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": "renditions",
+            "video_fields": "HLSURL",
             "video_id": self.video_id,
         })
-        print "video desc_url", desc_url
 
-        doc = grab_json(desc_url, 3600)
+        doc = grab_json(desc_url)
+        video_url = doc and doc["HLSURL"]
+        if not video_url:
+            return
+
+        filename = self.title + ".ts"
+        return lambda: download_hls(filename, video_url)
 
-        best_encoding_rate = 0
-        best_url = None
-        for item in doc['renditions']:
-            encoding_rate = item['encodingRate']
-            if encoding_rate > best_encoding_rate:
-                best_encoding_rate = encoding_rate
-                best_url = item['url']
+    def try_hds(self):
+        desc_url = append_to_qs(BRIGHTCOVE_API, {
+            "token": self.token,
+            "command": "find_video_by_id",
+            "video_fields": "hdsManifestUrl",
+            "video_id": self.video_id,
+        })
 
-        if best_url is None:
-            raise Exception("Could not find video URL: " + desc_url)
+        doc = grab_json(desc_url)
+        video_url = doc and doc["hdsManifestUrl"]
+        if not video_url:
+            return
 
-        vbase, vpath = best_url.split("&")
-        filename = self.title + ".mp4"
-        return download_rtmp(filename, vbase, vpath, HASH_URL)
+        filename = self.title + ".flv"
+        return lambda: download_hds(filename, video_url)
 
 
 class BrightcoveRootNode(Node):
@@ -62,19 +81,16 @@ class BrightcoveRootNode(Node):
     def fill_children(self):
         page_number = 0
         while page_number < 100:
-            sys.stdout.write(".")
-            sys.stdout.flush()
             url = self.get_all_videos_url(page_number)
             page_number += 1
 
-            page = grab_json(url, 3600)
+            page = grab_json(url)
             items = page["items"]
             if len(items) == 0:
                 break
 
             for video_desc in items:
                 self.process_video(video_desc)
-        print
 
     def process_video(self, video_desc):
         if not video_desc["customFields"]:
@@ -103,9 +119,9 @@ class Ch9RootNode(BrightcoveRootNode):
 
     def get_video_title(self, video_desc):
         title = video_desc["name"]
-        series = video_desc["customFields"]["series"]
         season = video_desc["customFields"].get("season", "")
         episode = video_desc["customFields"].get("episode", "1").rjust(2, "0")
+        series = self.get_series_name(video_desc)
 
         if re.match(R"ep(isode)?\s*[0-9]+\s*:", title.lower()):
             title = title.split(":", 1)[1].strip()
@@ -119,7 +135,10 @@ class Ch9RootNode(BrightcoveRootNode):
         return title
 
     def get_series_name(self, video_desc):
-        return video_desc["customFields"]["series"]
+        series = video_desc["customFields"].get("series", None)
+        if not series:
+            series = video_desc["name"]
+        return series
 
     def get_all_videos_url(self, page_number):
         return append_to_qs(BRIGHTCOVE_API, {
@@ -155,6 +174,6 @@ class Ch10RootNode(BrightcoveRootNode):
 
 
 def fill_nodes(root_node):
-    Ch9RootNode(root_node)
+    # Ch9RootNode(root_node) -- Need a new API token
     Ch10RootNode(root_node)