Skip to content

Commit a5b84f0

Browse files
author
oleksis
committed
Update youtube-dl 2020.12.22
1 parent eeceb3a commit a5b84f0

20 files changed

+1380
-664
lines changed

youtube_dl/extractor/anvato.py

Lines changed: 78 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,76 @@ class AnvatoIE(InfoExtractor):
116116
'anvato_scripps_app_ios_prod_409c41960c60b308db43c3cc1da79cab9f1c3d93': 'WPxj5GraLTkYCyj3M7RozLqIycjrXOEcDGFMIJPn',
117117
'EZqvRyKBJLrgpClDPDF8I7Xpdp40Vx73': '4OxGd2dEakylntVKjKF0UK9PDPYB6A9W',
118118
'M2v78QkpleXm9hPp9jUXI63x5vA6BogR': 'ka6K32k7ZALmpINkjJUGUo0OE42Md1BQ',
119-
'nbcu_nbcd_desktop_web_prod_93d8ead38ce2024f8f544b78306fbd15895ae5e6_secure': 'NNemUkySjxLyPTKvZRiGntBIjEyK8uqicjMakIaQ'
119+
'nbcu_nbcd_desktop_web_prod_93d8ead38ce2024f8f544b78306fbd15895ae5e6_secure': 'NNemUkySjxLyPTKvZRiGntBIjEyK8uqicjMakIaQ',
120+
'X8POa4zPPaKVZHqmWjuEzfP31b1QM9VN': 'Dn5vOY9ooDw7VSl9qztjZI5o0g08mA0z',
121+
'M2v78QkBMpNJlSPp9diX5F2PBmBy6Bog': 'ka6K32kyo7nDZfNkjQCGWf1lpApXMd1B',
122+
'bvJ0dQpav07l0hG5JgfVLF2dv1vARwpP': 'BzoQW24GrJZoJfmNodiJKSPeB9B8NOxj',
123+
'lxQMLg2XZKuEZaWgsqubBxV9INZ6bryY': 'Vm2Mx6noKds9jB71h6urazwlTG3m9x8l',
124+
'04EnjvXeoSmkbJ9ckPs7oY0mcxv7PlyN': 'aXERQP9LMfQVlEDsgGs6eEA1SWznAQ8P',
125+
'mQbO2ge6BFRWVPYCYpU06YvNt80XLvAX': 'E2BV1NGmasN5v7eujECVPJgwflnLPm2A',
126+
'g43oeBzJrCml7o6fa5fRL1ErCdeD8z4K': 'RX34mZ6zVH4Nr6whbxIGLv9WSbxEKo8V',
127+
'VQrDJoP7mtdBzkxhXbSPwGB1coeElk4x': 'j2VejQx0VFKQepAF7dI0mJLKtOVJE18z',
128+
'WxA5NzLRjCrmq0NUgaU5pdMDuZO7RJ4w': 'lyY5ADLKaIOLEgAsGQCveEMAcqnx3rY9',
129+
'M4lpMXB71ie0PjMCjdFzVXq0SeRVqz49': 'n2zVkOqaLIv3GbLfBjcwW51LcveWOZ2e',
130+
'dyDZGEqN8u8nkJZcJns0oxYmtP7KbGAn': 'VXOEqQW9BtEVLajfZQSLEqxgS5B7qn2D',
131+
'E7QNjrVY5u5mGvgu67IoDgV1CjEND8QR': 'rz8AaDmdKIkLmPNhB5ILPJnjS5PnlL8d',
132+
'a4zrqjoKlfzg0dwHEWtP31VqcLBpjm4g': 'LY9J16gwETdGWa3hjBu5o0RzuoQDjqXQ',
133+
'dQP5BZroMsMVLO1hbmT5r2Enu86GjxA6': '7XR3oOdbPF6x3PRFLDCq9RkgsRjAo48V',
134+
'M4lKNBO1NFe0PjMCj1tzVXq0SeRVqzA9': 'n2zoRqGLRUv3GbLfBmTwW51LcveWOZYe',
135+
'nAZ7MZdpGCGg1pqFEbsoJOz2C60mv143': 'dYJgdqA9aT4yojETqGi7yNgoFADxqmXP',
136+
'3y1MERYgOuE9NzbFgwhV6Wv2F0YKvbyz': '081xpZDQgC4VadLTavhWQxrku56DAgXV',
137+
'bmQvmEXr5HWklBMCZOcpE2Z3HBYwqGyl': 'zxXPbVNyMiMAZldhr9FkOmA0fl4aKr2v',
138+
'wA7oDNYldfr6050Hwxi52lPZiVlB86Ap': 'ZYK16aA7ni0d3l3c34uwpxD7CbReMm8Q',
139+
'g43MbKMWmFml7o7sJoSRkXxZiXRvJ3QK': 'RX3oBJonvs4Nr6rUWBCGn3matRGqJPXV',
140+
'mA9VdlqpLS0raGaSDvtoqNrBTzb8XY4q': '0XN4OjBD3fnW7r7IbmtJB4AyfOmlrE2r',
141+
'mAajOwgkGt17oGoFmEuklMP9H0GnW54d': 'lXbBLPGyzikNGeGujAuAJGjZiwLRxyXR',
142+
'vy8vjJ9kbUwrRqRu59Cj5dWZfzYErlAb': 'K8l7gpwaGcBpnAnCLNCmPZRdin3eaQX0',
143+
'xQMWBpR8oHEZaWaSMGUb0avOHjLVYn4Y': 'm2MrN4vEaf9jB7BFy5Srb40jTrN67AYl',
144+
'xyKEmVO3miRr6D6UVkt7oB8jtD6aJEAv': 'g2ddDebqDfqdgKgswyUKwGjbTWwzq923',
145+
'7Qk0wa2D9FjKapacoJF27aLvUDKkLGA0': 'b2kgBEkephJaMkMTL7s1PLe4Ua6WyP2P',
146+
'3QLg6nqmNTJ5VvVTo7f508LPidz1xwyY': 'g2L1GgpraipmAOAUqmIbBnPxHOmw4MYa',
147+
'3y1B7zZjXTE9NZNSzZSVNPZaTNLjo6Qz': '081b5G6wzH4VagaURmcWbN5mT4JGEe2V',
148+
'lAqnwvkw6SG6D8DSqmUg6DRLUp0w3G4x': 'O2pbP0xPDFNJjpjIEvcdryOJtpkVM4X5',
149+
'awA7xd1N0Hr6050Hw2c52lPZiVlB864p': 'GZYKpn4aoT0d3l3c3PiwpxD7CbReMmXQ',
150+
'jQVqPLl9YHL1WGWtR1HDgWBGT63qRNyV': '6X03ne6vrU4oWyWUN7tQVoajikxJR3Ye',
151+
'GQRMR8mL7uZK797t7xH3eNzPIP5dOny1': 'm2vqPWGd4U31zWzSyasDRAoMT1PKRp8o',
152+
'zydq9RdmRhXLkNkfNoTJlMzaF0lWekQB': '3X7LnvE7vH5nkEkSqLiey793Un7dLB8e',
153+
'VQrDzwkB2IdBzjzu9MHPbEYkSB50gR4x': 'j2VebLzoKUKQeEesmVh0gM1eIp9jKz8z',
154+
'mAa2wMamBs17oGoFmktklMP9H0GnW54d': 'lXbgP74xZTkNGeGujVUAJGjZiwLRxy8R',
155+
'7yjB6ZLG6sW8R6RF2xcan1KGfJ5dNoyd': 'wXQkPorvPHZ45N5t4Jf6qwg5Tp4xvw29',
156+
'a4zPpNeWGuzg0m0iX3tPeanGSkRKWXQg': 'LY9oa3QAyHdGW9Wu3Ri5JGeEik7l1N8Q',
157+
'k2rneA2M38k25cXDwwSknTJlxPxQLZ6M': '61lyA2aEVDzklfdwmmh31saPxQx2VRjp',
158+
'bK9Zk4OvPnvxduLgxvi8VUeojnjA02eV': 'o5jANYjbeMb4nfBaQvcLAt1jzLzYx6ze',
159+
'5VD6EydM3R9orHmNMGInGCJwbxbQvGRw': 'w3zjmX7g4vnxzCxElvUEOiewkokXprkZ',
160+
'70X35QbVYVYNPUmP9YfbzI06YqYQk2R1': 'vG4Aj2BMjMjoztB7zeFOnCVPJpJ8lMOa',
161+
'26qYwQVG9p1Bks2GgBckjfDJOXOAMgG1': 'r4ev9X0mv5zqJc0yk5IBDcQOwZw8mnwQ',
162+
'rvVKpA56MBXWlSxMw3cobT5pdkd4Dm7q': '1J7ZkY53pZ645c93owcLZuveE7E8B3rL',
163+
'qN1zdy1zlYL23IWZGWtDvfV6WeWQWkJo': 'qN1zdy1zlYL23IWZGWtDvfV6WeWQWkJo',
164+
'jdKqRGF16dKsBviMDae7IGDl7oTjEbVV': 'Q09l7vhlNxPFErIOK6BVCe7KnwUW5DVV',
165+
'3QLkogW1OUJ5VvPsrDH56DY2u7lgZWyY': 'g2LRE1V9espmAOPhE4ubj4ZdUA57yDXa',
166+
'wyJvWbXGBSdbkEzhv0CW8meou82aqRy8': 'M2wolPvyBIpQGkbT4juedD4ruzQGdK2y',
167+
'7QkdZrzEkFjKap6IYDU2PB0oCNZORmA0': 'b2kN1l96qhJaMkPs9dt1lpjBfwqZoA8P',
168+
'pvA05113MHG1w3JTYxc6DVlRCjErVz4O': 'gQXeAbblBUnDJ7vujbHvbRd1cxlz3AXO',
169+
'mA9blJDZwT0raG1cvkuoeVjLC7ZWd54q': '0XN9jRPwMHnW7rvumgfJZOD9CJgVkWYr',
170+
'5QwRN5qKJTvGKlDTmnf7xwNZcjRmvEy9': 'R2GP6LWBJU1QlnytwGt0B9pytWwAdDYy',
171+
'eyn5rPPbkfw2KYxH32fG1q58CbLJzM40': 'p2gyqooZnS56JWeiDgfmOy1VugOQEBXn',
172+
'3BABn3b5RfPJGDwilbHe7l82uBoR05Am': '7OYZG7KMVhbPdKJS3xcWEN3AuDlLNmXj',
173+
'xA5zNGXD3HrmqMlF6OS5pdMDuZO7RJ4w': 'yY5DAm6r1IOLE3BCVMFveEMAcqnx3r29',
174+
'g43PgW3JZfml7o6fDEURL1ErCdeD8zyK': 'RX3aQn1zrS4Nr6whDgCGLv9WSbxEKo2V',
175+
'lAqp8WbGgiG6D8LTKJcg3O72CDdre1Qx': 'O2pnm6473HNJjpKuVosd3vVeh975yrX5',
176+
'wyJbYEDxKSdbkJ6S6RhW8meou82aqRy8': 'M2wPm7EgRSpQGlAh70CedD4ruzQGdKYy',
177+
'M4lgW28nLCe0PVdtaXszVXq0SeRVqzA9': 'n2zmJvg4jHv3G0ETNgiwW51LcveWOZ8e',
178+
'5Qw3OVvp9FvGKlDTmOC7xwNZcjRmvEQ9': 'R2GzDdml9F1Qlnytw9s0B9pytWwAdD8y',
179+
'vy8a98X7zCwrRqbHrLUjYzwDiK2b70Qb': 'K8lVwzyjZiBpnAaSGeUmnAgxuGOBxmY0',
180+
'g4eGjJLLoiqRD3Pf9oT5O03LuNbLRDQp': '6XqD59zzpfN4EwQuaGt67qNpSyRBlnYy',
181+
'g43OPp9boIml7o6fDOIRL1ErCdeD8z4K': 'RX33alNB4s4Nr6whDPUGLv9WSbxEKoXV',
182+
'xA2ng9OkBcGKzDbTkKsJlx7dUK8R3dA5': 'z2aPnJvzBfObkwGC3vFaPxeBhxoMqZ8K',
183+
'xyKEgBajZuRr6DEC0Kt7XpD1cnNW9gAv': 'g2ddlEBvRsqdgKaI4jUK9PrgfMexGZ23',
184+
'BAogww51jIMa2JnH1BcYpXM5F658RNAL': 'rYWDmm0KptlkGv4FGJFMdZmjs9RDE6XR',
185+
'BAokpg62VtMa2JnH1mHYpXM5F658RNAL': 'rYWryDnlNslkGv4FG4HMdZmjs9RDE62R',
186+
'a4z1Px5e2hzg0m0iMMCPeanGSkRKWXAg': 'LY9eorNQGUdGW9WuKKf5JGeEik7l1NYQ',
187+
'kAx69R58kF9nY5YcdecJdl2pFXP53WyX': 'gXyRxELpbfPvLeLSaRil0mp6UEzbZJ8L',
188+
'BAoY13nwViMa2J2uo2cY6BlETgmdwryL': 'rYWwKzJmNFlkGvGtNoUM9bzwIJVzB1YR',
120189
}
121190

122191
_MCP_TO_ACCESS_KEY_TABLE = {
@@ -189,19 +258,17 @@ def _get_video_json(self, access_key, video_id):
189258

190259
video_data_url += '&X-Anvato-Adst-Auth=' + base64.b64encode(auth_secret).decode('ascii')
191260
anvrid = md5_text(time.time() * 1000 * random.random())[:30]
192-
payload = {
193-
'api': {
194-
'anvrid': anvrid,
195-
'anvstk': md5_text('%s|%s|%d|%s' % (
196-
access_key, anvrid, server_time,
197-
self._ANVACK_TABLE.get(access_key, self._API_KEY))),
198-
'anvts': server_time,
199-
},
261+
api = {
262+
'anvrid': anvrid,
263+
'anvts': server_time,
200264
}
265+
api['anvstk'] = md5_text('%s|%s|%d|%s' % (
266+
access_key, anvrid, server_time,
267+
self._ANVACK_TABLE.get(access_key, self._API_KEY)))
201268

202269
return self._download_json(
203270
video_data_url, video_id, transform_source=strip_jsonp,
204-
data=json.dumps(payload).encode('utf-8'))
271+
data=json.dumps({'api': api}).encode('utf-8'))
205272

206273
def _get_anvato_videos(self, access_key, video_id):
207274
video_data = self._get_video_json(access_key, video_id)
@@ -259,7 +326,7 @@ def _get_anvato_videos(self, access_key, video_id):
259326
'description': video_data.get('def_description'),
260327
'tags': video_data.get('def_tags', '').split(','),
261328
'categories': video_data.get('categories'),
262-
'thumbnail': video_data.get('thumbnail'),
329+
'thumbnail': video_data.get('src_image_url') or video_data.get('thumbnail'),
263330
'timestamp': int_or_none(video_data.get(
264331
'ts_published') or video_data.get('ts_added')),
265332
'uploader': video_data.get('mcp_id'),

youtube_dl/extractor/arkena.py

Lines changed: 91 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,39 @@
66
from .common import InfoExtractor
77
from ..compat import compat_urlparse
88
from ..utils import (
9-
determine_ext,
109
ExtractorError,
1110
float_or_none,
1211
int_or_none,
13-
mimetype2ext,
1412
parse_iso8601,
15-
strip_jsonp,
13+
try_get,
1614
)
1715

1816

1917
class ArkenaIE(InfoExtractor):
2018
_VALID_URL = r'''(?x)
2119
https?://
2220
(?:
23-
video\.arkena\.com/play2/embed/player\?|
21+
video\.(?:arkena|qbrick)\.com/play2/embed/player\?|
2422
play\.arkena\.com/(?:config|embed)/avp/v\d/player/media/(?P<id>[^/]+)/[^/]+/(?P<account_id>\d+)
2523
)
2624
'''
2725
_TESTS = [{
28-
'url': 'https://play.arkena.com/embed/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411',
29-
'md5': 'b96f2f71b359a8ecd05ce4e1daa72365',
26+
'url': 'https://video.qbrick.com/play2/embed/player?accountId=1034090&mediaId=d8ab4607-00090107-aab86310',
27+
'md5': '97f117754e5f3c020f5f26da4a44ebaf',
3028
'info_dict': {
31-
'id': 'b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe',
29+
'id': 'd8ab4607-00090107-aab86310',
3230
'ext': 'mp4',
33-
'title': 'Big Buck Bunny',
34-
'description': 'Royalty free test video',
35-
'timestamp': 1432816365,
36-
'upload_date': '20150528',
37-
'is_live': False,
31+
'title': 'EM_HT20_117_roslund_v2.mp4',
32+
'timestamp': 1608285912,
33+
'upload_date': '20201218',
34+
'duration': 1429.162667,
35+
'subtitles': {
36+
'sv': 'count:3',
37+
},
3838
},
39+
}, {
40+
'url': 'https://play.arkena.com/embed/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411',
41+
'only_matching': True,
3942
}, {
4043
'url': 'https://play.arkena.com/config/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411/?callbackMethod=jQuery1111023664739129262213_1469227693893',
4144
'only_matching': True,
@@ -72,62 +75,89 @@ def _real_extract(self, url):
7275
if not video_id or not account_id:
7376
raise ExtractorError('Invalid URL', expected=True)
7477

75-
playlist = self._download_json(
76-
'https://play.arkena.com/config/avp/v2/player/media/%s/0/%s/?callbackMethod=_'
77-
% (video_id, account_id),
78-
video_id, transform_source=strip_jsonp)['Playlist'][0]
79-
80-
media_info = playlist['MediaInfo']
81-
title = media_info['Title']
82-
media_files = playlist['MediaFiles']
78+
media = self._download_json(
79+
'https://video.qbrick.com/api/v1/public/accounts/%s/medias/%s' % (account_id, video_id),
80+
video_id, query={
81+
# https://video.qbrick.com/docs/api/examples/library-api.html
82+
'fields': 'asset/resources/*/renditions/*(height,id,language,links/*(href,mimeType),type,size,videos/*(audios/*(codec,sampleRate),bitrate,codec,duration,height,width),width),created,metadata/*(title,description),tags',
83+
})
84+
metadata = media.get('metadata') or {}
85+
title = metadata['title']
8386

84-
is_live = False
87+
duration = None
8588
formats = []
86-
for kind_case, kind_formats in media_files.items():
87-
kind = kind_case.lower()
88-
for f in kind_formats:
89-
f_url = f.get('Url')
90-
if not f_url:
91-
continue
92-
is_live = f.get('Live') == 'true'
93-
exts = (mimetype2ext(f.get('Type')), determine_ext(f_url, None))
94-
if kind == 'm3u8' or 'm3u8' in exts:
95-
formats.extend(self._extract_m3u8_formats(
96-
f_url, video_id, 'mp4', 'm3u8_native',
97-
m3u8_id=kind, fatal=False, live=is_live))
98-
elif kind == 'flash' or 'f4m' in exts:
99-
formats.extend(self._extract_f4m_formats(
100-
f_url, video_id, f4m_id=kind, fatal=False))
101-
elif kind == 'dash' or 'mpd' in exts:
102-
formats.extend(self._extract_mpd_formats(
103-
f_url, video_id, mpd_id=kind, fatal=False))
104-
elif kind == 'silverlight':
105-
# TODO: process when ism is supported (see
106-
# https://github.com/ytdl-org/youtube-dl/issues/8118)
107-
continue
108-
else:
109-
tbr = float_or_none(f.get('Bitrate'), 1000)
110-
formats.append({
111-
'url': f_url,
112-
'format_id': '%s-%d' % (kind, tbr) if tbr else kind,
113-
'tbr': tbr,
114-
})
89+
thumbnails = []
90+
subtitles = {}
91+
for resource in media['asset']['resources']:
92+
for rendition in (resource.get('renditions') or []):
93+
rendition_type = rendition.get('type')
94+
for i, link in enumerate(rendition.get('links') or []):
95+
href = link.get('href')
96+
if not href:
97+
continue
98+
if rendition_type == 'image':
99+
thumbnails.append({
100+
'filesize': int_or_none(rendition.get('size')),
101+
'height': int_or_none(rendition.get('height')),
102+
'id': rendition.get('id'),
103+
'url': href,
104+
'width': int_or_none(rendition.get('width')),
105+
})
106+
elif rendition_type == 'subtitle':
107+
subtitles.setdefault(rendition.get('language') or 'en', []).append({
108+
'url': href,
109+
})
110+
elif rendition_type == 'video':
111+
f = {
112+
'filesize': int_or_none(rendition.get('size')),
113+
'format_id': rendition.get('id'),
114+
'url': href,
115+
}
116+
video = try_get(rendition, lambda x: x['videos'][i], dict)
117+
if video:
118+
if not duration:
119+
duration = float_or_none(video.get('duration'))
120+
f.update({
121+
'height': int_or_none(video.get('height')),
122+
'tbr': int_or_none(video.get('bitrate'), 1000),
123+
'vcodec': video.get('codec'),
124+
'width': int_or_none(video.get('width')),
125+
})
126+
audio = try_get(video, lambda x: x['audios'][0], dict)
127+
if audio:
128+
f.update({
129+
'acodec': audio.get('codec'),
130+
'asr': int_or_none(audio.get('sampleRate')),
131+
})
132+
formats.append(f)
133+
elif rendition_type == 'index':
134+
mime_type = link.get('mimeType')
135+
if mime_type == 'application/smil+xml':
136+
formats.extend(self._extract_smil_formats(
137+
href, video_id, fatal=False))
138+
elif mime_type == 'application/x-mpegURL':
139+
formats.extend(self._extract_m3u8_formats(
140+
href, video_id, 'mp4', 'm3u8_native',
141+
m3u8_id='hls', fatal=False))
142+
elif mime_type == 'application/hds+xml':
143+
formats.extend(self._extract_f4m_formats(
144+
href, video_id, f4m_id='hds', fatal=False))
145+
elif mime_type == 'application/dash+xml':
146+
formats.extend(self._extract_f4m_formats(
147+
href, video_id, f4m_id='hds', fatal=False))
148+
elif mime_type == 'application/vnd.ms-sstr+xml':
149+
formats.extend(self._extract_ism_formats(
150+
href, video_id, ism_id='mss', fatal=False))
115151
self._sort_formats(formats)
116152

117-
description = media_info.get('Description')
118-
video_id = media_info.get('VideoId') or video_id
119-
timestamp = parse_iso8601(media_info.get('PublishDate'))
120-
thumbnails = [{
121-
'url': thumbnail['Url'],
122-
'width': int_or_none(thumbnail.get('Size')),
123-
} for thumbnail in (media_info.get('Poster') or []) if thumbnail.get('Url')]
124-
125153
return {
126154
'id': video_id,
127155
'title': title,
128-
'description': description,
129-
'timestamp': timestamp,
130-
'is_live': is_live,
156+
'description': metadata.get('description'),
157+
'timestamp': parse_iso8601(media.get('created')),
131158
'thumbnails': thumbnails,
159+
'subtitles': subtitles,
160+
'duration': duration,
161+
'tags': media.get('tags'),
132162
'formats': formats,
133163
}

0 commit comments

Comments
 (0)