diff options
author | Christopher Rosell <chrippa@tanuki.se> | 2012-10-04 14:12:37 +0200 |
---|---|---|
committer | Christopher Rosell <chrippa@tanuki.se> | 2012-10-04 14:14:21 +0200 |
commit | 1e429862787d1c50998aa03a648739133637afee (patch) | |
tree | 24abd1b2797e7bac99a097da9321183d1a530a24 | |
parent | 1af7ca5f01989565fefe3bbfb4e5a387f0558602 (diff) |
Add Livestream.com plugin (only the new version).
-rw-r--r-- | src/livestreamer/plugins/livestream.py | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/livestreamer/plugins/livestream.py b/src/livestreamer/plugins/livestream.py new file mode 100644 index 0000000..119f43c --- /dev/null +++ b/src/livestreamer/plugins/livestream.py @@ -0,0 +1,89 @@ +from livestreamer.stream import AkamaiHDStream +from livestreamer.plugins import Plugin, PluginError, NoStreamsError +from livestreamer.utils import urlget, verifyjson + +import json +import re +import xml.dom.minidom + +class Livestream(Plugin): + @classmethod + def can_handle_url(self, url): + return "new.livestream.com" in url + + def _get_stream_info(self): + res = urlget(self.url) + + match = re.search("var initialData = ({.+})", res.text) + + if match: + config = match.group(1) + + try: + parsed = json.loads(config) + except ValueError as err: + raise PluginError(("Unable to parse config JSON: {0})").format(err)) + + return parsed + + def _parse_smil(self, url): + res = urlget(url) + + try: + dom = xml.dom.minidom.parseString(res.text) + except Exception as err: + raise PluginError(("Unable to parse config XML: {0})").format(err)) + + httpbase = None + streams = {} + + for meta in dom.getElementsByTagName("meta"): + if meta.getAttribute("name") == "httpBase": + httpbase = meta.getAttribute("content") + break + + if not httpbase: + raise PluginError("Missing HTTP base in SMIL") + + for video in dom.getElementsByTagName("video"): + url = "{0}/{1}".format(httpbase, video.getAttribute("src")) + bitrate = int(video.getAttribute("system-bitrate")) + streams[bitrate] = AkamaiHDStream(self.session, url) + + return streams + + def _get_streams(self): + self.logger.debug("Fetching stream info") + info = self._get_stream_info() + + if not info: + raise NoStreamsError(self.url) + + streaminfo = verifyjson(info, "stream_info") + + if not streaminfo: + raise NoStreamsError(self.url) + + qualities = verifyjson(streaminfo, "qualities") + + streams = {} + + if not streaminfo["is_live"]: + raise NoStreamsError(self.url) + + if "play_url" in streaminfo: + smil = self._parse_smil(streaminfo["play_url"]) + + for bitrate, stream in smil.items(): + sname = "{0}k".format(bitrate/1000) + + for quality in qualities: + if quality["bitrate"] == bitrate: + sname = "{0}p".format(quality["height"]) + + streams[sname] = stream + + return streams + + +__plugin__ = Livestream |