+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):
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):
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"]:
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()
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, {
def fill_nodes(root_node):
- Ch9RootNode(root_node)
+ # Ch9RootNode(root_node) -- Need a new API token
Ch10RootNode(root_node)