Compare commits

..

No commits in common. "281b8e34432d8dba9902be2c1eb77d3e6371cd73" and "72a2c0a9ede04c6b82235e453b1a933faf072a76" have entirely different histories.

2 changed files with 78 additions and 99 deletions

View File

@ -25,12 +25,12 @@ class CuriosityStreamBaseIE(InfoExtractor):
raise ExtractorError( raise ExtractorError(
'%s said: %s' % (self.IE_NAME, error), expected=True) '%s said: %s' % (self.IE_NAME, error), expected=True)
def _call_api(self, path, video_id, query=None): def _call_api(self, path, video_id):
headers = {} headers = {}
if self._auth_token: if self._auth_token:
headers['X-Auth-Token'] = self._auth_token headers['X-Auth-Token'] = self._auth_token
result = self._download_json( result = self._download_json(
self._API_BASE_URL + path, video_id, headers=headers, query=query) self._API_BASE_URL + path, video_id, headers=headers)
self._handle_errors(result) self._handle_errors(result)
return result['data'] return result['data']
@ -52,75 +52,62 @@ class CuriosityStreamIE(CuriosityStreamBaseIE):
_VALID_URL = r'https?://(?:app\.)?curiositystream\.com/video/(?P<id>\d+)' _VALID_URL = r'https?://(?:app\.)?curiositystream\.com/video/(?P<id>\d+)'
_TEST = { _TEST = {
'url': 'https://app.curiositystream.com/video/2', 'url': 'https://app.curiositystream.com/video/2',
'md5': '262bb2f257ff301115f1973540de8983',
'info_dict': { 'info_dict': {
'id': '2', 'id': '2',
'ext': 'mp4', 'ext': 'mp4',
'title': 'How Did You Develop The Internet?', 'title': 'How Did You Develop The Internet?',
'description': 'Vint Cerf, Google\'s Chief Internet Evangelist, describes how he and Bob Kahn created the internet.', 'description': 'Vint Cerf, Google\'s Chief Internet Evangelist, describes how he and Bob Kahn created the internet.',
}, }
'params': {
'format': 'bestvideo',
# m3u8 download
'skip_download': True,
},
} }
def _real_extract(self, url): def _real_extract(self, url):
video_id = self._match_id(url) video_id = self._match_id(url)
media = self._call_api('media/' + video_id, video_id)
title = media['title']
formats = [] formats = []
for encoding_format in ('m3u8', 'mpd'): for encoding in media.get('encodings', []):
media = self._call_api('media/' + video_id, video_id, query={ m3u8_url = encoding.get('master_playlist_url')
'encodingsNew': 'true', if m3u8_url:
'encodingsFormat': encoding_format, formats.extend(self._extract_m3u8_formats(
}) m3u8_url, video_id, 'mp4', 'm3u8_native',
for encoding in media.get('encodings', []): m3u8_id='hls', fatal=False))
playlist_url = encoding.get('master_playlist_url') encoding_url = encoding.get('url')
if encoding_format == 'm3u8': file_url = encoding.get('file_url')
# use `m3u8` entry_protocol until EXT-X-MAP is properly supported by `m3u8_native` entry_protocol if not encoding_url and not file_url:
formats.extend(self._extract_m3u8_formats( continue
playlist_url, video_id, 'mp4', f = {
m3u8_id='hls', fatal=False)) 'width': int_or_none(encoding.get('width')),
elif encoding_format == 'mpd': 'height': int_or_none(encoding.get('height')),
formats.extend(self._extract_mpd_formats( 'vbr': int_or_none(encoding.get('video_bitrate')),
playlist_url, video_id, mpd_id='dash', fatal=False)) 'abr': int_or_none(encoding.get('audio_bitrate')),
encoding_url = encoding.get('url') 'filesize': int_or_none(encoding.get('size_in_bytes')),
file_url = encoding.get('file_url') 'vcodec': encoding.get('video_codec'),
if not encoding_url and not file_url: 'acodec': encoding.get('audio_codec'),
'container': encoding.get('container_type'),
}
for f_url in (encoding_url, file_url):
if not f_url:
continue continue
f = { fmt = f.copy()
'width': int_or_none(encoding.get('width')), rtmp = re.search(r'^(?P<url>rtmpe?://(?P<host>[^/]+)/(?P<app>.+))/(?P<playpath>mp[34]:.+)$', f_url)
'height': int_or_none(encoding.get('height')), if rtmp:
'vbr': int_or_none(encoding.get('video_bitrate')), fmt.update({
'abr': int_or_none(encoding.get('audio_bitrate')), 'url': rtmp.group('url'),
'filesize': int_or_none(encoding.get('size_in_bytes')), 'play_path': rtmp.group('playpath'),
'vcodec': encoding.get('video_codec'), 'app': rtmp.group('app'),
'acodec': encoding.get('audio_codec'), 'ext': 'flv',
'container': encoding.get('container_type'), 'format_id': 'rtmp',
} })
for f_url in (encoding_url, file_url): else:
if not f_url: fmt.update({
continue 'url': f_url,
fmt = f.copy() 'format_id': 'http',
rtmp = re.search(r'^(?P<url>rtmpe?://(?P<host>[^/]+)/(?P<app>.+))/(?P<playpath>mp[34]:.+)$', f_url) })
if rtmp: formats.append(fmt)
fmt.update({
'url': rtmp.group('url'),
'play_path': rtmp.group('playpath'),
'app': rtmp.group('app'),
'ext': 'flv',
'format_id': 'rtmp',
})
else:
fmt.update({
'url': f_url,
'format_id': 'http',
})
formats.append(fmt)
self._sort_formats(formats) self._sort_formats(formats)
title = media['title']
subtitles = {} subtitles = {}
for closed_caption in media.get('closed_captions', []): for closed_caption in media.get('closed_captions', []):
sub_url = closed_caption.get('file') sub_url = closed_caption.get('file')
@ -153,7 +140,7 @@ class CuriosityStreamCollectionIE(CuriosityStreamBaseIE):
'title': 'Curious Minds: The Internet', 'title': 'Curious Minds: The Internet',
'description': 'How is the internet shaping our lives in the 21st Century?', 'description': 'How is the internet shaping our lives in the 21st Century?',
}, },
'playlist_mincount': 16, 'playlist_mincount': 17,
}, { }, {
'url': 'https://curiositystream.com/series/2', 'url': 'https://curiositystream.com/series/2',
'only_matching': True, 'only_matching': True,

View File

@ -29,51 +29,34 @@ class JamendoIE(InfoExtractor):
'id': '196219', 'id': '196219',
'display_id': 'stories-from-emona-i', 'display_id': 'stories-from-emona-i',
'ext': 'flac', 'ext': 'flac',
# 'title': 'Maya Filipič - Stories from Emona I', 'title': 'Maya Filipič - Stories from Emona I',
'title': 'Stories from Emona I', 'artist': 'Maya Filipič',
# 'artist': 'Maya Filipič',
'track': 'Stories from Emona I', 'track': 'Stories from Emona I',
'duration': 210, 'duration': 210,
'thumbnail': r're:^https?://.*\.jpg', 'thumbnail': r're:^https?://.*\.jpg',
'timestamp': 1217438117, 'timestamp': 1217438117,
'upload_date': '20080730', 'upload_date': '20080730',
'license': 'by-nc-nd',
'view_count': int,
'like_count': int,
'average_rating': int,
'tags': ['piano', 'peaceful', 'newage', 'strings', 'upbeat'],
} }
}, { }, {
'url': 'https://licensing.jamendo.com/en/track/1496667/energetic-rock', 'url': 'https://licensing.jamendo.com/en/track/1496667/energetic-rock',
'only_matching': True, 'only_matching': True,
}] }]
def _call_api(self, resource, resource_id):
path = '/api/%ss' % resource
rand = compat_str(random.random())
return self._download_json(
'https://www.jamendo.com' + path, resource_id, query={
'id[]': resource_id,
}, headers={
'X-Jam-Call': '$%s*%s~' % (hashlib.sha1((path + rand).encode()).hexdigest(), rand)
})[0]
def _real_extract(self, url): def _real_extract(self, url):
track_id, display_id = self._VALID_URL_RE.match(url).groups() track_id, display_id = self._VALID_URL_RE.match(url).groups()
# webpage = self._download_webpage( webpage = self._download_webpage(
# 'https://www.jamendo.com/track/' + track_id, track_id) 'https://www.jamendo.com/track/' + track_id, track_id)
# models = self._parse_json(self._html_search_regex( models = self._parse_json(self._html_search_regex(
# r"data-bundled-models='([^']+)", r"data-bundled-models='([^']+)",
# webpage, 'bundled models'), track_id) webpage, 'bundled models'), track_id)
# track = models['track']['models'][0] track = models['track']['models'][0]
track = self._call_api('track', track_id)
title = track_name = track['name'] title = track_name = track['name']
# get_model = lambda x: try_get(models, lambda y: y[x]['models'][0], dict) or {} get_model = lambda x: try_get(models, lambda y: y[x]['models'][0], dict) or {}
# artist = get_model('artist') artist = get_model('artist')
# artist_name = artist.get('name') artist_name = artist.get('name')
# if artist_name: if artist_name:
# title = '%s - %s' % (artist_name, title) title = '%s - %s' % (artist_name, title)
# album = get_model('album') album = get_model('album')
formats = [{ formats = [{
'url': 'https://%s.jamendo.com/?trackid=%s&format=%s&from=app-97dab294' 'url': 'https://%s.jamendo.com/?trackid=%s&format=%s&from=app-97dab294'
@ -91,7 +74,7 @@ class JamendoIE(InfoExtractor):
urls = [] urls = []
thumbnails = [] thumbnails = []
for covers in (track.get('cover') or {}).values(): for _, covers in track.get('cover', {}).items():
for cover_id, cover_url in covers.items(): for cover_id, cover_url in covers.items():
if not cover_url or cover_url in urls: if not cover_url or cover_url in urls:
continue continue
@ -105,14 +88,13 @@ class JamendoIE(InfoExtractor):
}) })
tags = [] tags = []
for tag in (track.get('tags') or []): for tag in track.get('tags', []):
tag_name = tag.get('name') tag_name = tag.get('name')
if not tag_name: if not tag_name:
continue continue
tags.append(tag_name) tags.append(tag_name)
stats = track.get('stats') or {} stats = track.get('stats') or {}
license = track.get('licenseCC') or []
return { return {
'id': track_id, 'id': track_id,
@ -121,11 +103,11 @@ class JamendoIE(InfoExtractor):
'title': title, 'title': title,
'description': track.get('description'), 'description': track.get('description'),
'duration': int_or_none(track.get('duration')), 'duration': int_or_none(track.get('duration')),
# 'artist': artist_name, 'artist': artist_name,
'track': track_name, 'track': track_name,
# 'album': album.get('name'), 'album': album.get('name'),
'formats': formats, 'formats': formats,
'license': '-'.join(license) if license else None, 'license': '-'.join(track.get('licenseCC', [])) or None,
'timestamp': int_or_none(track.get('dateCreated')), 'timestamp': int_or_none(track.get('dateCreated')),
'view_count': int_or_none(stats.get('listenedAll')), 'view_count': int_or_none(stats.get('listenedAll')),
'like_count': int_or_none(stats.get('favorited')), 'like_count': int_or_none(stats.get('favorited')),
@ -134,9 +116,9 @@ class JamendoIE(InfoExtractor):
} }
class JamendoAlbumIE(JamendoIE): class JamendoAlbumIE(InfoExtractor):
_VALID_URL = r'https?://(?:www\.)?jamendo\.com/album/(?P<id>[0-9]+)' _VALID_URL = r'https?://(?:www\.)?jamendo\.com/album/(?P<id>[0-9]+)'
_TESTS = [{ _TEST = {
'url': 'https://www.jamendo.com/album/121486/duck-on-cover', 'url': 'https://www.jamendo.com/album/121486/duck-on-cover',
'info_dict': { 'info_dict': {
'id': '121486', 'id': '121486',
@ -169,7 +151,17 @@ class JamendoAlbumIE(JamendoIE):
'params': { 'params': {
'playlistend': 2 'playlistend': 2
} }
}] }
def _call_api(self, resource, resource_id):
path = '/api/%ss' % resource
rand = compat_str(random.random())
return self._download_json(
'https://www.jamendo.com' + path, resource_id, query={
'id[]': resource_id,
}, headers={
'X-Jam-Call': '$%s*%s~' % (hashlib.sha1((path + rand).encode()).hexdigest(), rand)
})[0]
def _real_extract(self, url): def _real_extract(self, url):
album_id = self._match_id(url) album_id = self._match_id(url)
@ -177,7 +169,7 @@ class JamendoAlbumIE(JamendoIE):
album_name = album.get('name') album_name = album.get('name')
entries = [] entries = []
for track in (album.get('tracks') or []): for track in album.get('tracks', []):
track_id = track.get('id') track_id = track.get('id')
if not track_id: if not track_id:
continue continue