diff --git a/youtube_dl/extractor/streamme.py b/youtube_dl/extractor/streamme.py index b3eb1cc65..72ddd34ef 100644 --- a/youtube_dl/extractor/streamme.py +++ b/youtube_dl/extractor/streamme.py @@ -13,10 +13,10 @@ from ..utils import ( class StreamMeIE(InfoExtractor): IE_NAME = 'StreamMe:video' - _API_CHANNEL = 'https://www.stream.me/api-user/v1//channel' - _API_ARCHIVE = 'https://www.stream.me/api-vod/v1//archives' + _API_CHANNEL = 'https://www.stream.me/api-user/v1/%s/channel' + _API_ARCHIVE = 'https://www.stream.me/api-vod/v1/%s/archives' _VALID_URL_BASE = r'https?://(video-cdn|www).stream.me' - _VALID_URL = r'%s\/archive\/(?P[^\#\/]+)\/[^\/]+\/(?P[^\/]+)' % _VALID_URL_BASE + _VALID_URL = r'%s/archive\/(?P[^\#/]+)/[^\/]+/(?P[^/]+)' % _VALID_URL_BASE _TEST = { 'url': 'https://www.stream.me/archive/kombatcup/kombat-cup-week-8-sunday-open/pDlXAj6mYb', 'md5': 'b32af6fad972d0bcf5854a416b5b3b01', @@ -34,20 +34,18 @@ class StreamMeIE(InfoExtractor): def _real_extract(self, url): m = re.match(self._VALID_URL, url) video_id = self._match_id(url) - apiurl = self._API_ARCHIVE.replace('', m.group('channel_id')) + apiurl = self._API_ARCHIVE % m.group('channel_id') - data = json.loads(self._download_webpage(apiurl, video_id)) + data = self._download_json(apiurl, video_id) - for vod in data.get('_embedded').get('vod'): + for vod in data['_embedded']['vod']: vod_info = [] if vod.get('urlId') == video_id: vod_info = vod break - manifest_json = self._download_json(vod_info - .get('_links') - .get('manifest') - .get('href'), video_id) + manifest_json = self._download_json(vod_info['_links']['manifest']['href'], + video_id, note='Downloading video manifest') formats = self._extract_formats(manifest_json.get('formats')) self._sort_formats(formats, 'vbr') @@ -57,19 +55,19 @@ class StreamMeIE(InfoExtractor): def _extract_info(self, info): return { - 'id': info.get('urlId') or 'live', + 'id': info.get('urlId') or info.get('publicId'), # 'formats': self.formats, - 'title': info.get('title'), + 'title': info.get('title') or 'Untitled Broadcast', 'age_limit': int_or_none(info.get('ageRating')), - 'description': info.get('description') or None, + 'description': info.get('description'), 'dislike_count': int_or_none(info.get('stats').get('raw').get('dislikes')), - 'display_id': info.get('titleSlug') or None, + 'display_id': info.get('titleSlug'), 'duration': int_or_none(info.get('duration')), 'like_count': int_or_none(info.get('stats').get('raw').get('likes')), - 'thumbnail': info.get('_links').get('thumbnail').get('href') or None, - 'timestamp': info.get('whenCreated') or None, - 'uploader': info.get('username') or None, - 'uploader_id': info.get('userSlug') or None, + 'thumbnail': info.get('_links').get('thumbnail').get('href'), + 'timestamp': info.get('whenCreated'), + 'uploader': info.get('username'), + 'uploader_id': info.get('userSlug'), 'view_count': int_or_none(info.get('stats').get('raw').get('views')), 'is_live': True if info.get('active') else False, } @@ -83,10 +81,10 @@ class StreamMeIE(InfoExtractor): for fmt_info in d.get('encodings'): formats.append({ 'url': fmt_info.get('location'), - 'width': fmt_info.get('videoWidth'), - 'height': fmt_info.get('videoHeight'), - 'vbr': fmt_info.get('videoKbps'), - 'abr': fmt_info.get('audioKbps'), + 'width': int_or_none(fmt_info.get('videoWidth')), + 'height': int_or_none(fmt_info.get('videoHeight')), + 'vbr': int_or_none(fmt_info.get('videoKbps')), + 'abr': int_or_none(fmt_info.get('audioKbps')), 'acodec': d.get('audioCodec'), 'vcodec': d.get('videoCodec'), 'format_id': "%s%sp" % (fmt_tag, fmt_info.get('videoHeight')), @@ -113,7 +111,7 @@ class StreamMeLiveIE(StreamMeIE): _TEST = { 'url': 'https://www.stream.me/kombatcup', 'info_dict': { - 'id': 'live', # see: StreamMeIE._extract_info() + 'id': '1246a915-eebe-4ffe-b12e-e4f5332abc4d', 'ext': 'mp4', 'title': 'KombatCup\'s Live Stream', 'age_limit': 13, @@ -131,7 +129,7 @@ class StreamMeLiveIE(StreamMeIE): def _real_extract(self, url): channel_id = self._match_id(url) - apiurl = StreamMeIE._API_CHANNEL.replace('', channel_id) + apiurl = StreamMeIE._API_CHANNEL % channel_id data = json.loads(self._download_webpage(apiurl, channel_id)) stream_info = [] @@ -143,10 +141,8 @@ class StreamMeLiveIE(StreamMeIE): if not stream_info.get('active'): raise ExtractorError('%s is offline' % channel_id, expected=True) - manifest_json = self._download_json(stream_info - .get('_links') - .get('manifest') - .get('href'), channel_id) + manifest_json = self._download_json(stream_info['_links']['manifest']['href'], + channel_id, 'Download video manifest') formats = self._extract_formats(manifest_json.get('formats')) self._sort_formats(formats, 'vbr') @@ -174,16 +170,13 @@ class StreamMeArchiveIE(StreamMeIE): def _real_extract(self, url): channel_id = self._match_id(url).split('#')[0] - apiurl = StreamMeIE._API_ARCHIVE.replace('', channel_id) + apiurl = StreamMeIE._API_ARCHIVE % channel_id # TODO: implement paginated downloading - data = json.loads(self._download_webpage(apiurl + '?limit=%d&offset=0' % self._PLAYLIST_LIMIT, channel_id)) + data = self._download_json(apiurl, channel_id, query={'limit': self._PLAYLIST_LIMIT, 'offset': 0}) playlist = [] - for vod in data.get('_embedded').get('vod'): - manifest_json = self._download_json(vod - .get('_links') - .get('manifest') - .get('href'), vod.get('urlId')) + for vod in data['_embedded']['vod']: + manifest_json = self._download_json(vod['_links']['manifest']['href'], vod.get('urlId')) formats = self._extract_formats(manifest_json.get('formats')) self._sort_formats(formats, 'vbr') info = self._extract_info(vod)