2 from __future__ 
import unicode_literals
 
   6 from .common 
import InfoExtractor
 
  18 class EaglePlatformIE(InfoExtractor
): 
  21                         eagleplatform:(?P<custom_host>[^/]+):| 
  22                         https?://(?P<host>.+?\.media\.eagleplatform\.com)/index/player\?.*\brecord_id= 
  27         # http://lenta.ru/news/2015/03/06/navalny/ 
  28         'url': 'http://lentaru.media.eagleplatform.com/index/player?player=new&record_id=227304&player_template_id=5201', 
  29         # Not checking MD5 as sometimes the direct HTTP link results in 404 and HLS is used 
  33             'title': 'Навальный вышел на свободу', 
  34             'description': 'md5:d97861ac9ae77377f3f20eaf9d04b4f5', 
  35             'thumbnail': r
're:^https?://.*\.jpg$', 
  41         # http://muz-tv.ru/play/7129/ 
  42         # http://media.clipyou.ru/index/player?record_id=12820&width=730&height=415&autoplay=true 
  43         'url': 'eagleplatform:media.clipyou.ru:12820', 
  44         'md5': '358597369cf8ba56675c1df15e7af624', 
  48             'title': "'O Sole Mio", 
  49             'thumbnail': r
're:^https?://.*\.jpg$', 
  53         'skip': 'Georestricted', 
  55         # referrer protected video (https://tvrain.ru/lite/teleshow/kak_vse_nachinalos/namin-418921/) 
  56         'url': 'eagleplatform:tvrainru.media.eagleplatform.com:582306', 
  57         'only_matching': True, 
  61     def _extract_url(webpage
): 
  62         # Regular iframe embedding 
  64             r
'<iframe[^>]+src=(["\'])(?P
<url
>(?
:https?
:)?
//.+?\
.media\
.eagleplatform\
.com
/index
/player
\?.+?
)\
1', 
  67             return mobj.group('url
') 
  70                             src=(?P<qjs>["\'])(?:https?:)?//(?P<host>(?:(?!(?P=qjs)).)+\.media\.eagleplatform\.com)/player/player\.js(?P=qjs) 
  73         # "Basic usage" embedding (see http://dultonmedia.github.io/eplayer/) 
  78                         class=(?P<qclass>["\'])eagleplayer(?P=qclass)[^>]+ 
  79                         data-id=["\'](?P<id>\d+) 
  80             ''' % PLAYER_JS_RE, webpage) 
  82             return 'eagleplatform
:%(host)s:%(id)s' % mobj.groupdict() 
  83         # Generalization of "Javascript code usage", "Combined usage" and 
  84         # "Usage without attaching to DOM" embeddings (see 
  85         # http://dultonmedia.github.io/eplayer/) 
  95                             \bid\s*:\s*["\']?(?P<id>\d+) 
 101             ''' % PLAYER_JS_RE, webpage) 
 103             return 'eagleplatform
:%(host)s:%(id)s' % mobj.groupdict() 
 106     def _handle_error(response): 
 107         status = int_or_none(response.get('status
', 200)) 
 109             raise ExtractorError(' '.join(response['errors
']), expected=True) 
 111     def _download_json(self, url_or_request, video_id, *args, **kwargs): 
 113             response = super(EaglePlatformIE, self)._download_json( 
 114                 url_or_request, video_id, *args, **kwargs) 
 115         except ExtractorError as ee: 
 116             if isinstance(ee.cause, compat_HTTPError): 
 117                 response = self._parse_json(ee.cause.read().decode('utf
-8'), video_id) 
 118                 self._handle_error(response) 
 122     def _get_video_url(self, url_or_request, video_id, note='Downloading JSON metadata
'): 
 123         return self._download_json(url_or_request, video_id, note)['data
'][0] 
 125     def _real_extract(self, url): 
 126         url, smuggled_data = unsmuggle_url(url, {}) 
 128         mobj = re.match(self._VALID_URL, url) 
 129         host, video_id = mobj.group('custom_host
') or mobj.group('host
'), mobj.group('id') 
 136         referrer = smuggled_data.get('referrer
') 
 138             headers['Referer
'] = referrer 
 139             query['referrer
'] = referrer 
 141         player_data = self._download_json( 
 142             'http
://%s/api
/player_data
' % host, video_id, 
 143             headers=headers, query=query) 
 145         media = player_data['data
']['playlist
']['viewports
'][0]['medialist
'][0] 
 147         title = media['title
'] 
 148         description = media.get('description
') 
 149         thumbnail = self._proto_relative_url(media.get('snapshot
'), 'http
:') 
 150         duration = int_or_none(media.get('duration
')) 
 151         view_count = int_or_none(media.get('views
')) 
 153         age_restriction = media.get('age_restriction
') 
 156             age_limit = 0 if age_restriction == 'allow_all
' else 18 
 158         secure_m3u8 = self._proto_relative_url(media['sources
']['secure_m3u8
']['auto
'], 'http
:') 
 162         m3u8_url = self._get_video_url(secure_m3u8, video_id, 'Downloading m3u8 JSON
') 
 163         m3u8_formats = self._extract_m3u8_formats( 
 164             m3u8_url, video_id, 'mp4
', entry_protocol='m3u8_native
', 
 165             m3u8_id='hls
', fatal=False) 
 166         formats.extend(m3u8_formats) 
 168         m3u8_formats_dict = {} 
 169         for f in m3u8_formats: 
 170             if f.get('height
') is not None: 
 171                 m3u8_formats_dict[f['height
']] = f 
 173         mp4_data = self._download_json( 
 174             # Secure mp4 URL is constructed according to Player.prototype.mp4 from 
 175             # http://lentaru.media.eagleplatform.com/player/player.js 
 176             re.sub(r'm3u8|hlsvod|hls|f4m
', 'mp4s
', secure_m3u8), 
 177             video_id, 'Downloading mp4 JSON
', fatal=False) 
 179             for format_id, format_url in mp4_data.get('data
', {}).items(): 
 180                 if not isinstance(format_url, compat_str): 
 182                 height = int_or_none(format_id) 
 183                 if height is not None and m3u8_formats_dict.get(height): 
 184                     f = m3u8_formats_dict[height].copy() 
 186                         'format_id
': f['format_id
'].replace('hls
', 'http
'), 
 191                         'format_id
': 'http
-%s' % format_id, 
 192                         'height
': int_or_none(format_id), 
 194                 f['url
'] = format_url 
 197         self._sort_formats(formats) 
 202             'description
': description, 
 203             'thumbnail
': thumbnail, 
 204             'duration
': duration, 
 205             'view_count
': view_count, 
 206             'age_limit
': age_limit,