6 from .common
import InfoExtractor
12 class ZDFIE(InfoExtractor
):
13 _VALID_URL
= r
'^https?://www\.zdf\.de/ZDFmediathek(?P<hash>#)?/(.*beitrag/(?:video/)?)(?P<video_id>[0-9]+)(?:/[^/?]+)?(?:\?.*)?'
16 u
"url": u
"http://www.zdf.de/ZDFmediathek/beitrag/video/2037704/ZDFspezial---Ende-des-Machtpokers--?bc=sts;stt",
17 u
"file": u
"2037704.webm",
19 u
"upload_date": u
"20131127",
20 u
"description": u
"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\".",
21 u
"uploader": u
"spezial",
22 u
"title": u
"ZDFspezial - Ende des Machtpokers"
24 u
"skip": u
"Videos on ZDF.de are depublicised in short order",
27 def _real_extract(self
, url
):
28 mobj
= re
.match(self
._VALID
_URL
, url
)
29 video_id
= mobj
.group('video_id')
31 xml_url
= u
'http://www.zdf.de/ZDFmediathek/xmlservice/web/beitragsDetails?ak=web&id=%s' % video_id
32 doc
= self
._download
_xml
(
34 note
=u
'Downloading video info',
35 errnote
=u
'Failed to download video info')
37 title
= doc
.find('.//information/title').text
38 description
= doc
.find('.//information/detail').text
39 uploader_node
= doc
.find('.//details/originChannelTitle')
40 uploader
= None if uploader_node
is None else uploader_node
.text
41 duration_str
= doc
.find('.//details/length').text
42 duration_m
= re
.match(r
'''(?x)^
44 :(?P<minutes>[0-9]{2})
45 :(?P<seconds>[0-9]{2})
50 (int(duration_m
.group('hours')) * 60 * 60) +
51 (int(duration_m
.group('minutes')) * 60) +
52 int(duration_m
.group('seconds'))
57 upload_date
= unified_strdate(doc
.find('.//details/airtime').text
)
59 def xml_to_format(fnode
):
60 video_url
= fnode
.find('url').text
61 is_available
= u
'http://www.metafilegenerator' not in video_url
63 format_id
= fnode
.attrib
['basetype']
64 format_m
= re
.match(r
'''(?x)
65 (?P<vcodec>[^_]+)_(?P<acodec>[^_]+)_(?P<container>[^_]+)_
66 (?P<proto>[^_]+)_(?P<index>[^_]+)_(?P<indexproto>[^_]+)
69 ext
= format_m
.group('container')
70 is_supported
= ext
!= 'f4f'
72 PROTO_ORDER
= ['http', 'rtmp', 'rtsp']
74 proto_pref
= -PROTO_ORDER
.index(format_m
.group('proto'))
78 quality
= fnode
.find('./quality').text
79 QUALITY_ORDER
= ['veryhigh', '300', 'high', 'med', 'low']
81 quality_pref
= -QUALITY_ORDER
.index(quality
)
85 abr
= int(fnode
.find('./audioBitrate').text
) // 1000
86 vbr
= int(fnode
.find('./videoBitrate').text
) // 1000
87 pref
= (is_available
, is_supported
,
88 proto_pref
, quality_pref
, vbr
, abr
)
92 format_note
+= u
'(unsupported)'
97 'format_id': format_id
+ u
'-' + quality
,
100 'acodec': format_m
.group('acodec'),
101 'vcodec': format_m
.group('vcodec'),
104 'width': int(fnode
.find('./width').text
),
105 'height': int(fnode
.find('./height').text
),
106 'filesize': int(fnode
.find('./filesize').text
),
107 'format_note': format_note
,
109 '_available': is_available
,
112 format_nodes
= doc
.findall('.//formitaeten/formitaet')
113 formats
= sorted(filter(lambda f
: f
['_available'],
114 map(xml_to_format
, format_nodes
)),
115 key
=operator
.itemgetter('_pref'))
121 'description': description
,
122 'uploader': uploader
,
123 'duration': duration
,
124 'upload_date': upload_date
,