4 from .common 
import InfoExtractor
 
   6     compat_urllib_parse_urlparse
, 
  12 class LivestreamIE(InfoExtractor
): 
  13     IE_NAME 
= u
'livestream' 
  14     _VALID_URL 
= r
'http://new\.livestream\.com/.*?/(?P<event_name>.*?)(/videos/(?P<id>\d+))?/?$' 
  16         u
'url': u
'http://new.livestream.com/CoheedandCambria/WebsterHall/videos/4719370', 
  17         u
'file': u
'4719370.mp4', 
  18         u
'md5': u
'0d2186e3187d185a04b3cdd02b828836', 
  20             u
'title': u
'Live from Webster Hall NYC', 
  21             u
'upload_date': u
'20121012', 
  25     def _extract_video_info(self
, video_data
): 
  26         video_url 
= video_data
.get('progressive_url_hd') or video_data
.get('progressive_url') 
  27         return {'id': video_data
['id'], 
  30                 'title': video_data
['caption'], 
  31                 'thumbnail': video_data
['thumbnail_url'], 
  32                 'upload_date': video_data
['updated_at'].replace('-','')[:8], 
  35     def _real_extract(self
, url
): 
  36         mobj 
= re
.match(self
._VALID
_URL
, url
) 
  37         video_id 
= mobj
.group('id') 
  38         event_name 
= mobj
.group('event_name') 
  39         webpage 
= self
._download
_webpage
(url
, video_id 
or event_name
) 
  42             # This is an event page: 
  43             config_json 
= self
._search
_regex
(r
'window.config = ({.*?});', 
  44                 webpage
, u
'window config') 
  45             info 
= json
.loads(config_json
)['event'] 
  46             videos 
= [self
._extract
_video
_info
(video_data
['data']) 
  47                 for video_data 
in info
['feed']['data'] if video_data
['type'] == u
'video'] 
  48             return self
.playlist_result(videos
, info
['id'], info
['full_name']) 
  50             og_video 
= self
._og
_search
_video
_url
(webpage
, name
=u
'player url') 
  51             query_str 
= compat_urllib_parse_urlparse(og_video
).query
 
  52             query 
= compat_urlparse
.parse_qs(query_str
) 
  53             api_url 
= query
['play_url'][0].replace('.smil', '') 
  54             info 
= json
.loads(self
._download
_webpage
(api_url
, video_id
, 
  55                                                      u
'Downloading video info')) 
  56             return self
._extract
_video
_info
(info
) 
  59 # The original version of Livestream uses a different system 
  60 class LivestreamOriginalIE(InfoExtractor
): 
  61     IE_NAME 
= u
'livestream:original' 
  62     _VALID_URL 
= r
'https?://www\.livestream\.com/(?P<user>[^/]+)/video\?.*?clipId=(?P<id>.*?)(&|$)' 
  64         u
'url': u
'http://www.livestream.com/dealbook/video?clipId=pla_8aa4a3f1-ba15-46a4-893b-902210e138fb', 
  66             u
'id': u
'pla_8aa4a3f1-ba15-46a4-893b-902210e138fb', 
  68             u
'title': u
'Spark 1 (BitCoin) with Cameron Winklevoss & Tyler Winklevoss of Winklevoss Capital', 
  72             u
'skip_download': True, 
  76     def _real_extract(self
, url
): 
  77         mobj 
= re
.match(self
._VALID
_URL
, url
) 
  78         video_id 
= mobj
.group('id') 
  79         user 
= mobj
.group('user') 
  80         api_url 
= 'http://x{0}x.api.channel.livestream.com/2.0/clipdetails?extendedInfo=true&id={1}'.format(user
, video_id
) 
  82         info 
= self
._download
_xml
(api_url
, video_id
) 
  83         item 
= info
.find('channel').find('item') 
  84         ns 
= {'media': 'http://search.yahoo.com/mrss'} 
  85         thumbnail_url 
= item
.find(xpath_with_ns('media:thumbnail', ns
)).attrib
['url'] 
  86         # Remove the extension and number from the path (like 1.jpg) 
  87         path 
= self
._search
_regex
(r
'(user-files/.+)_.*?\.jpg$', thumbnail_url
, u
'path') 
  91             'title': item
.find('title').text
, 
  92             'url': 'rtmp://extondemand.livestream.com/ondemand', 
  93             'play_path': 'mp4:trans/dv15/mogulus-{0}.mp4'.format(path
), 
  95             'thumbnail': thumbnail_url
,