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