|
|
@ -91,6 +91,15 @@ class RoosterTeethIE(RoosterTeethBaseIE):
|
|
|
|
'thumbnail': r're:^https?://.*\.png$',
|
|
|
|
'thumbnail': r're:^https?://.*\.png$',
|
|
|
|
'series': 'Million Dollars, But...',
|
|
|
|
'series': 'Million Dollars, But...',
|
|
|
|
'episode': 'Million Dollars, But... The Game Announcement',
|
|
|
|
'episode': 'Million Dollars, But... The Game Announcement',
|
|
|
|
|
|
|
|
'tags': ['Game Show', 'Sketch'],
|
|
|
|
|
|
|
|
'season_number': 2,
|
|
|
|
|
|
|
|
'availability': 'public',
|
|
|
|
|
|
|
|
'episode_number': 10,
|
|
|
|
|
|
|
|
'episode_id': '00374575-464e-11e7-a302-065410f210c4',
|
|
|
|
|
|
|
|
'season': 'Season 2',
|
|
|
|
|
|
|
|
'season_id': 'ffa27d48-464d-11e7-a302-065410f210c4',
|
|
|
|
|
|
|
|
'channel_id': '92b6bb21-91d2-4b1b-bf95-3268fa0d9939',
|
|
|
|
|
|
|
|
'duration': 145,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
'params': {'skip_download': True},
|
|
|
|
'params': {'skip_download': True},
|
|
|
|
}, {
|
|
|
|
}, {
|
|
|
@ -104,6 +113,15 @@ class RoosterTeethIE(RoosterTeethBaseIE):
|
|
|
|
'channel_id': '92f780eb-ebfe-4bf5-a3b5-c6ad5460a5f1',
|
|
|
|
'channel_id': '92f780eb-ebfe-4bf5-a3b5-c6ad5460a5f1',
|
|
|
|
'thumbnail': r're:^https?://.*\.(png|jpe?g)$',
|
|
|
|
'thumbnail': r're:^https?://.*\.(png|jpe?g)$',
|
|
|
|
'ext': 'mp4',
|
|
|
|
'ext': 'mp4',
|
|
|
|
|
|
|
|
'availability': 'public',
|
|
|
|
|
|
|
|
'episode_id': 'f8117b13-f068-499e-803e-eec9ea2dec8c',
|
|
|
|
|
|
|
|
'episode_number': 3,
|
|
|
|
|
|
|
|
'tags': ['Animation'],
|
|
|
|
|
|
|
|
'season_id': '4b8f0a9e-12c4-41ed-8caa-fed15a85bab8',
|
|
|
|
|
|
|
|
'season': 'Season 1',
|
|
|
|
|
|
|
|
'series': 'RWBY: World of Remnant',
|
|
|
|
|
|
|
|
'season_number': 1,
|
|
|
|
|
|
|
|
'duration': 216,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
'params': {'skip_download': True},
|
|
|
|
'params': {'skip_download': True},
|
|
|
|
}, {
|
|
|
|
}, {
|
|
|
@ -133,10 +151,10 @@ class RoosterTeethIE(RoosterTeethBaseIE):
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
video_data = self._download_json(
|
|
|
|
video_data = self._download_json(
|
|
|
|
api_episode_url + '/videos', display_id,
|
|
|
|
api_episode_url + '/videos', display_id, 'Downloading video JSON metadata',
|
|
|
|
'Downloading video JSON metadata')['data'][0]
|
|
|
|
headers={'Client-Type': 'web'})['data'][0] # web client-type yields ad-free streams
|
|
|
|
m3u8_url = video_data['attributes']['url']
|
|
|
|
m3u8_url = video_data['attributes']['url']
|
|
|
|
# XXX: additional URL at video_data['links']['download']
|
|
|
|
# XXX: additional ad-free URL at video_data['links']['download'] but often gives 403 errors
|
|
|
|
except ExtractorError as e:
|
|
|
|
except ExtractorError as e:
|
|
|
|
if isinstance(e.cause, HTTPError) and e.cause.status == 403:
|
|
|
|
if isinstance(e.cause, HTTPError) and e.cause.status == 403:
|
|
|
|
if self._parse_json(e.cause.response.read().decode(), display_id).get('access') is False:
|
|
|
|
if self._parse_json(e.cause.response.read().decode(), display_id).get('access') is False:
|
|
|
|