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
): 
  24                     (?:(?:www|m|mobile)\.)? 
  25                     (?:odnoklassniki|ok)\.ru/ 
  28                         web-api/video/moviePlayer/| 
  36         'url': 'http://ok.ru/video/20079905452', 
  37         'md5': '0b62089b479e06681abaaca9d204f152', 
  41             'title': 'Культура меняет нас (прекрасный ролик!))', 
  43             'upload_date': '20141207', 
  44             'uploader_id': '330537914540', 
  45             'uploader': 'Виталий Добровольский', 
  51         'url': 'http://ok.ru/video/63567059965189-0?fromTime=5', 
  52         'md5': '6ff470ea2dd51d5d18c295a355b0b6bc', 
  54             'id': '63567059965189-0', 
  56             'title': 'Девушка без комплексов ...', 
  58             'upload_date': '20150518', 
  59             'uploader_id': '534380003155', 
  60             'uploader': '☭ Андрей Мещанинов ☭', 
  66         # YouTube embed (metadataUrl, provider == USER_YOUTUBE) 
  67         'url': 'http://ok.ru/video/64211978996595-1', 
  68         'md5': '2f206894ffb5dbfcce2c5a14b909eea5', 
  72             'title': 'Космическая среда от 26 августа 2015', 
  73             'description': 'md5:848eb8b85e5e3471a3a803dae1343ed0', 
  75             'upload_date': '20150826', 
  76             'uploader_id': 'tvroscosmos', 
  77             'uploader': 'Телестудия Роскосмоса', 
  81         # YouTube embed (metadata, provider == USER_YOUTUBE, no metadata.movie.title field) 
  82         'url': 'http://ok.ru/video/62036049272859-0', 
  84             'id': '62036049272859-0', 
  86             'title': 'МУЗЫКА     ДОЖДЯ .', 
  87             'description': 'md5:6f1867132bd96e33bf53eda1091e8ed0', 
  88             'upload_date': '20120106', 
  89             'uploader_id': '473534735899', 
  90             'uploader': 'МARINA D', 
  94             'skip_download': True, 
  96         'skip': 'Video has not been found', 
  98         'url': 'http://ok.ru/web-api/video/moviePlayer/20079905452', 
  99         'only_matching': True, 
 101         'url': 'http://www.ok.ru/video/20648036891', 
 102         'only_matching': True, 
 104         'url': 'http://www.ok.ru/videoembed/20648036891', 
 105         'only_matching': True, 
 107         'url': 'http://m.ok.ru/video/20079905452', 
 108         'only_matching': True, 
 110         'url': 'http://mobile.ok.ru/video/20079905452', 
 111         'only_matching': True, 
 113         'url': 'https://www.ok.ru/live/484531969818', 
 114         'only_matching': True, 
 116         'url': 'https://m.ok.ru/dk?st.cmd=movieLayer&st.discId=863789452017&st.retLoc=friend&st.rtu=%2Fdk%3Fst.cmd%3DfriendMovies%26st.mode%3Down%26st.mrkId%3D%257B%2522uploadedMovieMarker%2522%253A%257B%2522marker%2522%253A%25221519410114503%2522%252C%2522hasMore%2522%253Atrue%257D%252C%2522sharedMovieMarker%2522%253A%257B%2522marker%2522%253Anull%252C%2522hasMore%2522%253Afalse%257D%257D%26st.friendId%3D561722190321%26st.frwd%3Don%26_prevCmd%3DfriendMovies%26tkn%3D7257&st.discType=MOVIE&st.mvId=863789452017&_prevCmd=friendMovies&tkn=3648#lst#', 
 117         'only_matching': True, 
 120     def _real_extract(self
, url
): 
 121         start_time 
= int_or_none(compat_parse_qs( 
 122             compat_urllib_parse_urlparse(url
).query
).get('fromTime', [None])[0]) 
 124         video_id 
= self
._match
_id
(url
) 
 126         webpage 
= self
._download
_webpage
( 
 127             'http://ok.ru/video/%s' % video_id
, video_id
) 
 129         error 
= self
._search
_regex
( 
 130             r
'[^>]+class="vp_video_stub_txt"[^>]*>([^<]+)<', 
 131             webpage
, 'error', default
=None) 
 133             raise ExtractorError(error
, expected
=True) 
 135         player 
= self
._parse
_json
( 
 136             unescapeHTML(self
._search
_regex
( 
 137                 r
'data-options=(?P<quote>["\'])(?P
<player
>{.+?
%s.+?
})(?P
=quote
)' % video_id, 
 138                 webpage, 'player
', group='player
')), 
 141         flashvars = player['flashvars
'] 
 143         metadata = flashvars.get('metadata
') 
 145             metadata = self._parse_json(metadata, video_id) 
 148             st_location = flashvars.get('location
') 
 150                 data['st
.location
'] = st_location 
 151             metadata = self._download_json( 
 152                 compat_urllib_parse_unquote(flashvars['metadataUrl
']), 
 153                 video_id, 'Downloading metadata JSON
', 
 154                 data=urlencode_postdata(data)) 
 156         movie = metadata['movie
'] 
 158         # Some embedded videos may not contain title in movie dict (e.g. 
 159         # http://ok.ru/video/62036049272859-0) thus we allow missing title 
 160         # here and it's going to be extracted later by an extractor that
 
 161         # will process the actual embed. 
 162         provider 
= metadata
.get('provider') 
 163         title 
= movie
['title'] if provider 
== 'UPLOADED_ODKL' else movie
.get('title') 
 165         thumbnail 
= movie
.get('poster') 
 166         duration 
= int_or_none(movie
.get('duration')) 
 168         author 
= metadata
.get('author', {}) 
 169         uploader_id 
= author
.get('id') 
 170         uploader 
= author
.get('name') 
 172         upload_date 
= unified_strdate(self
._html
_search
_meta
( 
 173             'ya:ovs:upload_date', webpage
, 'upload date', default
=None)) 
 176         adult 
= self
._html
_search
_meta
( 
 177             'ya:ovs:adult', webpage
, 'age limit', default
=None) 
 179             age_limit 
= 18 if adult 
== 'true' else 0 
 181         like_count 
= int_or_none(metadata
.get('likeCount')) 
 186             'thumbnail': thumbnail
, 
 187             'duration': duration
, 
 188             'upload_date': upload_date
, 
 189             'uploader': uploader
, 
 190             'uploader_id': uploader_id
, 
 191             'like_count': like_count
, 
 192             'age_limit': age_limit
, 
 193             'start_time': start_time
, 
 196         if provider 
== 'USER_YOUTUBE': 
 198                 '_type': 'url_transparent', 
 199                 'url': movie
['contentId'], 
 204         if provider 
== 'LIVE_TV_APP': 
 205             info
['title'] = self
._live
_title
(title
) 
 207         quality 
= qualities(('4', '0', '1', '2', '3', '5')) 
 212             'format_id': f
['name'], 
 213         } for f 
in metadata
['videos']] 
 215         m3u8_url 
= metadata
.get('hlsManifestUrl') 
 217             formats
.extend(self
._extract
_m
3u8_formats
( 
 218                 m3u8_url
, video_id
, 'mp4', 'm3u8_native', 
 219                 m3u8_id
='hls', fatal
=False)) 
 221         dash_manifest 
= metadata
.get('metadataEmbedded') 
 223             formats
.extend(self
._parse
_mpd
_formats
( 
 224                 compat_etree_fromstring(dash_manifest
), 'mpd')) 
 227             fmt_type 
= self
._search
_regex
( 
 228                 r
'\btype[/=](\d)', fmt
['url'], 
 229                 'format type', default
=None) 
 231                 fmt
['quality'] = quality(fmt_type
) 
 234         m3u8_url 
= metadata
.get('hlsMasterPlaylistUrl') 
 236             formats
.extend(self
._extract
_m
3u8_formats
( 
 237                 m3u8_url
, video_id
, 'mp4', entry_protocol
='m3u8', 
 238                 m3u8_id
='hls', fatal
=False)) 
 239         rtmp_url 
= metadata
.get('rtmpUrl') 
 247         self
._sort
_formats
(formats
) 
 249         info
['formats'] = formats