]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/limelight.py
a425bafe30ae5cffdbeb793ef27c4ffdb870dcc9
   2 from __future__ 
import unicode_literals
 
   6 from .common 
import InfoExtractor
 
  14 class LimelightBaseIE(InfoExtractor
): 
  15     _PLAYLIST_SERVICE_URL 
= 'http://production-ps.lvp.llnw.net/r/PlaylistService/%s/%s/%s' 
  16     _API_URL 
= 'http://api.video.limelight.com/rest/organizations/%s/%s/%s/%s.json' 
  18     def _call_playlist_service(self
, item_id
, method
, fatal
=True): 
  19         return self
._download
_json
( 
  20             self
._PLAYLIST
_SERVICE
_URL 
% (self
._PLAYLIST
_SERVICE
_PATH
, item_id
, method
), 
  21             item_id
, 'Downloading PlaylistService %s JSON' % method
, fatal
=fatal
) 
  23     def _call_api(self
, organization_id
, item_id
, method
): 
  24         return self
._download
_json
( 
  25             self
._API
_URL 
% (organization_id
, self
._API
_PATH
, item_id
, method
), 
  26             item_id
, 'Downloading API %s JSON' % method
) 
  28     def _extract(self
, item_id
, pc_method
, mobile_method
, meta_method
): 
  29         pc 
= self
._call
_playlist
_service
(item_id
, pc_method
) 
  30         metadata 
= self
._call
_api
(pc
['orgId'], item_id
, meta_method
) 
  31         mobile 
= self
._call
_playlist
_service
(item_id
, mobile_method
, fatal
=False) 
  32         return pc
, mobile
, metadata
 
  34     def _extract_info(self
, streams
, mobile_urls
, properties
): 
  35         video_id 
= properties
['media_id'] 
  38         for stream 
in streams
: 
  39             stream_url 
= stream
.get('url') 
  40             if not stream_url 
or stream
.get('drmProtected'): 
  42             ext 
= determine_ext(stream_url
) 
  44                 formats
.extend(self
._extract
_f
4m
_formats
( 
  45                     stream_url
, video_id
, f4m_id
='hds', fatal
=False)) 
  49                     'abr': float_or_none(stream
.get('audioBitRate')), 
  50                     'vbr': float_or_none(stream
.get('videoBitRate')), 
  51                     'fps': float_or_none(stream
.get('videoFrameRate')), 
  52                     'width': int_or_none(stream
.get('videoWidthInPixels')), 
  53                     'height': int_or_none(stream
.get('videoHeightInPixels')), 
  56                 rtmp 
= re
.search(r
'^(?P<url>rtmpe?://(?P<host>[^/]+)/(?P<app>.+))/(?P<playpath>mp4:.+)$', stream_url
) 
  59                     if stream
.get('videoBitRate'): 
  60                         format_id 
+= '-%d' % int_or_none(stream
['videoBitRate']) 
  63                         'url': 'http://%s/%s' % (rtmp
.group('host').replace('csl.', 'cpl.'), rtmp
.group('playpath')[4:]), 
  64                         'format_id': format_id
.replace('rtmp', 'http'), 
  66                     formats
.append(http_fmt
) 
  68                         'url': rtmp
.group('url'), 
  69                         'play_path': rtmp
.group('playpath'), 
  70                         'app': rtmp
.group('app'), 
  72                         'format_id': format_id
, 
  76         for mobile_url 
in mobile_urls
: 
  77             media_url 
= mobile_url
.get('mobileUrl') 
  78             format_id 
= mobile_url
.get('targetMediaPlatform') 
  79             if not media_url 
or format_id 
== 'Widevine': 
  81             ext 
= determine_ext(media_url
) 
  83                 formats
.extend(self
._extract
_m
3u8_formats
( 
  84                     media_url
, video_id
, 'mp4', 'm3u8_native', 
  85                     m3u8_id
=format_id
, fatal
=False)) 
  87                 formats
.extend(self
._extract
_f
4m
_formats
( 
  88                     stream_url
, video_id
, f4m_id
=format_id
, fatal
=False)) 
  92                     'format_id': format_id
, 
  97         self
._sort
_formats
(formats
) 
  99         title 
= properties
['title'] 
 100         description 
= properties
.get('description') 
 101         timestamp 
= int_or_none(properties
.get('publish_date') or properties
.get('create_date')) 
 102         duration 
= float_or_none(properties
.get('duration_in_milliseconds'), 1000) 
 103         filesize 
= int_or_none(properties
.get('total_storage_in_bytes')) 
 104         categories 
= [properties
.get('category')] 
 105         tags 
= properties
.get('tags', []) 
 107             'url': thumbnail
['url'], 
 108             'width': int_or_none(thumbnail
.get('width')), 
 109             'height': int_or_none(thumbnail
.get('height')), 
 110         } for thumbnail 
in properties
.get('thumbnails', []) if thumbnail
.get('url')] 
 113         for caption 
in properties
.get('captions', []): 
 114             lang 
= caption
.get('language_code') 
 115             subtitles_url 
= caption
.get('url') 
 116             if lang 
and subtitles_url
: 
 117                 subtitles
.setdefault(lang
, []).append({ 
 118                     'url': subtitles_url
, 
 120         closed_captions_url 
= properties
.get('closed_captions_url') 
 121         if closed_captions_url
: 
 122             subtitles
.setdefault('en', []).append({ 
 123                 'url': closed_captions_url
, 
 130             'description': description
, 
 132             'timestamp': timestamp
, 
 133             'duration': duration
, 
 134             'filesize': filesize
, 
 135             'categories': categories
, 
 137             'thumbnails': thumbnails
, 
 138             'subtitles': subtitles
, 
 142 class LimelightMediaIE(LimelightBaseIE
): 
 143     IE_NAME 
= 'limelight' 
 144     _VALID_URL 
= r
'''(?x) 
 149                                     link\.videoplatform\.limelight\.com/media/| 
 150                                     assets\.delvenetworks\.com/player/loader\.swf 
 157         'url': 'http://link.videoplatform.limelight.com/media/?mediaId=3ffd040b522b4485b6d84effc750cd86', 
 159             'id': '3ffd040b522b4485b6d84effc750cd86', 
 161             'title': 'HaP and the HB Prince Trailer', 
 162             'description': 'md5:8005b944181778e313d95c1237ddb640', 
 163             'thumbnail': 're:^https?://.*\.jpeg$', 
 165             'timestamp': 1244136834, 
 166             'upload_date': '20090604', 
 170             'skip_download': True, 
 173         # video with subtitles 
 174         'url': 'limelight:media:a3e00274d4564ec4a9b29b9466432335', 
 175         'md5': '2fa3bad9ac321e23860ca23bc2c69e3d', 
 177             'id': 'a3e00274d4564ec4a9b29b9466432335', 
 179             'title': '3Play Media Overview Video', 
 180             'thumbnail': 're:^https?://.*\.jpeg$', 
 182             'timestamp': 1338929955, 
 183             'upload_date': '20120605', 
 184             'subtitles': 'mincount:9', 
 187         'url': 'https://assets.delvenetworks.com/player/loader.swf?mediaId=8018a574f08d416e95ceaccae4ba0452', 
 188         'only_matching': True, 
 190     _PLAYLIST_SERVICE_PATH 
= 'media' 
 193     def _real_extract(self
, url
): 
 194         video_id 
= self
._match
_id
(url
) 
 196         pc
, mobile
, metadata 
= self
._extract
( 
 197             video_id
, 'getPlaylistByMediaId', 'getMobilePlaylistByMediaId', 'properties') 
 199         return self
._extract
_info
( 
 200             pc
['playlistItems'][0].get('streams', []), 
 201             mobile
['mediaList'][0].get('mobileUrls', []) if mobile 
else [], 
 205 class LimelightChannelIE(LimelightBaseIE
): 
 206     IE_NAME 
= 'limelight:channel' 
 207     _VALID_URL 
= r
'''(?x) 
 212                                     link\.videoplatform\.limelight\.com/media/| 
 213                                     assets\.delvenetworks\.com/player/loader\.swf 
 220         'url': 'http://link.videoplatform.limelight.com/media/?channelId=ab6a524c379342f9b23642917020c082', 
 222             'id': 'ab6a524c379342f9b23642917020c082', 
 223             'title': 'Javascript Sample Code', 
 225         'playlist_mincount': 3, 
 227         'url': 'http://assets.delvenetworks.com/player/loader.swf?channelId=ab6a524c379342f9b23642917020c082', 
 228         'only_matching': True, 
 230     _PLAYLIST_SERVICE_PATH 
= 'channel' 
 231     _API_PATH 
= 'channels' 
 233     def _real_extract(self
, url
): 
 234         channel_id 
= self
._match
_id
(url
) 
 236         pc
, mobile
, medias 
= self
._extract
( 
 237             channel_id
, 'getPlaylistByChannelId', 
 238             'getMobilePlaylistWithNItemsByChannelId?begin=0&count=-1', 'media') 
 242                 pc
['playlistItems'][i
].get('streams', []), 
 243                 mobile
['mediaList'][i
].get('mobileUrls', []) if mobile 
else [], 
 244                 medias
['media_list'][i
]) 
 245             for i 
in range(len(medias
['media_list']))] 
 247         return self
.playlist_result(entries
, channel_id
, pc
['title']) 
 250 class LimelightChannelListIE(LimelightBaseIE
): 
 251     IE_NAME 
= 'limelight:channel_list' 
 252     _VALID_URL 
= r
'''(?x) 
 254                             limelight:channel_list:| 
 257                                     link\.videoplatform\.limelight\.com/media/| 
 258                                     assets\.delvenetworks\.com/player/loader\.swf 
 260                                 \?.*?\bchannelListId= 
 265         'url': 'http://link.videoplatform.limelight.com/media/?channelListId=301b117890c4465c8179ede21fd92e2b', 
 267             'id': '301b117890c4465c8179ede21fd92e2b', 
 268             'title': 'Website - Hero Player', 
 270         'playlist_mincount': 2, 
 272         'url': 'https://assets.delvenetworks.com/player/loader.swf?channelListId=301b117890c4465c8179ede21fd92e2b', 
 273         'only_matching': True, 
 275     _PLAYLIST_SERVICE_PATH 
= 'channel_list' 
 277     def _real_extract(self
, url
): 
 278         channel_list_id 
= self
._match
_id
(url
) 
 280         channel_list 
= self
._call
_playlist
_service
(channel_list_id
, 'getMobileChannelListById') 
 283             self
.url_result('limelight:channel:%s' % channel
['id'], 'LimelightChannel') 
 284             for channel 
in channel_list
['channelList']] 
 286         return self
.playlist_result(entries
, channel_list_id
, channel_list
['title'])