]>
Commit | Line | Data |
---|---|---|
a0758dfa | 1 | from .common import InfoExtractor |
3d2623a8 | 2 | from ..networking.exceptions import HTTPError |
4ce3407d | 3 | from ..utils import ( |
e897bd82 SS |
4 | ExtractorError, |
5 | int_or_none, | |
4ce3407d RA |
6 | qualities, |
7 | strip_or_none, | |
4ce3407d | 8 | ) |
a0758dfa | 9 | |
10 | ||
11 | class FilmOnIE(InfoExtractor): | |
4ce3407d RA |
12 | IE_NAME = 'filmon' |
13 | _VALID_URL = r'(?:https?://(?:www\.)?filmon\.com/vod/view/|filmon:)(?P<id>\d+)' | |
a0758dfa | 14 | _TESTS = [{ |
4ce3407d RA |
15 | 'url': 'https://www.filmon.com/vod/view/24869-0-plan-9-from-outer-space', |
16 | 'info_dict': { | |
17 | 'id': '24869', | |
18 | 'ext': 'mp4', | |
19 | 'title': 'Plan 9 From Outer Space', | |
20 | 'description': 'Dead human, zombies and vampires', | |
21 | }, | |
a0758dfa | 22 | }, { |
4ce3407d RA |
23 | 'url': 'https://www.filmon.com/vod/view/2825-1-popeye-series-1', |
24 | 'info_dict': { | |
25 | 'id': '2825', | |
26 | 'title': 'Popeye Series 1', | |
27 | 'description': 'The original series of Popeye.', | |
28 | }, | |
29 | 'playlist_mincount': 8, | |
a0758dfa | 30 | }] |
31 | ||
32 | def _real_extract(self, url): | |
4ce3407d | 33 | video_id = self._match_id(url) |
a0758dfa | 34 | |
4ce3407d RA |
35 | try: |
36 | response = self._download_json( | |
add96eb9 | 37 | f'https://www.filmon.com/api/vod/movie?id={video_id}', |
4ce3407d RA |
38 | video_id)['response'] |
39 | except ExtractorError as e: | |
3d2623a8 | 40 | if isinstance(e.cause, HTTPError): |
41 | errmsg = self._parse_json(e.cause.response.read().decode(), video_id)['reason'] | |
add96eb9 | 42 | raise ExtractorError(f'{self.IE_NAME} said: {errmsg}', expected=True) |
4ce3407d | 43 | raise |
a0758dfa | 44 | |
4ce3407d RA |
45 | title = response['title'] |
46 | description = strip_or_none(response.get('description')) | |
a0758dfa | 47 | |
4ce3407d RA |
48 | if response.get('type_id') == 1: |
49 | entries = [self.url_result('filmon:' + episode_id) for episode_id in response.get('episodes', [])] | |
50 | return self.playlist_result(entries, video_id, title, description) | |
a0758dfa | 51 | |
4ce3407d RA |
52 | QUALITY = qualities(('low', 'high')) |
53 | formats = [] | |
54 | for format_id, stream in response.get('streams', {}).items(): | |
55 | stream_url = stream.get('url') | |
56 | if not stream_url: | |
57 | continue | |
a0758dfa | 58 | formats.append({ |
4ce3407d RA |
59 | 'format_id': format_id, |
60 | 'url': stream_url, | |
a0758dfa | 61 | 'ext': 'mp4', |
4ce3407d RA |
62 | 'quality': QUALITY(stream.get('quality')), |
63 | 'protocol': 'm3u8_native', | |
a0758dfa | 64 | }) |
a0758dfa | 65 | |
4ce3407d RA |
66 | thumbnails = [] |
67 | poster = response.get('poster', {}) | |
68 | thumbs = poster.get('thumbs', {}) | |
69 | thumbs['poster'] = poster | |
70 | for thumb_id, thumb in thumbs.items(): | |
71 | thumb_url = thumb.get('url') | |
72 | if not thumb_url: | |
73 | continue | |
74 | thumbnails.append({ | |
75 | 'id': thumb_id, | |
76 | 'url': thumb_url, | |
77 | 'width': int_or_none(thumb.get('width')), | |
78 | 'height': int_or_none(thumb.get('height')), | |
79 | }) | |
80 | ||
a0758dfa | 81 | return { |
4ce3407d RA |
82 | 'id': video_id, |
83 | 'title': title, | |
a0758dfa | 84 | 'formats': formats, |
4ce3407d | 85 | 'description': description, |
a0758dfa | 86 | 'thumbnails': thumbnails, |
a0758dfa | 87 | } |
88 | ||
89 | ||
4ce3407d RA |
90 | class FilmOnChannelIE(InfoExtractor): |
91 | IE_NAME = 'filmon:channel' | |
92 | _VALID_URL = r'https?://(?:www\.)?filmon\.com/(?:tv|channel)/(?P<id>[a-z0-9-]+)' | |
a0758dfa | 93 | _TESTS = [{ |
4ce3407d RA |
94 | # VOD |
95 | 'url': 'http://www.filmon.com/tv/sports-haters', | |
a0758dfa | 96 | 'info_dict': { |
4ce3407d | 97 | 'id': '4190', |
a0758dfa | 98 | 'ext': 'mp4', |
4ce3407d RA |
99 | 'title': 'Sports Haters', |
100 | 'description': 'md5:dabcb4c1d9cfc77085612f1a85f8275d', | |
a0758dfa | 101 | }, |
102 | }, { | |
4ce3407d RA |
103 | # LIVE |
104 | 'url': 'https://www.filmon.com/channel/filmon-sports', | |
105 | 'only_matching': True, | |
106 | }, { | |
107 | 'url': 'https://www.filmon.com/tv/2894', | |
108 | 'only_matching': True, | |
a0758dfa | 109 | }] |
110 | ||
4ce3407d RA |
111 | _THUMBNAIL_RES = [ |
112 | ('logo', 56, 28), | |
113 | ('big_logo', 106, 106), | |
114 | ('extra_big_logo', 300, 300), | |
115 | ] | |
a0758dfa | 116 | |
4ce3407d RA |
117 | def _real_extract(self, url): |
118 | channel_id = self._match_id(url) | |
a0758dfa | 119 | |
4ce3407d RA |
120 | try: |
121 | channel_data = self._download_json( | |
122 | 'http://www.filmon.com/api-v2/channel/' + channel_id, channel_id)['data'] | |
123 | except ExtractorError as e: | |
3d2623a8 | 124 | if isinstance(e.cause, HTTPError): |
125 | errmsg = self._parse_json(e.cause.response.read().decode(), channel_id)['message'] | |
add96eb9 | 126 | raise ExtractorError(f'{self.IE_NAME} said: {errmsg}', expected=True) |
4ce3407d | 127 | raise |
a0758dfa | 128 | |
add96eb9 | 129 | channel_id = str(channel_data['id']) |
4ce3407d RA |
130 | is_live = not channel_data.get('is_vod') and not channel_data.get('is_vox') |
131 | title = channel_data['title'] | |
a0758dfa | 132 | |
4ce3407d | 133 | QUALITY = qualities(('low', 'high')) |
a0758dfa | 134 | formats = [] |
4ce3407d RA |
135 | for stream in channel_data.get('streams', []): |
136 | stream_url = stream.get('url') | |
137 | if not stream_url: | |
138 | continue | |
139 | if not is_live: | |
140 | formats.extend(self._extract_wowza_formats( | |
141 | stream_url, channel_id, skip_protocols=['dash', 'rtmp', 'rtsp'])) | |
142 | continue | |
143 | quality = stream.get('quality') | |
a0758dfa | 144 | formats.append({ |
4ce3407d RA |
145 | 'format_id': quality, |
146 | # this is an m3u8 stream, but we are deliberately not using _extract_m3u8_formats | |
147 | # because it doesn't have bitrate variants anyway | |
148 | 'url': stream_url, | |
a0758dfa | 149 | 'ext': 'mp4', |
4ce3407d | 150 | 'quality': QUALITY(quality), |
a0758dfa | 151 | }) |
a0758dfa | 152 | |
4ce3407d RA |
153 | thumbnails = [] |
154 | for name, width, height in self._THUMBNAIL_RES: | |
a0758dfa | 155 | thumbnails.append({ |
4ce3407d | 156 | 'id': name, |
add96eb9 | 157 | 'url': f'http://static.filmon.com/assets/channels/{channel_id}/{name}.png', |
4ce3407d RA |
158 | 'width': width, |
159 | 'height': height, | |
a0758dfa | 160 | }) |
161 | ||
162 | return { | |
4ce3407d RA |
163 | 'id': channel_id, |
164 | 'display_id': channel_data.get('alias'), | |
39ca3b5c | 165 | 'title': title, |
4ce3407d | 166 | 'description': channel_data.get('description'), |
a0758dfa | 167 | 'thumbnails': thumbnails, |
4ce3407d RA |
168 | 'formats': formats, |
169 | 'is_live': is_live, | |
a0758dfa | 170 | } |