+ }]
+ _SMIL_BASE_URL = 'http://smil.lvl3.vevo.com/'
+
+ def _real_initialize(self):
+ req = compat_urllib_request.Request(
+ 'http://www.vevo.com/auth', data=b'')
+ webpage = self._download_webpage(
+ req, None,
+ note='Retrieving oauth token',
+ errnote='Unable to retrieve oauth token',
+ fatal=False)
+ if webpage is False:
+ self._oauth_token = None
+ else:
+ self._oauth_token = self._search_regex(
+ r'access_token":\s*"([^"]+)"',
+ webpage, 'access token', fatal=False)
+
+ def _formats_from_json(self, video_info):
+ last_version = {'version': -1}
+ for version in video_info['videoVersions']:
+ # These are the HTTP downloads, other types are for different manifests
+ if version['sourceType'] == 2:
+ if version['version'] > last_version['version']:
+ last_version = version
+ if last_version['version'] == -1:
+ raise ExtractorError('Unable to extract last version of the video')
+
+ renditions = xml.etree.ElementTree.fromstring(last_version['data'])
+ formats = []
+ # Already sorted from worst to best quality
+ for rend in renditions.findall('rendition'):
+ attr = rend.attrib
+ format_note = '%(videoCodec)s@%(videoBitrate)4sk, %(audioCodec)s@%(audioBitrate)3sk' % attr
+ formats.append({
+ 'url': attr['url'],
+ 'format_id': attr['name'],
+ 'format_note': format_note,
+ 'height': int(attr['frameheight']),
+ 'width': int(attr['frameWidth']),
+ })
+ return formats
+
+ def _formats_from_smil(self, smil_xml):
+ formats = []
+ smil_doc = xml.etree.ElementTree.fromstring(smil_xml.encode('utf-8'))
+ els = smil_doc.findall('.//{http://www.w3.org/2001/SMIL20/Language}video')
+ for el in els:
+ src = el.attrib['src']
+ m = re.match(r'''(?xi)
+ (?P<ext>[a-z0-9]+):
+ (?P<path>
+ [/a-z0-9]+ # The directory and main part of the URL
+ _(?P<cbr>[0-9]+)k
+ _(?P<width>[0-9]+)x(?P<height>[0-9]+)
+ _(?P<vcodec>[a-z0-9]+)
+ _(?P<vbr>[0-9]+)
+ _(?P<acodec>[a-z0-9]+)
+ _(?P<abr>[0-9]+)
+ \.[a-z0-9]+ # File extension
+ )''', src)
+ if not m:
+ continue
+
+ format_url = self._SMIL_BASE_URL + m.group('path')
+ formats.append({
+ 'url': format_url,
+ 'format_id': 'SMIL_' + m.group('cbr'),
+ 'vcodec': m.group('vcodec'),
+ 'acodec': m.group('acodec'),
+ 'vbr': int(m.group('vbr')),
+ 'abr': int(m.group('abr')),
+ 'ext': m.group('ext'),
+ 'width': int(m.group('width')),
+ 'height': int(m.group('height')),
+ })
+ return formats
+
+ def _download_api_formats(self, video_id):
+ if not self._oauth_token:
+ self._downloader.report_warning(
+ 'No oauth token available, skipping API HLS download')
+ return []
+
+ api_url = 'https://apiv2.vevo.com/video/%s/streams/hls?token=%s' % (
+ video_id, self._oauth_token)
+ api_data = self._download_json(
+ api_url, video_id,
+ note='Downloading HLS formats',
+ errnote='Failed to download HLS format list', fatal=False)
+ if api_data is None:
+ return []
+
+ m3u8_url = api_data[0]['url']
+ return self._extract_m3u8_formats(
+ m3u8_url, video_id, entry_protocol='m3u8_native', ext='mp4',
+ preference=0)