+ def _real_extract(self, url):
+ mobj = re.match(self._VALID_URL, url)
+ video_id, display_id = mobj.group('id', 'display_id')
+
+ webpage = self._download_webpage(url, display_id)
+
+ video = self._parse_json(
+ self._search_regex(
+ r'INITIALSTATE\s*=\s*(["\'])(?P<value>(?:(?!\1).)+)\1',
+ webpage, 'data', group='value'), video_id,
+ transform_source=lambda x: compat_urllib_parse_unquote(
+ compat_b64decode(x).decode('utf-8')))['page']['video']
+
+ title = video['title']
+ media_id = video['mediaId']
+ sources = [compat_str(e['height'])
+ for e in video['encodings'] if e.get('height')]
+ formats = self._extract_formats(url, video_id, media_id, sources)
+
+ thumbnail = url_or_none(video.get('masterThumb'))
+ uploader = try_get(video, lambda x: x['user']['username'], compat_str)
+ uploader_id = str_or_none(try_get(
+ video, lambda x: x['user']['id'], int))
+ channel = try_get(video, lambda x: x['channel']['name'], compat_str)
+ channel_id = str_or_none(try_get(
+ video, lambda x: x['channel']['id'], int))
+ like_count = int_or_none(video.get('likes'))
+ dislike_count = int_or_none(video.get('dislikes'))
+ view_count = int_or_none(video.get('playsQty'))
+ duration = int_or_none(video.get('durationInSeconds'))
+ timestamp = unified_timestamp(video.get('publishedAt'))
+
+ return {
+ 'id': video_id,
+ 'title': title,
+ 'formats': formats,
+ 'thumbnail': thumbnail,
+ 'uploader': uploader or channel,
+ 'uploader_id': uploader_id or channel_id,
+ 'channel': channel,
+ 'channel_id': channel_id,
+ 'timestamp': timestamp,
+ 'like_count': like_count,
+ 'dislike_count': dislike_count,
+ 'view_count': view_count,
+ 'duration': duration,
+ 'age_limit': 18,
+ }
+