]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/threeqsdn.py
1 from __future__
import unicode_literals
5 from .common
import InfoExtractor
6 from ..compat
import compat_HTTPError
16 class ThreeQSDNIE(InfoExtractor
):
19 _VALID_URL
= r
'https?://playout\.3qsdn\.com/(?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})'
21 # https://player.3qsdn.com/demo.html
22 'url': 'https://playout.3qsdn.com/7201c779-6b3c-11e7-a40e-002590c750be',
23 'md5': '64a57396b16fa011b15e0ea60edce918',
25 'id': '7201c779-6b3c-11e7-a40e-002590c750be',
29 'description': 'Video Ads Demo',
30 'timestamp': 1500334803,
31 'upload_date': '20170717',
37 'expected_warnings': ['Unknown MIME type application/mp4 in DASH manifest'],
40 'url': 'https://playout.3qsdn.com/66e68995-11ca-11e8-9273-002590c750be',
42 'id': '66e68995-11ca-11e8-9273-002590c750be',
44 'title': 're:^66e68995-11ca-11e8-9273-002590c750be [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
48 'skip_download': True, # m3u8 downloads
52 'url': 'http://playout.3qsdn.com/9edf36e0-6bf2-11e2-a16a-9acf09e2db48',
53 'only_matching': True,
55 # live audio stream with some 404 URLs
56 'url': 'http://playout.3qsdn.com/ac5c3186-777a-11e2-9c30-9acf09e2db48',
57 'only_matching': True,
59 # geo restricted with 'This content is not available in your country'
60 'url': 'http://playout.3qsdn.com/d63a3ffe-75e8-11e2-9c30-9acf09e2db48',
61 'only_matching': True,
63 # geo restricted with 'playout.3qsdn.com/forbidden'
64 'url': 'http://playout.3qsdn.com/8e330f26-6ae2-11e2-a16a-9acf09e2db48',
65 'only_matching': True,
67 # live video with rtmp link
68 'url': 'https://playout.3qsdn.com/6092bb9e-8f72-11e4-a173-002590c750be',
69 'only_matching': True,
71 # ondemand from http://www.philharmonie.tv/veranstaltung/26/
72 'url': 'http://playout.3qsdn.com/0280d6b9-1215-11e6-b427-0cc47a188158?protocol=http',
73 'only_matching': True,
76 'url': 'https://playout.3qsdn.com/d755d94b-4ab9-11e3-9162-0025907ad44f?js=true',
77 'only_matching': True,
81 def _extract_url(webpage
):
83 r
'<iframe[^>]+\b(?:data-)?src=(["\'])(?P
<url
>%s.*?
)\
1' % ThreeQSDNIE._VALID_URL, webpage)
85 return mobj.group('url
')
87 def _real_extract(self, url):
88 video_id = self._match_id(url)
91 config = self._download_json(
92 url.replace('://playout
.3qsdn
.com
/', '://playout
.3qsdn
.com
/config
/'), video_id)
93 except ExtractorError as e:
94 if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401:
95 self.raise_geo_restricted()
98 live = config.get('streamContent
') == 'live
'
99 aspect = float_or_none(config.get('aspect
'))
103 for source_type, source in (config.get('sources
') or {}).items():
106 if source_type == 'dash
':
107 fmts, subs = self._extract_mpd_formats_and_subtitles(
108 source, video_id, mpd_id='mpd
', fatal=False)
110 subtitles = self._merge_subtitles(subtitles, subs)
111 elif source_type == 'hls
':
112 fmts, subs = self._extract_m3u8_formats_and_subtitles(
113 source, video_id, 'mp4
', 'm3u8
' if live else 'm3u8_native
',
114 m3u8_id='hls
', fatal=False)
116 subtitles = self._merge_subtitles(subtitles, subs)
117 elif source_type == 'progressive
':
120 if not (src and self._is_valid_url(src, video_id)):
124 ext = determine_ext(src)
126 format_id.append(ext)
127 height = int_or_none(s.get('height
'))
129 format_id.append('%dp
' % height)
131 width = int(height * aspect)
134 'format_id
': '-'.join(format_id),
136 'source_preference
': 0,
138 'vcodec
': 'none
' if height == 0 else None,
141 # It seems like this would be correctly handled by default
142 # However, unless someone can confirm this, the old
143 # behaviour is being kept as-is
144 self._sort_formats(formats, ('res
', 'source_preference
'))
146 for subtitle in (config.get('subtitles
') or []):
147 src = subtitle.get('src
')
150 subtitles.setdefault(subtitle.get('label
') or 'eng
', []).append({
154 title = config.get('title
') or video_id
158 'title
': self._live_title(title) if live else title,
159 'thumbnail
': config.get('poster
') or None,
160 'description
': config.get('description
') or None,
161 'timestamp
': parse_iso8601(config.get('upload_date
')),
162 'duration
': float_or_none(config.get('vlength
')) or None,
165 'subtitles
': subtitles,