]>
Commit | Line | Data |
---|---|---|
9787c5f4 | 1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
e33a7253 | 4 | from .adobepass import AdobePassIE |
a22ccac1 S |
5 | from .uplynk import UplynkPreplayIE |
6 | from ..compat import compat_str | |
e37b54b1 | 7 | from ..utils import ( |
a22ccac1 | 8 | HEADRequest, |
bf6ec2fe S |
9 | int_or_none, |
10 | parse_age_limit, | |
11 | parse_duration, | |
12 | try_get, | |
13 | unified_timestamp, | |
e37b54b1 | 14 | ) |
9787c5f4 | 15 | |
16 | ||
e33a7253 | 17 | class FOXIE(AdobePassIE): |
bf6ec2fe S |
18 | _VALID_URL = r'https?://(?:www\.)?fox\.com/watch/(?P<id>[\da-fA-F]+)' |
19 | _TESTS = [{ | |
20 | # clip | |
21 | 'url': 'https://www.fox.com/watch/4b765a60490325103ea69888fb2bd4e8/', | |
5e3a6fec | 22 | 'md5': 'ebd296fcc41dd4b19f8115d8461a3165', |
9787c5f4 | 23 | 'info_dict': { |
bf6ec2fe | 24 | 'id': '4b765a60490325103ea69888fb2bd4e8', |
9787c5f4 | 25 | 'ext': 'mp4', |
bf6ec2fe S |
26 | 'title': 'Aftermath: Bruce Wayne Develops Into The Dark Knight', |
27 | 'description': 'md5:549cd9c70d413adb32ce2a779b53b486', | |
28 | 'duration': 102, | |
29 | 'timestamp': 1504291893, | |
30 | 'upload_date': '20170901', | |
31 | 'creator': 'FOX', | |
32 | 'series': 'Gotham', | |
9787c5f4 | 33 | }, |
bf6ec2fe S |
34 | 'params': { |
35 | 'skip_download': True, | |
36 | }, | |
37 | }, { | |
38 | # episode, geo-restricted | |
39 | 'url': 'https://www.fox.com/watch/087036ca7f33c8eb79b08152b4dd75c1/', | |
40 | 'only_matching': True, | |
41 | }, { | |
42 | # episode, geo-restricted, tv provided required | |
43 | 'url': 'https://www.fox.com/watch/30056b295fb57f7452aeeb4920bc3024/', | |
44 | 'only_matching': True, | |
45 | }] | |
9787c5f4 | 46 | |
47 | def _real_extract(self, url): | |
48 | video_id = self._match_id(url) | |
7aa0ee32 | 49 | |
bf6ec2fe S |
50 | video = self._download_json( |
51 | 'https://api.fox.com/fbc-content/v1_4/video/%s' % video_id, | |
52 | video_id, headers={ | |
53 | 'apikey': 'abdcbed02c124d393b39e818a4312055', | |
54 | 'Content-Type': 'application/json', | |
55 | 'Referer': url, | |
56 | }) | |
57 | ||
58 | title = video['name'] | |
a22ccac1 | 59 | release_url = video['videoRelease']['url'] |
bf6ec2fe S |
60 | |
61 | description = video.get('description') | |
62 | duration = int_or_none(video.get('durationInSeconds')) or int_or_none( | |
63 | video.get('duration')) or parse_duration(video.get('duration')) | |
64 | timestamp = unified_timestamp(video.get('datePublished')) | |
65 | age_limit = parse_age_limit(video.get('contentRating')) | |
66 | ||
67 | data = try_get( | |
68 | video, lambda x: x['trackingData']['properties'], dict) or {} | |
69 | ||
70 | creator = data.get('brand') or data.get('network') or video.get('network') | |
71 | ||
72 | series = video.get('seriesName') or data.get( | |
73 | 'seriesName') or data.get('show') | |
74 | season_number = int_or_none(video.get('seasonNumber')) | |
75 | episode = video.get('name') | |
76 | episode_number = int_or_none(video.get('episodeNumber')) | |
77 | release_year = int_or_none(video.get('releaseYear')) | |
78 | ||
79 | if data.get('authRequired'): | |
80 | # TODO: AP | |
81 | pass | |
82 | ||
a22ccac1 | 83 | info = { |
bf6ec2fe S |
84 | 'id': video_id, |
85 | 'title': title, | |
86 | 'description': description, | |
87 | 'duration': duration, | |
88 | 'timestamp': timestamp, | |
89 | 'age_limit': age_limit, | |
90 | 'creator': creator, | |
91 | 'series': series, | |
92 | 'season_number': season_number, | |
93 | 'episode': episode, | |
94 | 'episode_number': episode_number, | |
95 | 'release_year': release_year, | |
bf6ec2fe | 96 | } |
a22ccac1 S |
97 | |
98 | urlh = self._request_webpage(HEADRequest(release_url), video_id) | |
99 | video_url = compat_str(urlh.geturl()) | |
100 | ||
101 | if UplynkPreplayIE.suitable(video_url): | |
102 | info.update({ | |
103 | '_type': 'url_transparent', | |
104 | 'url': video_url, | |
105 | 'ie_key': UplynkPreplayIE.ie_key(), | |
106 | }) | |
107 | else: | |
108 | m3u8_url = self._download_json(release_url, video_id)['playURL'] | |
109 | formats = self._extract_m3u8_formats( | |
110 | m3u8_url, video_id, 'mp4', | |
111 | entry_protocol='m3u8_native', m3u8_id='hls') | |
112 | self._sort_formats(formats) | |
113 | info['formats'] = formats | |
114 | return info |