From 9b4184489b7012618185f519c21ac6c7766d384f Mon Sep 17 00:00:00 2001 From: Marcus Soll Date: Fri, 29 May 2015 12:33:40 +0200 Subject: [PATCH 1/2] Added plugin for blip.tv VOD --- docs/plugin_matrix.rst | 1 + src/livestreamer/plugins/bliptv.py | 60 ++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100755 src/livestreamer/plugins/bliptv.py diff --git a/docs/plugin_matrix.rst b/docs/plugin_matrix.rst index 673f9cc9..a7a4da14 100755 --- a/docs/plugin_matrix.rst +++ b/docs/plugin_matrix.rst @@ -23,6 +23,7 @@ azubutv azubu.tv Yes No beam beam.pro Yes No beattv be-at.tv Yes Yes Playlist not implemented yet. bambuser bambuser.com Yes Yes +bliptv blip.tv -- Yes chaturbate chaturbate.com Yes No connectcast connectcast.tv Yes Yes crunchyroll crunchyroll.com -- Yes diff --git a/src/livestreamer/plugins/bliptv.py b/src/livestreamer/plugins/bliptv.py new file mode 100755 index 00000000..7130b3dc --- /dev/null +++ b/src/livestreamer/plugins/bliptv.py @@ -0,0 +1,60 @@ +import re + +from livestreamer.plugin import Plugin, PluginError +from livestreamer.plugin.api import http +from livestreamer.stream import HTTPStream + +_url_re = re.compile("(http(s)?://)?blip.tv/.*-(?P\d+)") +VIDEO_GET_URL = 'http://player.blip.tv/file/get/{0}' +SINGLE_VIDEO_URL = '.*\.((mp4)|(mov)|(m4v)|(flv))' + + +def get_quality_dict(quality_list): + quality_list.sort() + quality_dict = {} + i = 0 + for bitrate in quality_list: + if i == 0: + quality_dict['%i' % bitrate] = 'low' + elif i == 1: + quality_dict['%i' % bitrate] = 'medium' + elif i == 2: + quality_dict['%i' % bitrate] = 'high' + elif i == 3: + quality_dict['%i' % bitrate] = 'ultra' + else: + quality_dict['%i' % bitrate] = 'ultra+_%i' % (i-3) + i += 1 + return quality_dict + + +class bliptv(Plugin): + @classmethod + def can_handle_url(cls, url): + return _url_re.match(url) + + def _get_streams(self): + match = _url_re.match(self.url) + videoid = match.group("videoid") + try: + get_return = http.get(VIDEO_GET_URL.format(videoid)) + except: + raise PluginError('Can not get video information from blip.tv for id %s' % videoid) + json_decode = http.json(get_return) + streams = {} + quality_list = [] + for stream in json_decode: + if re.compile(SINGLE_VIDEO_URL).match(stream['direct_url']): + quality_list.append(int(stream['video_bitrate'])) + if len(quality_list) == 0: + raise PluginError('No videos on blip.tv found for id %s' % videoid) + quality_dict = get_quality_dict(quality_list) + for stream in json_decode: + if re.compile(SINGLE_VIDEO_URL).match(stream['direct_url']): + streams[quality_dict[stream['video_bitrate']]] = HTTPStream(self.session, stream['direct_url']) + quality_list.sort() + streams['worst'] = streams[quality_dict['%i' % quality_list[0]]] + streams['best'] = streams[quality_dict['%i' % quality_list[-1]]] + return streams + +__plugin__ = bliptv From d8a664f78ffc8b157db143ae596ef6210ee6b091 Mon Sep 17 00:00:00 2001 From: Marcus Soll Date: Sat, 30 May 2015 17:20:30 +0200 Subject: [PATCH 2/2] Updated blip.tv plugin Fixed flaws according to https://github.com/chrippa/livestreamer/pull/936 --- src/livestreamer/plugins/bliptv.py | 41 ++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 14 deletions(-) mode change 100755 => 100644 src/livestreamer/plugins/bliptv.py diff --git a/src/livestreamer/plugins/bliptv.py b/src/livestreamer/plugins/bliptv.py old mode 100755 new mode 100644 index 7130b3dc..d8c38648 --- a/src/livestreamer/plugins/bliptv.py +++ b/src/livestreamer/plugins/bliptv.py @@ -6,14 +6,23 @@ _url_re = re.compile("(http(s)?://)?blip.tv/.*-(?P\d+)") VIDEO_GET_URL = 'http://player.blip.tv/file/get/{0}' -SINGLE_VIDEO_URL = '.*\.((mp4)|(mov)|(m4v)|(flv))' +SINGLE_VIDEO_URL = re.compile('.*\.((mp4)|(mov)|(m4v)|(flv))') + +QUALITY_WEIGHTS = { + "ultra": 1080, + "high": 720, + "medium": 480, + "low": 240, +} + +QUALITY_WEIGHTS_ULTRA = re.compile('ultra+_(?P\d+)') def get_quality_dict(quality_list): quality_list.sort() quality_dict = {} i = 0 - for bitrate in quality_list: + for i, bitrate in enumerate(quality_list): if i == 0: quality_dict['%i' % bitrate] = 'low' elif i == 1: @@ -24,7 +33,6 @@ def get_quality_dict(quality_list): quality_dict['%i' % bitrate] = 'ultra' else: quality_dict['%i' % bitrate] = 'ultra+_%i' % (i-3) - i += 1 return quality_dict @@ -33,28 +41,33 @@ class bliptv(Plugin): def can_handle_url(cls, url): return _url_re.match(url) + @classmethod + def stream_weight(cls, key): + match_ultra = QUALITY_WEIGHTS_ULTRA.match(key) + if match_ultra: + ultra_level = int(match_ultra.group('level')) + return 1080 * (ultra_level + 1), "bliptv" + weight = QUALITY_WEIGHTS.get(key) + if weight: + return weight, "bliptv" + return Plugin.stream_weight(key) + def _get_streams(self): match = _url_re.match(self.url) - videoid = match.group("videoid") - try: - get_return = http.get(VIDEO_GET_URL.format(videoid)) - except: - raise PluginError('Can not get video information from blip.tv for id %s' % videoid) + videoid = match.group('videoid') + get_return = http.get(VIDEO_GET_URL.format(videoid)) json_decode = http.json(get_return) streams = {} quality_list = [] for stream in json_decode: - if re.compile(SINGLE_VIDEO_URL).match(stream['direct_url']): + if SINGLE_VIDEO_URL.match(stream['direct_url']): quality_list.append(int(stream['video_bitrate'])) if len(quality_list) == 0: - raise PluginError('No videos on blip.tv found for id %s' % videoid) + return quality_dict = get_quality_dict(quality_list) for stream in json_decode: - if re.compile(SINGLE_VIDEO_URL).match(stream['direct_url']): + if SINGLE_VIDEO_URL.match(stream['direct_url']): streams[quality_dict[stream['video_bitrate']]] = HTTPStream(self.session, stream['direct_url']) - quality_list.sort() - streams['worst'] = streams[quality_dict['%i' % quality_list[0]]] - streams['best'] = streams[quality_dict['%i' % quality_list[-1]]] return streams __plugin__ = bliptv