]>
Commit | Line | Data |
---|---|---|
69295694 | 1 | # coding: utf-8 |
938dd254 JMF |
2 | from __future__ import unicode_literals |
3 | ||
cb882540 | 4 | import uuid |
69295694 | 5 | |
938dd254 | 6 | from .common import InfoExtractor |
eb97f46e | 7 | from ..compat import ( |
cb882540 | 8 | compat_str, |
15707c7e | 9 | compat_urllib_parse_urlencode, |
eb97f46e JMF |
10 | compat_urlparse, |
11 | ) | |
1cc79574 | 12 | from ..utils import ( |
f84ce1eb | 13 | int_or_none, |
47335a0e RA |
14 | extract_attributes, |
15 | determine_ext, | |
cb882540 D |
16 | smuggle_url, |
17 | parse_duration, | |
938dd254 JMF |
18 | ) |
19 | ||
20 | ||
47335a0e RA |
21 | class MiTeleBaseIE(InfoExtractor): |
22 | def _get_player_info(self, url, webpage): | |
23 | player_data = extract_attributes(self._search_regex( | |
24 | r'(?s)(<ms-video-player.+?</ms-video-player>)', | |
25 | webpage, 'ms video player')) | |
26 | video_id = player_data['data-media-id'] | |
27 | config_url = compat_urlparse.urljoin(url, player_data['data-config']) | |
28 | config = self._download_json( | |
29 | config_url, video_id, 'Downloading config JSON') | |
30 | mmc_url = config['services']['mmc'] | |
31 | ||
32 | duration = None | |
33 | formats = [] | |
34 | for m_url in (mmc_url, mmc_url.replace('/flash.json', '/html5.json')): | |
35 | mmc = self._download_json( | |
36 | m_url, video_id, 'Downloading mmc JSON') | |
37 | if not duration: | |
38 | duration = int_or_none(mmc.get('duration')) | |
39 | for location in mmc['locations']: | |
40 | gat = self._proto_relative_url(location.get('gat'), 'http:') | |
41 | bas = location.get('bas') | |
42 | loc = location.get('loc') | |
43 | ogn = location.get('ogn') | |
44 | if None in (gat, bas, loc, ogn): | |
45 | continue | |
46 | token_data = { | |
47 | 'bas': bas, | |
48 | 'icd': loc, | |
49 | 'ogn': ogn, | |
50 | 'sta': '0', | |
51 | } | |
52 | media = self._download_json( | |
53 | '%s/?%s' % (gat, compat_urllib_parse_urlencode(token_data)), | |
54 | video_id, 'Downloading %s JSON' % location['loc']) | |
55 | file_ = media.get('file') | |
56 | if not file_: | |
57 | continue | |
58 | ext = determine_ext(file_) | |
59 | if ext == 'f4m': | |
60 | formats.extend(self._extract_f4m_formats( | |
61 | file_ + '&hdcore=3.2.0&plugin=aasp-3.2.0.77.18', | |
62 | video_id, f4m_id='hds', fatal=False)) | |
63 | elif ext == 'm3u8': | |
64 | formats.extend(self._extract_m3u8_formats( | |
65 | file_, video_id, 'mp4', 'm3u8_native', m3u8_id='hls', fatal=False)) | |
66 | self._sort_formats(formats) | |
67 | ||
68 | return { | |
69 | 'id': video_id, | |
70 | 'formats': formats, | |
71 | 'thumbnail': player_data.get('data-poster') or config.get('poster', {}).get('imageUrl'), | |
72 | 'duration': duration, | |
73 | } | |
74 | ||
75 | ||
cb882540 | 76 | class MiTeleIE(InfoExtractor): |
3368d70d | 77 | IE_DESC = 'mitele.es' |
b68599ed | 78 | _VALID_URL = r'https?://(?:www\.)?mitele\.es/(?:[^/]+/)+(?P<id>[^/]+)/player' |
938dd254 | 79 | |
69295694 | 80 | _TESTS = [{ |
cb882540 | 81 | 'url': 'http://www.mitele.es/programas-tv/diario-de/57b0dfb9c715da65618b4afa/player', |
938dd254 | 82 | 'info_dict': { |
cb882540 | 83 | 'id': '57b0dfb9c715da65618b4afa', |
47335a0e | 84 | 'ext': 'mp4', |
f84ce1eb S |
85 | 'title': 'Tor, la web invisible', |
86 | 'description': 'md5:3b6fce7eaa41b2d97358726378d9369f', | |
69295694 S |
87 | 'series': 'Diario de', |
88 | 'season': 'La redacción', | |
8eb7b5c3 S |
89 | 'season_number': 14, |
90 | 'season_id': 'diario_de_t14_11981', | |
69295694 | 91 | 'episode': 'Programa 144', |
8eb7b5c3 | 92 | 'episode_number': 3, |
ec85ded8 | 93 | 'thumbnail': r're:(?i)^https?://.*\.jpg$', |
938dd254 JMF |
94 | 'duration': 2913, |
95 | }, | |
cb882540 | 96 | 'add_ie': ['Ooyala'], |
69295694 S |
97 | }, { |
98 | # no explicit title | |
cb882540 | 99 | 'url': 'http://www.mitele.es/programas-tv/cuarto-milenio/57b0de3dc915da14058b4876/player', |
69295694 | 100 | 'info_dict': { |
cb882540 | 101 | 'id': '57b0de3dc915da14058b4876', |
47335a0e | 102 | 'ext': 'mp4', |
cb882540 D |
103 | 'title': 'Cuarto Milenio Temporada 6 Programa 226', |
104 | 'description': 'md5:5ff132013f0cd968ffbf1f5f3538a65f', | |
69295694 S |
105 | 'series': 'Cuarto Milenio', |
106 | 'season': 'Temporada 6', | |
8eb7b5c3 S |
107 | 'season_number': 6, |
108 | 'season_id': 'cuarto_milenio_t06_12715', | |
69295694 | 109 | 'episode': 'Programa 226', |
8eb7b5c3 | 110 | 'episode_number': 24, |
ec85ded8 | 111 | 'thumbnail': r're:(?i)^https?://.*\.jpg$', |
cb882540 | 112 | 'duration': 7313, |
69295694 S |
113 | }, |
114 | 'params': { | |
115 | 'skip_download': True, | |
116 | }, | |
cb882540 | 117 | 'add_ie': ['Ooyala'], |
b68599ed | 118 | }, { |
119 | 'url': 'http://www.mitele.es/series-online/la-que-se-avecina/57aac5c1c915da951a8b45ed/player', | |
120 | 'only_matching': True, | |
69295694 | 121 | }] |
938dd254 JMF |
122 | |
123 | def _real_extract(self, url): | |
cb882540 D |
124 | video_id = self._match_id(url) |
125 | webpage = self._download_webpage(url, video_id) | |
126 | ||
8eb7b5c3 S |
127 | gigya_url = self._search_regex( |
128 | r'<gigya-api>[^>]*</gigya-api>[^>]*<script\s+src="([^"]*)">[^>]*</script>', | |
129 | webpage, 'gigya', default=None) | |
130 | gigya_sc = self._download_webpage( | |
131 | compat_urlparse.urljoin('http://www.mitele.es/', gigya_url), | |
132 | video_id, 'Downloading gigya script') | |
133 | ||
cb882540 | 134 | # Get a appKey/uuid for getting the session key |
8eb7b5c3 S |
135 | appKey_var = self._search_regex( |
136 | r'value\s*\(\s*["\']appGridApplicationKey["\']\s*,\s*([0-9a-f]+)', | |
137 | gigya_sc, 'appKey variable') | |
138 | appKey = self._search_regex( | |
139 | r'var\s+%s\s*=\s*["\']([0-9a-f]+)' % appKey_var, gigya_sc, 'appKey') | |
140 | ||
141 | session_json = self._download_json( | |
142 | 'https://appgrid-api.cloud.accedo.tv/session', | |
143 | video_id, 'Downloading session keys', query={ | |
144 | 'appKey': appKey, | |
145 | 'uuid': compat_str(uuid.uuid4()), | |
146 | }) | |
147 | ||
148 | paths = self._download_json( | |
149 | 'https://appgrid-api.cloud.accedo.tv/metadata/general_configuration,%20web_configuration', | |
150 | video_id, 'Downloading paths JSON', | |
151 | query={'sessionKey': compat_str(session_json['sessionKey'])}) | |
152 | ||
cb882540 | 153 | ooyala_s = paths['general_configuration']['api_configuration']['ooyala_search'] |
8eb7b5c3 S |
154 | source = self._download_json( |
155 | 'http://%s%s%s/docs/%s' % ( | |
156 | ooyala_s['base_url'], ooyala_s['full_path'], | |
157 | ooyala_s['provider_id'], video_id), | |
158 | video_id, 'Downloading data JSON', query={ | |
159 | 'include_titles': 'Series,Season', | |
160 | 'product_name': 'test', | |
161 | 'format': 'full', | |
162 | })['hits']['hits'][0]['_source'] | |
cb882540 | 163 | |
8eb7b5c3 | 164 | embedCode = source['offers'][0]['embed_codes'][0] |
cb882540 | 165 | titles = source['localizable_titles'][0] |
8eb7b5c3 | 166 | |
cb882540 | 167 | title = titles.get('title_medium') or titles['title_long'] |
8eb7b5c3 S |
168 | |
169 | description = titles.get('summary_long') or titles.get('summary_medium') | |
170 | ||
171 | def get(key1, key2): | |
172 | value1 = source.get(key1) | |
173 | if not value1 or not isinstance(value1, list): | |
174 | return | |
175 | if not isinstance(value1[0], dict): | |
176 | return | |
177 | return value1[0].get(key2) | |
178 | ||
179 | series = get('localizable_titles_series', 'title_medium') | |
180 | ||
181 | season = get('localizable_titles_season', 'title_medium') | |
182 | season_number = int_or_none(source.get('season_number')) | |
183 | season_id = source.get('season_id') | |
184 | ||
185 | episode = titles.get('title_sort_name') | |
186 | episode_number = int_or_none(source.get('episode_number')) | |
187 | ||
188 | duration = parse_duration(get('videos', 'duration')) | |
f84ce1eb | 189 | |
cb882540 D |
190 | return { |
191 | '_type': 'url_transparent', | |
192 | # for some reason only HLS is supported | |
193 | 'url': smuggle_url('ooyala:' + embedCode, {'supportedformats': 'm3u8'}), | |
194 | 'id': video_id, | |
f84ce1eb | 195 | 'title': title, |
cb882540 | 196 | 'description': description, |
69295694 S |
197 | 'series': series, |
198 | 'season': season, | |
8eb7b5c3 S |
199 | 'season_number': season_number, |
200 | 'season_id': season_id, | |
69295694 | 201 | 'episode': episode, |
8eb7b5c3 | 202 | 'episode_number': episode_number, |
cb882540 | 203 | 'duration': duration, |
8eb7b5c3 | 204 | 'thumbnail': get('images', 'url'), |
cb882540 | 205 | } |