]>
Commit | Line | Data |
---|---|---|
e9bf7479 JMF |
1 | import re |
2 | import json | |
3 | ||
4 | from .common import InfoExtractor | |
5 | from ..utils import ( | |
f8b56e95 | 6 | ExtractorError, |
e9bf7479 | 7 | xpath_with_ns, |
e9bf7479 JMF |
8 | ) |
9 | ||
10 | _x = lambda p: xpath_with_ns(p, {'smil': 'http://www.w3.org/2005/SMIL21/Language'}) | |
11 | ||
12 | ||
13 | class ThePlatformIE(InfoExtractor): | |
b9a2c538 | 14 | _VALID_URL = r'(?:https?://link\.theplatform\.com/s/[^/]+/|theplatform:)(?P<id>[^/\?]+)' |
e9bf7479 JMF |
15 | |
16 | _TEST = { | |
17 | # from http://www.metacafe.com/watch/cb-e9I_cZgTgIPd/blackberrys_big_bold_z30/ | |
18 | u'url': u'http://link.theplatform.com/s/dJ5BDC/e9I_cZgTgIPd/meta.smil?format=smil&Tracking=true&mbr=true', | |
19 | u'info_dict': { | |
20 | u'id': u'e9I_cZgTgIPd', | |
21 | u'ext': u'flv', | |
22 | u'title': u'Blackberry\'s big, bold Z30', | |
23 | u'description': u'The Z30 is Blackberry\'s biggest, baddest mobile messaging device yet.', | |
24 | u'duration': 247, | |
25 | }, | |
26 | u'params': { | |
27 | # rtmp download | |
28 | u'skip_download': True, | |
29 | }, | |
30 | } | |
31 | ||
32 | def _get_info(self, video_id): | |
33 | smil_url = ('http://link.theplatform.com/s/dJ5BDC/{0}/meta.smil?' | |
34 | 'format=smil&mbr=true'.format(video_id)) | |
35 | meta = self._download_xml(smil_url, video_id) | |
f8b56e95 PH |
36 | |
37 | try: | |
38 | error_msg = next( | |
39 | n.attrib['abstract'] | |
40 | for n in meta.findall(_x('.//smil:ref')) | |
48462108 | 41 | if n.attrib.get('title') == u'Geographic Restriction') |
f8b56e95 PH |
42 | except StopIteration: |
43 | pass | |
44 | else: | |
45 | raise ExtractorError(error_msg, expected=True) | |
46 | ||
e9bf7479 JMF |
47 | info_url = 'http://link.theplatform.com/s/dJ5BDC/{0}?format=preview'.format(video_id) |
48 | info_json = self._download_webpage(info_url, video_id) | |
49 | info = json.loads(info_json) | |
50 | ||
51 | head = meta.find(_x('smil:head')) | |
52 | body = meta.find(_x('smil:body')) | |
53 | base_url = head.find(_x('smil:meta')).attrib['base'] | |
54 | switch = body.find(_x('smil:switch')) | |
55 | formats = [] | |
56 | for f in switch.findall(_x('smil:video')): | |
57 | attr = f.attrib | |
360babf7 PH |
58 | width = int(attr['width']) |
59 | height = int(attr['height']) | |
60 | vbr = int(attr['system-bitrate']) // 1000 | |
61 | format_id = '%dx%d_%dk' % (width, height, vbr) | |
e9bf7479 | 62 | formats.append({ |
360babf7 | 63 | 'format_id': format_id, |
e9bf7479 JMF |
64 | 'url': base_url, |
65 | 'play_path': 'mp4:' + attr['src'], | |
66 | 'ext': 'flv', | |
360babf7 PH |
67 | 'width': width, |
68 | 'height': height, | |
69 | 'vbr': vbr, | |
e9bf7479 | 70 | }) |
360babf7 PH |
71 | |
72 | self._sort_formats(formats) | |
e9bf7479 JMF |
73 | |
74 | return { | |
75 | 'id': video_id, | |
76 | 'title': info['title'], | |
77 | 'formats': formats, | |
78 | 'description': info['description'], | |
79 | 'thumbnail': info['defaultThumbnailUrl'], | |
80 | 'duration': info['duration']//1000, | |
81 | } | |
82 | ||
83 | def _real_extract(self, url): | |
84 | mobj = re.match(self._VALID_URL, url) | |
85 | video_id = mobj.group('id') | |
86 | return self._get_info(video_id) |