2 from __future__ 
import unicode_literals
 
   4 from .common 
import InfoExtractor
 
  12 class CamModelsIE(InfoExtractor
): 
  13     _VALID_URL 
= r
'https?://(?:www\.)?cammodels\.com/cam/(?P<id>[^/?#&]+)' 
  15         'url': 'https://www.cammodels.com/cam/AutumnKnight/', 
  16         'only_matching': True, 
  20     def _real_extract(self
, url
): 
  21         user_id 
= self
._match
_id
(url
) 
  23         webpage 
= self
._download
_webpage
( 
  24             url
, user_id
, headers
=self
.geo_verification_headers()) 
  26         manifest_root 
= self
._html
_search
_regex
( 
  27             r
'manifestUrlRoot=([^&\']+)', webpage, 'manifest
', default=None) 
  31                 ("I'm offline
, but let
's stay connected", 'This user 
is currently offline
'), 
  32                 ('in a private show
', 'This user 
is in a private show
'), 
  33                 ('is currently performing LIVE
', 'This model 
is currently performing live
'), 
  35             for pattern, message in ERRORS: 
  36                 if pattern in webpage: 
  41                 error = 'Unable to find manifest URL root
' 
  43             raise ExtractorError(error, expected=expected) 
  45         manifest = self._download_json( 
  46             '%s%s.json
' % (manifest_root, user_id), user_id) 
  49         for format_id, format_dict in manifest['formats
'].items(): 
  50             if not isinstance(format_dict, dict): 
  52             encodings = format_dict.get('encodings
') 
  53             if not isinstance(encodings, list): 
  55             vcodec = format_dict.get('videoCodec
') 
  56             acodec = format_dict.get('audioCodec
') 
  57             for media in encodings: 
  58                 if not isinstance(media, dict): 
  60                 media_url = url_or_none(media.get('location
')) 
  64                 format_id_list = [format_id] 
  65                 height = int_or_none(media.get('videoHeight
')) 
  66                 if height is not None: 
  67                     format_id_list.append('%dp
' % height) 
  70                     'format_id
': '-'.join(format_id_list), 
  71                     'width
': int_or_none(media.get('videoWidth
')), 
  73                     'vbr
': int_or_none(media.get('videoKbps
')), 
  74                     'abr
': int_or_none(media.get('audioKbps
')), 
  75                     'fps
': int_or_none(media.get('fps
')), 
  79                 if 'rtmp
' in format_id: 
  81                 elif 'hls
' in format_id: 
  84                         # hls skips fragments, preferring rtmp 
  90         self._sort_formats(formats) 
  94             'title
': self._live_title(user_id),