+ subtitles = {}
+ subtitles_data = metadata.get('subtitles', {}).get('data', {})
+ if subtitles_data and isinstance(subtitles_data, dict):
+ for subtitle_lang, subtitle in subtitles_data.items():
+ subtitles[subtitle_lang] = [{
+ 'ext': determine_ext(subtitle_url),
+ 'url': subtitle_url,
+ } for subtitle_url in subtitle.get('urls', [])]
+
+ return {
+ 'id': video_id,
+ 'title': title,
+ 'description': description,
+ 'thumbnail': thumbnail,
+ 'duration': duration,
+ 'timestamp': timestamp,
+ 'uploader': uploader,
+ 'uploader_id': uploader_id,
+ 'age_limit': age_limit,
+ 'view_count': view_count,
+ 'comment_count': comment_count,
+ 'formats': formats,
+ 'subtitles': subtitles,
+ }
+
+ # vevo embed
+ vevo_id = self._search_regex(
+ r'<link rel="video_src" href="[^"]*?vevo.com[^"]*?video=(?P<id>[\w]*)',
+ webpage, 'vevo embed', default=None)
+ if vevo_id:
+ return self.url_result('vevo:%s' % vevo_id, 'Vevo')
+
+ # fallback old player
+ embed_page = self._download_webpage_no_ff(
+ 'https://www.dailymotion.com/embed/video/%s' % video_id,
+ video_id, 'Downloading embed page')
+
+ timestamp = parse_iso8601(self._html_search_meta(
+ 'video:release_date', webpage, 'upload date'))
+
+ info = self._parse_json(
+ self._search_regex(
+ r'var info = ({.*?}),$', embed_page,
+ 'video info', flags=re.MULTILINE),
+ video_id)
+
+ self._check_error(info)
+
+ formats = []
+ for (key, format_id) in self._FORMATS:
+ video_url = info.get(key)
+ if video_url is not None:
+ m_size = re.search(r'H264-(\d+)x(\d+)', video_url)
+ if m_size is not None:
+ width, height = map(int_or_none, (m_size.group(1), m_size.group(2)))
+ else:
+ width, height = None, None
+ formats.append({
+ 'url': video_url,
+ 'ext': 'mp4',
+ 'format_id': format_id,
+ 'width': width,
+ 'height': height,
+ })
+ self._sort_formats(formats)
+
+ # subtitles
+ video_subtitles = self.extract_subtitles(video_id, webpage)
+
+ title = self._og_search_title(webpage, default=None)
+ if title is None:
+ title = self._html_search_regex(
+ r'(?s)<span\s+id="video_title"[^>]*>(.*?)</span>', webpage,
+ 'title')
+
+ return {
+ 'id': video_id,
+ 'formats': formats,
+ 'uploader': info['owner.screenname'],
+ 'timestamp': timestamp,
+ 'title': title,
+ 'description': description,
+ 'subtitles': video_subtitles,
+ 'thumbnail': info['thumbnail_url'],
+ 'age_limit': age_limit,
+ 'view_count': view_count,
+ 'duration': info['duration']
+ }
+
+ def _check_error(self, info):
+ error = info.get('error')
+ if info.get('error') is not None:
+ title = error['title']
+ # See https://developer.dailymotion.com/api#access-error
+ if error.get('code') == 'DM007':
+ self.raise_geo_restricted(msg=title)
+ raise ExtractorError(
+ '%s said: %s' % (self.IE_NAME, title), expected=True)
+
+ def _get_subtitles(self, video_id, webpage):
+ try:
+ sub_list = self._download_webpage(
+ 'https://api.dailymotion.com/video/%s/subtitles?fields=id,language,url' % video_id,
+ video_id, note=False)
+ except ExtractorError as err:
+ self._downloader.report_warning('unable to download video subtitles: %s' % error_to_compat_str(err))
+ return {}
+ info = json.loads(sub_list)
+ if (info['total'] > 0):
+ sub_lang_list = dict((l['language'], [{'url': l['url'], 'ext': 'srt'}]) for l in info['list'])
+ return sub_lang_list
+ self._downloader.report_warning('video doesn\'t have subtitles')
+ return {}
+
+
+class DailymotionPlaylistIE(DailymotionBaseInfoExtractor):
+ IE_NAME = 'dailymotion:playlist'