youtube-dl

Another place where youtube-dl lives on
git clone git://git.oshgnacknak.de/youtube-dl.git
Log | Files | Refs | README | LICENSE

cbs.py (4856B)


      1 from __future__ import unicode_literals
      2 
      3 from .theplatform import ThePlatformFeedIE
      4 from ..utils import (
      5     ExtractorError,
      6     int_or_none,
      7     find_xpath_attr,
      8     xpath_element,
      9     xpath_text,
     10     update_url_query,
     11 )
     12 
     13 
     14 class CBSBaseIE(ThePlatformFeedIE):
     15     def _parse_smil_subtitles(self, smil, namespace=None, subtitles_lang='en'):
     16         subtitles = {}
     17         for k, ext in [('sMPTE-TTCCURL', 'tt'), ('ClosedCaptionURL', 'ttml'), ('webVTTCaptionURL', 'vtt')]:
     18             cc_e = find_xpath_attr(smil, self._xpath_ns('.//param', namespace), 'name', k)
     19             if cc_e is not None:
     20                 cc_url = cc_e.get('value')
     21                 if cc_url:
     22                     subtitles.setdefault(subtitles_lang, []).append({
     23                         'ext': ext,
     24                         'url': cc_url,
     25                     })
     26         return subtitles
     27 
     28 
     29 class CBSIE(CBSBaseIE):
     30     _VALID_URL = r'(?:cbs:|https?://(?:www\.)?(?:(?:cbs|paramountplus)\.com/shows/[^/]+/video|colbertlateshow\.com/(?:video|podcasts))/)(?P<id>[\w-]+)'
     31 
     32     _TESTS = [{
     33         'url': 'http://www.cbs.com/shows/garth-brooks/video/_u7W953k6la293J7EPTd9oHkSPs6Xn6_/connect-chat-feat-garth-brooks/',
     34         'info_dict': {
     35             'id': '_u7W953k6la293J7EPTd9oHkSPs6Xn6_',
     36             'ext': 'mp4',
     37             'title': 'Connect Chat feat. Garth Brooks',
     38             'description': 'Connect with country music singer Garth Brooks, as he chats with fans on Wednesday November 27, 2013. Be sure to tune in to Garth Brooks: Live from Las Vegas, Friday November 29, at 9/8c on CBS!',
     39             'duration': 1495,
     40             'timestamp': 1385585425,
     41             'upload_date': '20131127',
     42             'uploader': 'CBSI-NEW',
     43         },
     44         'params': {
     45             # m3u8 download
     46             'skip_download': True,
     47         },
     48         '_skip': 'Blocked outside the US',
     49     }, {
     50         'url': 'http://colbertlateshow.com/video/8GmB0oY0McANFvp2aEffk9jZZZ2YyXxy/the-colbeard/',
     51         'only_matching': True,
     52     }, {
     53         'url': 'http://www.colbertlateshow.com/podcasts/dYSwjqPs_X1tvbV_P2FcPWRa_qT6akTC/in-the-bad-room-with-stephen/',
     54         'only_matching': True,
     55     }, {
     56         'url': 'https://www.paramountplus.com/shows/all-rise/video/QmR1WhNkh1a_IrdHZrbcRklm176X_rVc/all-rise-space/',
     57         'only_matching': True,
     58     }]
     59 
     60     def _extract_video_info(self, content_id, site='cbs', mpx_acc=2198311517):
     61         items_data = self._download_xml(
     62             'http://can.cbs.com/thunder/player/videoPlayerService.php',
     63             content_id, query={'partner': site, 'contentId': content_id})
     64         video_data = xpath_element(items_data, './/item')
     65         title = xpath_text(video_data, 'videoTitle', 'title', True)
     66         tp_path = 'dJ5BDC/media/guid/%d/%s' % (mpx_acc, content_id)
     67         tp_release_url = 'http://link.theplatform.com/s/' + tp_path
     68 
     69         asset_types = []
     70         subtitles = {}
     71         formats = []
     72         last_e = None
     73         for item in items_data.findall('.//item'):
     74             asset_type = xpath_text(item, 'assetType')
     75             if not asset_type or asset_type in asset_types or 'HLS_FPS' in asset_type or 'DASH_CENC' in asset_type:
     76                 continue
     77             asset_types.append(asset_type)
     78             query = {
     79                 'mbr': 'true',
     80                 'assetTypes': asset_type,
     81             }
     82             if asset_type.startswith('HLS') or asset_type in ('OnceURL', 'StreamPack'):
     83                 query['formats'] = 'MPEG4,M3U'
     84             elif asset_type in ('RTMP', 'WIFI', '3G'):
     85                 query['formats'] = 'MPEG4,FLV'
     86             try:
     87                 tp_formats, tp_subtitles = self._extract_theplatform_smil(
     88                     update_url_query(tp_release_url, query), content_id,
     89                     'Downloading %s SMIL data' % asset_type)
     90             except ExtractorError as e:
     91                 last_e = e
     92                 continue
     93             formats.extend(tp_formats)
     94             subtitles = self._merge_subtitles(subtitles, tp_subtitles)
     95         if last_e and not formats:
     96             raise last_e
     97         self._sort_formats(formats)
     98 
     99         info = self._extract_theplatform_metadata(tp_path, content_id)
    100         info.update({
    101             'id': content_id,
    102             'title': title,
    103             'series': xpath_text(video_data, 'seriesTitle'),
    104             'season_number': int_or_none(xpath_text(video_data, 'seasonNumber')),
    105             'episode_number': int_or_none(xpath_text(video_data, 'episodeNumber')),
    106             'duration': int_or_none(xpath_text(video_data, 'videoLength'), 1000),
    107             'thumbnail': xpath_text(video_data, 'previewImageURL'),
    108             'formats': formats,
    109             'subtitles': subtitles,
    110         })
    111         return info
    112 
    113     def _real_extract(self, url):
    114         content_id = self._match_id(url)
    115         return self._extract_video_info(content_id)