]>
Commit | Line | Data |
---|---|---|
a2e6db36 | 1 | # coding: utf-8 |
919052d0 | 2 | from __future__ import unicode_literals |
a2e6db36 | 3 | |
d5822b96 PH |
4 | import re |
5 | ||
6 | from .common import InfoExtractor | |
7 | from ..utils import ( | |
61224dbc | 8 | int_or_none, |
02dbf93f | 9 | unified_strdate, |
d5822b96 PH |
10 | ) |
11 | ||
0b7c2485 | 12 | |
8cc3eba7 PH |
13 | def extract_from_xml_url(ie, video_id, xml_url): |
14 | doc = ie._download_xml( | |
15 | xml_url, video_id, | |
16 | note='Downloading video info', | |
17 | errnote='Failed to download video info') | |
18 | ||
19 | title = doc.find('.//information/title').text | |
20 | description = doc.find('.//information/detail').text | |
21 | duration = int(doc.find('.//details/lengthSec').text) | |
22 | uploader_node = doc.find('.//details/originChannelTitle') | |
23 | uploader = None if uploader_node is None else uploader_node.text | |
24 | uploader_id_node = doc.find('.//details/originChannelId') | |
25 | uploader_id = None if uploader_id_node is None else uploader_id_node.text | |
26 | upload_date = unified_strdate(doc.find('.//details/airtime').text) | |
27 | ||
28 | def xml_to_format(fnode): | |
29 | video_url = fnode.find('url').text | |
30 | is_available = 'http://www.metafilegenerator' not in video_url | |
31 | ||
32 | format_id = fnode.attrib['basetype'] | |
33 | format_m = re.match(r'''(?x) | |
34 | (?P<vcodec>[^_]+)_(?P<acodec>[^_]+)_(?P<container>[^_]+)_ | |
35 | (?P<proto>[^_]+)_(?P<index>[^_]+)_(?P<indexproto>[^_]+) | |
36 | ''', format_id) | |
37 | ||
38 | ext = format_m.group('container') | |
39 | proto = format_m.group('proto').lower() | |
40 | ||
41 | quality = fnode.find('./quality').text | |
42 | abr = int(fnode.find('./audioBitrate').text) // 1000 | |
43 | vbr_node = fnode.find('./videoBitrate') | |
44 | vbr = None if vbr_node is None else int(vbr_node.text) // 1000 | |
45 | ||
46 | width_node = fnode.find('./width') | |
47 | width = None if width_node is None else int_or_none(width_node.text) | |
48 | height_node = fnode.find('./height') | |
49 | height = None if height_node is None else int_or_none(height_node.text) | |
50 | ||
51 | format_note = '' | |
52 | if not format_note: | |
53 | format_note = None | |
54 | ||
55 | return { | |
56 | 'format_id': format_id + '-' + quality, | |
57 | 'url': video_url, | |
58 | 'ext': ext, | |
59 | 'acodec': format_m.group('acodec'), | |
60 | 'vcodec': format_m.group('vcodec'), | |
61 | 'abr': abr, | |
62 | 'vbr': vbr, | |
63 | 'width': width, | |
64 | 'height': height, | |
65 | 'filesize': int_or_none(fnode.find('./filesize').text), | |
66 | 'format_note': format_note, | |
67 | 'protocol': proto, | |
68 | '_available': is_available, | |
69 | } | |
70 | ||
71 | format_nodes = doc.findall('.//formitaeten/formitaet') | |
72 | formats = list(filter( | |
73 | lambda f: f['_available'], | |
74 | map(xml_to_format, format_nodes))) | |
75 | ie._sort_formats(formats) | |
76 | ||
77 | return { | |
78 | 'id': video_id, | |
79 | 'title': title, | |
80 | 'description': description, | |
81 | 'duration': duration, | |
82 | 'uploader': uploader, | |
83 | 'uploader_id': uploader_id, | |
84 | 'upload_date': upload_date, | |
85 | 'formats': formats, | |
86 | } | |
87 | ||
88 | ||
d5822b96 | 89 | class ZDFIE(InfoExtractor): |
aea85662 | 90 | _VALID_URL = r'^https?://www\.zdf\.de/ZDFmediathek(?P<hash>#)?/(.*beitrag/(?:video/)?)(?P<id>[0-9]+)(?:/[^/?]+)?(?:\?.*)?' |
a2e6db36 PH |
91 | |
92 | _TEST = { | |
919052d0 S |
93 | 'url': 'http://www.zdf.de/ZDFmediathek/beitrag/video/2037704/ZDFspezial---Ende-des-Machtpokers--?bc=sts;stt', |
94 | 'info_dict': { | |
95 | 'id': '2037704', | |
96 | 'ext': 'webm', | |
97 | 'title': 'ZDFspezial - Ende des Machtpokers', | |
98 | 'description': 'Union und SPD haben sich auf einen Koalitionsvertrag geeinigt. Aber was bedeutet das für die Bürger? Sehen Sie hierzu das ZDFspezial "Ende des Machtpokers - Große Koalition für Deutschland".', | |
99 | 'duration': 1022, | |
100 | 'uploader': 'spezial', | |
101 | 'uploader_id': '225948', | |
102 | 'upload_date': '20131127', | |
a2e6db36 | 103 | }, |
919052d0 | 104 | 'skip': 'Videos on ZDF.de are depublicised in short order', |
a2e6db36 | 105 | } |
d5822b96 PH |
106 | |
107 | def _real_extract(self, url): | |
aea85662 | 108 | video_id = self._match_id(url) |
d5822b96 | 109 | |
919052d0 | 110 | xml_url = 'http://www.zdf.de/ZDFmediathek/xmlservice/web/beitragsDetails?ak=web&id=%s' % video_id |
8cc3eba7 | 111 | return extract_from_xml_url(self, video_id, xml_url) |