2 from __future__ 
import unicode_literals
 
   4 from .common 
import InfoExtractor
 
   6     compat_etree_fromstring
, 
   8     compat_urllib_parse_unquote
, 
   9     compat_urllib_parse_urlparse
, 
  21 class OdnoklassnikiIE(InfoExtractor
): 
  22     _VALID_URL 
= r
'https?://(?:(?:www|m|mobile)\.)?(?:odnoklassniki|ok)\.ru/(?:video(?:embed)?|web-api/video/moviePlayer|live)/(?P<id>[\d-]+)' 
  25         'url': 'http://ok.ru/video/20079905452', 
  26         'md5': '0b62089b479e06681abaaca9d204f152', 
  30             'title': 'Культура меняет нас (прекрасный ролик!))', 
  32             'upload_date': '20141207', 
  33             'uploader_id': '330537914540', 
  34             'uploader': 'Виталий Добровольский', 
  40         'url': 'http://ok.ru/video/63567059965189-0?fromTime=5', 
  41         'md5': '6ff470ea2dd51d5d18c295a355b0b6bc', 
  43             'id': '63567059965189-0', 
  45             'title': 'Девушка без комплексов ...', 
  47             'upload_date': '20150518', 
  48             'uploader_id': '534380003155', 
  49             'uploader': '☭ Андрей Мещанинов ☭', 
  55         # YouTube embed (metadataUrl, provider == USER_YOUTUBE) 
  56         'url': 'http://ok.ru/video/64211978996595-1', 
  57         'md5': '2f206894ffb5dbfcce2c5a14b909eea5', 
  61             'title': 'Космическая среда от 26 августа 2015', 
  62             'description': 'md5:848eb8b85e5e3471a3a803dae1343ed0', 
  64             'upload_date': '20150826', 
  65             'uploader_id': 'tvroscosmos', 
  66             'uploader': 'Телестудия Роскосмоса', 
  70         # YouTube embed (metadata, provider == USER_YOUTUBE, no metadata.movie.title field) 
  71         'url': 'http://ok.ru/video/62036049272859-0', 
  73             'id': '62036049272859-0', 
  75             'title': 'МУЗЫКА     ДОЖДЯ .', 
  76             'description': 'md5:6f1867132bd96e33bf53eda1091e8ed0', 
  77             'upload_date': '20120106', 
  78             'uploader_id': '473534735899', 
  79             'uploader': 'МARINA D', 
  83             'skip_download': True, 
  85         'skip': 'Video has not been found', 
  87         'url': 'http://ok.ru/web-api/video/moviePlayer/20079905452', 
  88         'only_matching': True, 
  90         'url': 'http://www.ok.ru/video/20648036891', 
  91         'only_matching': True, 
  93         'url': 'http://www.ok.ru/videoembed/20648036891', 
  94         'only_matching': True, 
  96         'url': 'http://m.ok.ru/video/20079905452', 
  97         'only_matching': True, 
  99         'url': 'http://mobile.ok.ru/video/20079905452', 
 100         'only_matching': True, 
 102         'url': 'https://www.ok.ru/live/484531969818', 
 103         'only_matching': True, 
 106     def _real_extract(self
, url
): 
 107         start_time 
= int_or_none(compat_parse_qs( 
 108             compat_urllib_parse_urlparse(url
).query
).get('fromTime', [None])[0]) 
 110         video_id 
= self
._match
_id
(url
) 
 112         webpage 
= self
._download
_webpage
( 
 113             'http://ok.ru/video/%s' % video_id
, video_id
) 
 115         error 
= self
._search
_regex
( 
 116             r
'[^>]+class="vp_video_stub_txt"[^>]*>([^<]+)<', 
 117             webpage
, 'error', default
=None) 
 119             raise ExtractorError(error
, expected
=True) 
 121         player 
= self
._parse
_json
( 
 122             unescapeHTML(self
._search
_regex
( 
 123                 r
'data-options=(?P<quote>["\'])(?P
<player
>{.+?
%s.+?
})(?P
=quote
)' % video_id, 
 124                 webpage, 'player
', group='player
')), 
 127         flashvars = player['flashvars
'] 
 129         metadata = flashvars.get('metadata
') 
 131             metadata = self._parse_json(metadata, video_id) 
 134             st_location = flashvars.get('location
') 
 136                 data['st
.location
'] = st_location 
 137             metadata = self._download_json( 
 138                 compat_urllib_parse_unquote(flashvars['metadataUrl
']), 
 139                 video_id, 'Downloading metadata JSON
', 
 140                 data=urlencode_postdata(data)) 
 142         movie = metadata['movie
'] 
 144         # Some embedded videos may not contain title in movie dict (e.g. 
 145         # http://ok.ru/video/62036049272859-0) thus we allow missing title 
 146         # here and it's going to be extracted later by an extractor that
 
 147         # will process the actual embed. 
 148         provider 
= metadata
.get('provider') 
 149         title 
= movie
['title'] if provider 
== 'UPLOADED_ODKL' else movie
.get('title') 
 151         thumbnail 
= movie
.get('poster') 
 152         duration 
= int_or_none(movie
.get('duration')) 
 154         author 
= metadata
.get('author', {}) 
 155         uploader_id 
= author
.get('id') 
 156         uploader 
= author
.get('name') 
 158         upload_date 
= unified_strdate(self
._html
_search
_meta
( 
 159             'ya:ovs:upload_date', webpage
, 'upload date', default
=None)) 
 162         adult 
= self
._html
_search
_meta
( 
 163             'ya:ovs:adult', webpage
, 'age limit', default
=None) 
 165             age_limit 
= 18 if adult 
== 'true' else 0 
 167         like_count 
= int_or_none(metadata
.get('likeCount')) 
 172             'thumbnail': thumbnail
, 
 173             'duration': duration
, 
 174             'upload_date': upload_date
, 
 175             'uploader': uploader
, 
 176             'uploader_id': uploader_id
, 
 177             'like_count': like_count
, 
 178             'age_limit': age_limit
, 
 179             'start_time': start_time
, 
 182         if provider 
== 'USER_YOUTUBE': 
 184                 '_type': 'url_transparent', 
 185                 'url': movie
['contentId'], 
 190         if provider 
== 'LIVE_TV_APP': 
 191             info
['title'] = self
._live
_title
(title
) 
 193         quality 
= qualities(('4', '0', '1', '2', '3', '5')) 
 198             'format_id': f
['name'], 
 199         } for f 
in metadata
['videos']] 
 201         m3u8_url 
= metadata
.get('hlsManifestUrl') 
 203             formats
.extend(self
._extract
_m
3u8_formats
( 
 204                 m3u8_url
, video_id
, 'mp4', 'm3u8_native', 
 205                 m3u8_id
='hls', fatal
=False)) 
 207         dash_manifest 
= metadata
.get('metadataEmbedded') 
 209             formats
.extend(self
._parse
_mpd
_formats
( 
 210                 compat_etree_fromstring(dash_manifest
), 'mpd')) 
 213             fmt_type 
= self
._search
_regex
( 
 214                 r
'\btype[/=](\d)', fmt
['url'], 
 215                 'format type', default
=None) 
 217                 fmt
['quality'] = quality(fmt_type
) 
 220         m3u8_url 
= metadata
.get('hlsMasterPlaylistUrl') 
 222             formats
.extend(self
._extract
_m
3u8_formats
( 
 223                 m3u8_url
, video_id
, 'mp4', entry_protocol
='m3u8', 
 224                 m3u8_id
='hls', fatal
=False)) 
 225         rtmp_url 
= metadata
.get('rtmpUrl') 
 233         self
._sort
_formats
(formats
) 
 235         info
['formats'] = formats