]>
jfr.im git - yt-dlp.git/blob - yt_dlp/extractor/threeqsdn.py
3 from .common
import InfoExtractor
4 from ..compat
import compat_HTTPError
15 class ThreeQSDNIE(InfoExtractor
):
18 _VALID_URL
= r
'https?://playout\.3qsdn\.com/(?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})'
20 # https://player.3qsdn.com/demo.html
21 'url': 'https://playout.3qsdn.com/7201c779-6b3c-11e7-a40e-002590c750be',
22 'md5': '64a57396b16fa011b15e0ea60edce918',
24 'id': '7201c779-6b3c-11e7-a40e-002590c750be',
28 'description': 'Video Ads Demo',
29 'timestamp': 1500334803,
30 'upload_date': '20170717',
36 'expected_warnings': ['Unknown MIME type application/mp4 in DASH manifest'],
39 'url': 'https://playout.3qsdn.com/66e68995-11ca-11e8-9273-002590c750be',
41 'id': '66e68995-11ca-11e8-9273-002590c750be',
43 'title': 're:^66e68995-11ca-11e8-9273-002590c750be [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
47 'skip_download': True, # m3u8 downloads
51 'url': 'http://playout.3qsdn.com/9edf36e0-6bf2-11e2-a16a-9acf09e2db48',
52 'only_matching': True,
54 # live audio stream with some 404 URLs
55 'url': 'http://playout.3qsdn.com/ac5c3186-777a-11e2-9c30-9acf09e2db48',
56 'only_matching': True,
58 # geo restricted with 'This content is not available in your country'
59 'url': 'http://playout.3qsdn.com/d63a3ffe-75e8-11e2-9c30-9acf09e2db48',
60 'only_matching': True,
62 # geo restricted with 'playout.3qsdn.com/forbidden'
63 'url': 'http://playout.3qsdn.com/8e330f26-6ae2-11e2-a16a-9acf09e2db48',
64 'only_matching': True,
66 # live video with rtmp link
67 'url': 'https://playout.3qsdn.com/6092bb9e-8f72-11e4-a173-002590c750be',
68 'only_matching': True,
70 # ondemand from http://www.philharmonie.tv/veranstaltung/26/
71 'url': 'http://playout.3qsdn.com/0280d6b9-1215-11e6-b427-0cc47a188158?protocol=http',
72 'only_matching': True,
75 'url': 'https://playout.3qsdn.com/d755d94b-4ab9-11e3-9162-0025907ad44f?js=true',
76 'only_matching': True,
80 def _extract_url(webpage
):
82 r
'<iframe[^>]+\b(?:data-)?src=(["\'])(?P
<url
>%s.*?
)\
1' % ThreeQSDNIE._VALID_URL, webpage)
84 return mobj.group('url
')
86 def _real_extract(self, url):
87 video_id = self._match_id(url)
90 config = self._download_json(
91 url.replace('://playout
.3qsdn
.com
/', '://playout
.3qsdn
.com
/config
/'), video_id)
92 except ExtractorError as e:
93 if isinstance(e.cause, compat_HTTPError) and e.cause.code == 401:
94 self.raise_geo_restricted()
97 live = config.get('streamContent
') == 'live
'
98 aspect = float_or_none(config.get('aspect
'))
102 for source_type, source in (config.get('sources
') or {}).items():
105 if source_type == 'dash
':
106 fmts, subs = self._extract_mpd_formats_and_subtitles(
107 source, video_id, mpd_id='mpd
', fatal=False)
109 subtitles = self._merge_subtitles(subtitles, subs)
110 elif source_type == 'hls
':
111 fmts, subs = self._extract_m3u8_formats_and_subtitles(
112 source, video_id, 'mp4
', live=live, m3u8_id='hls
', fatal=False)
114 subtitles = self._merge_subtitles(subtitles, subs)
115 elif source_type == 'progressive
':
118 if not (src and self._is_valid_url(src, video_id)):
120 ext = determine_ext(src)
121 height = int_or_none(s.get('height
'))
124 'format_id
': join_nonempty('http
', ext, height and '%dp
' % height),
126 'source_preference
': 0,
128 'vcodec
': 'none
' if height == 0 else None,
129 'width
': int(height * aspect) if height and aspect else None,
131 # It seems like this would be correctly handled by default
132 # However, unless someone can confirm this, the old
133 # behaviour is being kept as-is
134 self._sort_formats(formats, ('res
', 'source_preference
'))
136 for subtitle in (config.get('subtitles
') or []):
137 src = subtitle.get('src
')
140 subtitles.setdefault(subtitle.get('label
') or 'eng
', []).append({
144 title = config.get('title
') or video_id
149 'thumbnail
': config.get('poster
') or None,
150 'description
': config.get('description
') or None,
151 'timestamp
': parse_iso8601(config.get('upload_date
')),
152 'duration
': float_or_none(config.get('vlength
')) or None,
155 'subtitles
': subtitles,