]>
Commit | Line | Data |
---|---|---|
53bfd6b2 | 1 | from __future__ import unicode_literals |
2 | ||
33a1ec95 | 3 | import re |
4 | ||
53bfd6b2 | 5 | from .common import InfoExtractor |
9298d4e3 | 6 | from ..utils import ( |
65ba8b23 | 7 | parse_duration, |
9298d4e3 | 8 | parse_iso8601, |
9298d4e3 | 9 | ) |
33a1ec95 | 10 | from ..compat import ( |
11 | compat_str, | |
12 | compat_urlparse, | |
13 | ) | |
53bfd6b2 | 14 | |
15 | ||
16 | class DiscoveryIE(InfoExtractor): | |
96a9f22d | 17 | _VALID_URL = r'''(?x)https?://(?:www\.)?(?: |
fec040e7 | 18 | discovery| |
19 | investigationdiscovery| | |
20 | discoverylife| | |
21 | animalplanet| | |
22 | ahctv| | |
23 | destinationamerica| | |
24 | sciencechannel| | |
25 | tlc| | |
26 | velocity | |
b05641ce | 27 | )\.com/(?:[^/]+/)*(?P<id>[^./?#]+)''' |
65ba8b23 | 28 | _TESTS = [{ |
cea2582d | 29 | 'url': 'http://www.discovery.com/tv-shows/mythbusters/videos/mission-impossible-outtakes.htm', |
53bfd6b2 | 30 | 'info_dict': { |
65ba8b23 YCH |
31 | 'id': '20769', |
32 | 'ext': 'mp4', | |
9298d4e3 | 33 | 'title': 'Mission Impossible Outtakes', |
9b05bd42 | 34 | 'description': ('Watch Jamie Hyneman and Adam Savage practice being' |
9e1a5b84 JW |
35 | ' each other -- to the point of confusing Jamie\'s dog -- and ' |
36 | 'don\'t miss Adam moon-walking as Jamie ... behind Jamie\'s' | |
37 | ' back.'), | |
9b05bd42 | 38 | 'duration': 156, |
fec040e7 | 39 | 'timestamp': 1302032462, |
40 | 'upload_date': '20110405', | |
9b05bd42 | 41 | }, |
65ba8b23 YCH |
42 | 'params': { |
43 | 'skip_download': True, # requires ffmpeg | |
44 | } | |
45 | }, { | |
46 | 'url': 'http://www.discovery.com/tv-shows/mythbusters/videos/mythbusters-the-simpsons', | |
47 | 'info_dict': { | |
48 | 'id': 'mythbusters-the-simpsons', | |
49 | 'title': 'MythBusters: The Simpsons', | |
50 | }, | |
fec040e7 | 51 | 'playlist_mincount': 10, |
52 | }, { | |
53 | 'url': 'http://www.animalplanet.com/longfin-eels-maneaters/', | |
54 | 'info_dict': { | |
55 | 'id': '78326', | |
56 | 'ext': 'mp4', | |
57 | 'title': 'Longfin Eels: Maneaters?', | |
58 | 'description': 'Jeremy Wade tests whether or not New Zealand\'s longfin eels are man-eaters by covering himself in fish guts and getting in the water with them.', | |
59 | 'upload_date': '20140725', | |
60 | 'timestamp': 1406246400, | |
61 | 'duration': 116, | |
62 | }, | |
65ba8b23 | 63 | }] |
53bfd6b2 | 64 | |
65 | def _real_extract(self, url): | |
fec040e7 | 66 | display_id = self._match_id(url) |
67 | info = self._download_json(url + '?flat=1', display_id) | |
9b05bd42 | 68 | |
65ba8b23 | 69 | video_title = info.get('playlist_title') or info.get('video_title') |
53bfd6b2 | 70 | |
19dbaeec S |
71 | entries = [] |
72 | ||
73 | for idx, video_info in enumerate(info['playlist']): | |
33a1ec95 | 74 | m3u8_url = video_info['src'] |
75 | formats = m3u8_formats = self._extract_m3u8_formats( | |
76 | m3u8_url, display_id, 'mp4', 'm3u8_native', m3u8_id='hls', | |
19dbaeec | 77 | note='Download m3u8 information for video %d' % (idx + 1)) |
33a1ec95 | 78 | qualities_basename = self._search_regex( |
79 | '/([^/]+)\.csmil/', m3u8_url, 'qualities basename', default=None) | |
80 | if qualities_basename: | |
81 | m3u8_path = compat_urlparse.urlparse(m3u8_url).path | |
82 | QUALITIES_RE = r'((,\d+k)+,?)' | |
83 | qualities = self._search_regex( | |
84 | QUALITIES_RE, qualities_basename, | |
85 | 'qualities', default=None) | |
86 | if qualities: | |
87 | qualities = list(map(lambda q: int(q[:-1]), qualities.strip(',').split(','))) | |
88 | qualities.sort() | |
89 | http_path = m3u8_path[1:].split('/', 1)[1] | |
90 | http_template = re.sub(QUALITIES_RE, r'%dk', http_path) | |
91 | http_template = http_template.replace('.csmil/master.m3u8', '') | |
92 | http_template = compat_urlparse.urljoin( | |
93 | 'http://discsmil.edgesuite.net/', http_template) | |
94 | if m3u8_formats: | |
95 | self._sort_formats(m3u8_formats) | |
96 | m3u8_formats = list(filter( | |
97 | lambda f: f.get('vcodec') != 'none' and f.get('resolution') != 'multiple', | |
98 | m3u8_formats)) | |
99 | if len(qualities) == len(m3u8_formats): | |
100 | for q, m3u8_format in zip(qualities, m3u8_formats): | |
101 | f = m3u8_format.copy() | |
102 | f.update({ | |
103 | 'url': http_template % q, | |
104 | 'format_id': f['format_id'].replace('hls', 'http'), | |
105 | 'protocol': 'http', | |
106 | }) | |
107 | formats.append(f) | |
108 | else: | |
109 | for q in qualities: | |
110 | formats.append({ | |
111 | 'url': http_template % q, | |
112 | 'ext': 'mp4', | |
113 | 'format_id': 'http-%d' % q, | |
114 | 'tbr': q, | |
115 | }) | |
19dbaeec | 116 | self._sort_formats(formats) |
93f7a31b | 117 | |
118 | subtitles = [] | |
119 | caption_url = video_info.get('captionsUrl') | |
120 | if caption_url: | |
121 | subtitles = { | |
122 | 'en': [{ | |
123 | 'url': caption_url, | |
124 | }] | |
125 | } | |
126 | ||
19dbaeec S |
127 | entries.append({ |
128 | 'id': compat_str(video_info['id']), | |
129 | 'formats': formats, | |
130 | 'title': video_info['title'], | |
131 | 'description': video_info.get('description'), | |
132 | 'duration': parse_duration(video_info.get('video_length')), | |
133 | 'webpage_url': video_info.get('href') or video_info.get('url'), | |
134 | 'thumbnail': video_info.get('thumbnailURL'), | |
135 | 'alt_title': video_info.get('secondary_title'), | |
136 | 'timestamp': parse_iso8601(video_info.get('publishedDate')), | |
93f7a31b | 137 | 'subtitles': subtitles, |
19dbaeec | 138 | }) |
65ba8b23 | 139 | |
fec040e7 | 140 | return self.playlist_result(entries, display_id, video_title) |