]>
Commit | Line | Data |
---|---|---|
80f772c2 | 1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
4 | from .common import InfoExtractor | |
5 | from ..utils import int_or_none | |
6 | ||
7 | ||
8 | class CrackleIE(InfoExtractor): | |
9 | _VALID_URL = r'(?:crackle:|https?://(?:www\.)?crackle\.com/(?:playlist/\d+/|(?:[^/]+/)+))(?P<id>\d+)' | |
10 | _TEST = { | |
11 | 'url': 'http://www.crackle.com/the-art-of-more/2496419', | |
12 | 'info_dict': { | |
13 | 'id': '2496419', | |
14 | 'ext': 'mp4', | |
15 | 'title': 'Heavy Lies the Head', | |
16 | 'description': 'md5:bb56aa0708fe7b9a4861535f15c3abca', | |
17 | }, | |
18 | 'params': { | |
19 | # m3u8 download | |
20 | 'skip_download': True, | |
21 | } | |
22 | } | |
23 | ||
24 | # extracted from http://legacyweb-us.crackle.com/flash/QueryReferrer.ashx | |
25 | _SUBTITLE_SERVER = 'http://web-us-az.crackle.com' | |
26 | _UPLYNK_OWNER_ID = 'e8773f7770a44dbd886eee4fca16a66b' | |
27 | _THUMBNAIL_TEMPLATE = 'http://images-us-am.crackle.com/%stnl_1920x1080.jpg?ts=20140107233116?c=635333335057637614' | |
28 | ||
29 | # extracted from http://legacyweb-us.crackle.com/flash/ReferrerRedirect.ashx | |
30 | _MEDIA_FILE_SLOTS = { | |
31 | 'c544.flv': { | |
32 | 'width': 544, | |
33 | 'height': 306, | |
34 | }, | |
35 | '360p.mp4': { | |
36 | 'width': 640, | |
37 | 'height': 360, | |
38 | }, | |
39 | '480p.mp4': { | |
40 | 'width': 852, | |
41 | 'height': 478, | |
42 | }, | |
43 | '480p_1mbps.mp4': { | |
44 | 'width': 852, | |
45 | 'height': 478, | |
46 | }, | |
47 | } | |
48 | ||
49 | def _real_extract(self, url): | |
50 | video_id = self._match_id(url) | |
51 | item = self._download_xml( | |
47d205a6 | 52 | 'http://legacyweb-us.crackle.com/app/revamp/vidwallcache.aspx?flags=-1&fm=%s' % video_id, |
53 | video_id).find('i') | |
80f772c2 | 54 | title = item.attrib['t'] |
55 | ||
56 | thumbnail = None | |
57 | subtitles = {} | |
47d205a6 | 58 | formats = self._extract_m3u8_formats( |
59 | 'http://content.uplynk.com/ext/%s/%s.m3u8' % (self._UPLYNK_OWNER_ID, video_id), | |
a1188d0e | 60 | video_id, 'mp4', m3u8_id='hls', fatal=None) |
80f772c2 | 61 | path = item.attrib.get('p') |
62 | if path: | |
63 | thumbnail = self._THUMBNAIL_TEMPLATE % path | |
64 | http_base_url = 'http://ahttp.crackle.com/' + path | |
65 | for mfs_path, mfs_info in self._MEDIA_FILE_SLOTS.items(): | |
66 | formats.append({ | |
67 | 'url': http_base_url + mfs_path, | |
a1188d0e | 68 | 'format_id': 'http-' + mfs_path.split('.')[0], |
80f772c2 | 69 | 'width': mfs_info['width'], |
70 | 'height': mfs_info['height'], | |
71 | }) | |
72 | for cc in item.findall('cc'): | |
73 | locale = cc.attrib.get('l') | |
74 | v = cc.attrib.get('v') | |
75 | if locale and v: | |
76 | if locale not in subtitles: | |
77 | subtitles[locale] = [] | |
78 | subtitles[locale] = [{ | |
79 | 'url': '%s/%s%s_%s.xml' % (self._SUBTITLE_SERVER, path, locale, v), | |
80 | 'ext': 'ttml', | |
81 | }] | |
47d205a6 | 82 | self._sort_formats(formats, ('width', 'height', 'tbr', 'format_id')) |
80f772c2 | 83 | |
84 | return { | |
85 | 'id': video_id, | |
86 | 'title': title, | |
87 | 'description': item.attrib.get('d'), | |
88 | 'duration': int(item.attrib.get('r'), 16) if item.attrib.get('r') else None, | |
89 | 'series': item.attrib.get('sn'), | |
90 | 'season_number': int_or_none(item.attrib.get('se')), | |
91 | 'episode_number': int_or_none(item.attrib.get('ep')), | |
92 | 'thumbnail': thumbnail, | |
93 | 'subtitles': subtitles, | |
94 | 'formats': formats, | |
95 | } |