]>
Commit | Line | Data |
---|---|---|
05a0068a RA |
1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
4 | import re | |
5 | ||
6 | from .common import InfoExtractor | |
7 | from ..utils import ( | |
fe45b0e0 | 8 | ExtractorError, |
29f7c58a | 9 | float_or_none, |
fe45b0e0 | 10 | int_or_none, |
29f7c58a | 11 | parse_iso8601, |
12 | try_get, | |
05a0068a RA |
13 | ) |
14 | ||
15 | ||
c9e12a61 | 16 | class NineCNineMediaIE(InfoExtractor): |
fe45b0e0 | 17 | IE_NAME = '9c9media' |
c9e12a61 | 18 | _GEO_COUNTRIES = ['CA'] |
fe45b0e0 | 19 | _VALID_URL = r'9c9media:(?P<destination_code>[^:]+):(?P<id>\d+)' |
c9e12a61 | 20 | _API_BASE_TEMPLATE = 'http://capi.9c9media.com/destinations/%s/platforms/desktop/contents/%s/' |
fe45b0e0 RA |
21 | |
22 | def _real_extract(self, url): | |
23 | destination_code, content_id = re.match(self._VALID_URL, url).groups() | |
24 | api_base_url = self._API_BASE_TEMPLATE % (destination_code, content_id) | |
25 | content = self._download_json(api_base_url, content_id, query={ | |
26 | '$include': '[Media,Season,ContentPackages]', | |
27 | }) | |
28 | title = content['Name'] | |
29 | if len(content['ContentPackages']) > 1: | |
30 | raise ExtractorError('multiple content packages') | |
31 | content_package = content['ContentPackages'][0] | |
32 | package_id = content_package['Id'] | |
33 | content_package_url = api_base_url + 'contentpackages/%s/' % package_id | |
c9e12a61 RA |
34 | content_package = self._download_json( |
35 | content_package_url, content_id, query={ | |
36 | '$include': '[HasClosedCaptions]', | |
37 | }) | |
fe45b0e0 | 38 | |
06869367 | 39 | if (not self._downloader.params.get('allow_unplayable_formats') |
40 | and try_get(content_package, lambda x: x['Constraints']['Security']['Type'])): | |
fe45b0e0 RA |
41 | raise ExtractorError('This video is DRM protected.', expected=True) |
42 | ||
c9e12a61 RA |
43 | manifest_base_url = content_package_url + 'manifest.' |
44 | formats = [] | |
45 | formats.extend(self._extract_m3u8_formats( | |
46 | manifest_base_url + 'm3u8', content_id, 'mp4', | |
47 | 'm3u8_native', m3u8_id='hls', fatal=False)) | |
48 | formats.extend(self._extract_f4m_formats( | |
49 | manifest_base_url + 'f4m', content_id, | |
50 | f4m_id='hds', fatal=False)) | |
51 | formats.extend(self._extract_mpd_formats( | |
52 | manifest_base_url + 'mpd', content_id, | |
53 | mpd_id='dash', fatal=False)) | |
54 | self._sort_formats(formats) | |
fe45b0e0 RA |
55 | |
56 | thumbnails = [] | |
29f7c58a | 57 | for image in (content.get('Images') or []): |
fe45b0e0 RA |
58 | image_url = image.get('Url') |
59 | if not image_url: | |
60 | continue | |
61 | thumbnails.append({ | |
62 | 'url': image_url, | |
63 | 'width': int_or_none(image.get('Width')), | |
64 | 'height': int_or_none(image.get('Height')), | |
65 | }) | |
66 | ||
67 | tags, categories = [], [] | |
68 | for source_name, container in (('Tags', tags), ('Genres', categories)): | |
69 | for e in content.get(source_name, []): | |
70 | e_name = e.get('Name') | |
71 | if not e_name: | |
72 | continue | |
73 | container.append(e_name) | |
74 | ||
29f7c58a | 75 | season = content.get('Season') or {} |
c9e12a61 RA |
76 | |
77 | info = { | |
78 | 'id': content_id, | |
79 | 'title': title, | |
80 | 'description': content.get('Desc') or content.get('ShortDesc'), | |
fe45b0e0 RA |
81 | 'timestamp': parse_iso8601(content.get('BroadcastDateTime')), |
82 | 'episode_number': int_or_none(content.get('Episode')), | |
83 | 'season': season.get('Name'), | |
29f7c58a | 84 | 'season_number': int_or_none(season.get('Number')), |
fe45b0e0 | 85 | 'season_id': season.get('Id'), |
29f7c58a | 86 | 'series': try_get(content, lambda x: x['Media']['Name']), |
fe45b0e0 RA |
87 | 'tags': tags, |
88 | 'categories': categories, | |
c9e12a61 RA |
89 | 'duration': float_or_none(content_package.get('Duration')), |
90 | 'formats': formats, | |
29f7c58a | 91 | 'thumbnails': thumbnails, |
fe45b0e0 RA |
92 | } |
93 | ||
c9e12a61 RA |
94 | if content_package.get('HasClosedCaptions'): |
95 | info['subtitles'] = { | |
96 | 'en': [{ | |
97 | 'url': manifest_base_url + 'vtt', | |
98 | 'ext': 'vtt', | |
99 | }, { | |
100 | 'url': manifest_base_url + 'srt', | |
101 | 'ext': 'srt', | |
102 | }] | |
fe45b0e0 | 103 | } |
fe45b0e0 | 104 | |
c9e12a61 | 105 | return info |