1 from .common
import InfoExtractor
2 from ..networking
.exceptions
import HTTPError
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})'
17 _EMBED_REGEX
= [r
'<iframe[^>]+\b(?:data-)?src=(["\'])(?P
<url
>%s.*?
)\
1' % _VALID_URL]
19 # https://player.3qsdn.com/demo.html
20 'url
': 'https
://playout
.3qsdn
.com
/7201c779
-6b3c
-11e7
-a40e
-002590c750be
',
21 'md5
': '64a57396b16fa011b15e0ea60edce918
',
23 'id': '7201c779
-6b3c
-11e7
-a40e
-002590c750be
',
27 'description
': 'Video Ads Demo
',
28 'timestamp
': 1500334803,
29 'upload_date
': '20170717',
35 'expected_warnings
': ['Unknown MIME
type application
/mp4
in DASH manifest
'],
38 'url
': 'https
://playout
.3qsdn
.com
/66e68995
-11ca
-11e8
-9273-002590c750be
',
40 'id': '66e68995
-11ca
-11e8
-9273-002590c750be
',
42 'title
': 're
:^
66e68995
-11ca
-11e8
-9273-002590c750be
[0-9]{4}
-[0-9]{2}
-[0-9]{2}
[0-9]{2}
:[0-9]{2}$
',
46 'skip_download
': True, # m3u8 downloads
50 'url
': 'http
://playout
.3qsdn
.com
/9edf36e0
-6bf2
-11e2
-a16a
-9acf09e2db48
',
51 'only_matching
': True,
53 # live audio stream with some 404 URLs
54 'url
': 'http
://playout
.3qsdn
.com
/ac5c3186
-777a
-11e2
-9c30
-9acf09e2db48
',
55 'only_matching
': True,
57 # geo restricted with 'This content
is not available
in your country
'
58 'url
': 'http
://playout
.3qsdn
.com
/d63a3ffe
-75e8
-11e2
-9c30
-9acf09e2db48
',
59 'only_matching
': True,
61 # geo restricted with 'playout
.3qsdn
.com
/forbidden
'
62 'url
': 'http
://playout
.3qsdn
.com
/8e330f26
-6ae2
-11e2
-a16a
-9acf09e2db48
',
63 'only_matching
': True,
65 # live video with rtmp link
66 'url
': 'https
://playout
.3qsdn
.com
/6092bb9e
-8f72
-11e4
-a173
-002590c750be
',
67 'only_matching
': True,
69 # ondemand from http://www.philharmonie.tv/veranstaltung/26/
70 'url
': 'http
://playout
.3qsdn
.com
/0280d6b9
-1215-11e6
-b427
-0cc47a188158?protocol
=http
',
71 'only_matching
': True,
74 'url
': 'https
://playout
.3qsdn
.com
/d755d94b
-4ab9
-11e3
-9162-0025907ad44f?js
=true
',
75 'only_matching
': True,
78 def _extract_from_webpage(self, url, webpage):
79 for res in super()._extract_from_webpage(url, webpage):
82 '_type
': 'url_transparent
',
83 'uploader
': self._search_regex(r'^
(?
:https?
://)?
([^
/]*)/.*', url, 'video uploader
'),
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, HTTPError) and e.cause.status == 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,
132 for subtitle in (config.get('subtitles
') or []):
133 src = subtitle.get('src
')
136 subtitles.setdefault(subtitle.get('label
') or 'eng
', []).append({
140 title = config.get('title
') or video_id
145 'thumbnail
': config.get('poster
') or None,
146 'description
': config.get('description
') or None,
147 'timestamp
': parse_iso8601(config.get('upload_date
')),
148 'duration
': float_or_none(config.get('vlength
')) or None,
151 'subtitles
': subtitles,
152 # It seems like this would be correctly handled by default
153 # However, unless someone can confirm this, the old
154 # behaviour is being kept as-is
155 '_format_sort_fields
': ('res
', 'source_preference
')