]>
Raphaƫl G. Git Repositories - youtubedl/blob - youtube_dl/extractor/threeqsdn.py
1 from __future__
import unicode_literals
5 from .common
import InfoExtractor
13 class ThreeQSDNIE(InfoExtractor
):
16 _VALID_URL
= r
'https?://playout\.3qsdn\.com/(?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})'
18 # ondemand from http://www.philharmonie.tv/veranstaltung/26/
19 'url': 'http://playout.3qsdn.com/0280d6b9-1215-11e6-b427-0cc47a188158?protocol=http',
20 'md5': 'ab040e37bcfa2e0c079f92cb1dd7f6cd',
22 'id': '0280d6b9-1215-11e6-b427-0cc47a188158',
24 'title': '0280d6b9-1215-11e6-b427-0cc47a188158',
27 'expected_warnings': ['Failed to download MPD manifest'],
30 'url': 'https://playout.3qsdn.com/d755d94b-4ab9-11e3-9162-0025907ad44f?js=true',
32 'id': 'd755d94b-4ab9-11e3-9162-0025907ad44f',
34 'title': 'd755d94b-4ab9-11e3-9162-0025907ad44f',
39 'url': 'http://playout.3qsdn.com/9edf36e0-6bf2-11e2-a16a-9acf09e2db48',
40 'only_matching': True,
42 # live audio stream with some 404 URLs
43 'url': 'http://playout.3qsdn.com/ac5c3186-777a-11e2-9c30-9acf09e2db48',
44 'only_matching': True,
46 # geo restricted with 'This content is not available in your country'
47 'url': 'http://playout.3qsdn.com/d63a3ffe-75e8-11e2-9c30-9acf09e2db48',
48 'only_matching': True,
50 # geo restricted with 'playout.3qsdn.com/forbidden'
51 'url': 'http://playout.3qsdn.com/8e330f26-6ae2-11e2-a16a-9acf09e2db48',
52 'only_matching': True,
54 # live video with rtmp link
55 'url': 'https://playout.3qsdn.com/6092bb9e-8f72-11e4-a173-002590c750be',
56 'only_matching': True,
60 def _extract_url(webpage
):
62 r
'<iframe[^>]+\b(?:data-)?src=(["\'])(?P
<url
>%s.*?
)\
1' % ThreeQSDNIE._VALID_URL, webpage)
64 return mobj.group('url
')
66 def _real_extract(self, url):
67 video_id = self._match_id(url)
69 js = self._download_webpage(
70 'http
://playout
.3qsdn
.com
/%s' % video_id, video_id,
73 if any(p in js for p in (
74 '>This content
is not available
in your country
',
75 'playout
.3qsdn
.com
/forbidden
')):
76 self.raise_geo_restricted()
78 stream_content = self._search_regex(
79 r'streamContent\s
*:\s
*(["\'])(?P<content>.+?)\1', js,
80 'stream content', default='demand', group='content')
82 live = stream_content == 'live'
84 stream_type = self._search_regex(
85 r'streamType\s*:\s*(["\'])(?P
<type>audio|video
)\
1', js,
86 'stream
type', default='video
', group='type')
91 def extract_formats(item_url, item={}):
92 if not item_url or item_url in urls:
95 type_ = item.get('type')
96 ext = determine_ext(item_url, default_ext=None)
97 if type_ == 'application
/dash
+xml
' or ext == 'mpd
':
98 formats.extend(self._extract_mpd_formats(
99 item_url, video_id, mpd_id='mpd
', fatal=False))
100 elif type_ in ('application
/vnd
.apple
.mpegURL
', 'application
/x
-mpegurl
') or ext == 'm3u8
':
101 formats.extend(self._extract_m3u8_formats(
102 item_url, video_id, 'mp4
',
103 entry_protocol='m3u8
' if live else 'm3u8_native
',
104 m3u8_id='hls
', fatal=False))
106 formats.extend(self._extract_f4m_formats(
107 item_url, video_id, f4m_id='hds
', fatal=False))
109 if not self._is_valid_url(item_url, video_id):
113 'format_id
': item.get('quality
'),
114 'ext
': 'mp4
' if item_url.startswith('rtsp
') else mimetype2ext(type_) or ext,
115 'vcodec
': 'none
' if stream_type == 'audio
' else None,
118 for item_js in re.findall(r'({.*?
\b(?
:src|source
)\s
*:\s
*["\'].+?})', js):
119 f = self._parse_json(
120 item_js, video_id, transform_source=js_to_json, fatal=False)
123 extract_formats(f.get('src'), f)
125 # More relaxed version to collect additional URLs and acting
126 # as a future-proof fallback
127 for _, src in re.findall(r'\b(?:src|source)\s*:\s*(["\'])((?
:https?|rtsp
)://.+?
)\
1', js):
130 self._sort_formats(formats)
132 title = self._live_title(video_id) if live else video_id