[ie/wistia] Support password-protected videos (#11100)
[yt-dlp3.git] / yt_dlp / extractor / screencastify.py
blob3c43043de69634f7b305601360fd38c5e5e53669
1 import urllib.parse
3 from .common import InfoExtractor
4 from ..utils import traverse_obj, update_url_query
7 class ScreencastifyIE(InfoExtractor):
8 _VALID_URL = [
9 r'https?://watch\.screencastify\.com/v/(?P<id>[^/?#]+)',
10 r'https?://app\.screencastify\.com/v[23]/watch/(?P<id>[^/?#]+)',
12 _TESTS = [{
13 'url': 'https://watch.screencastify.com/v/sYVkZip3quLKhHw4Ybk8',
14 'info_dict': {
15 'id': 'sYVkZip3quLKhHw4Ybk8',
16 'ext': 'mp4',
17 'title': 'Inserting and Aligning the Case Top and Bottom',
18 'description': '',
19 'uploader': 'Paul Gunn',
20 'extra_param_to_segment_url': str,
22 'params': {
23 'skip_download': 'm3u8',
25 }, {
26 'url': 'https://app.screencastify.com/v3/watch/J5N7H11wofDN1jZUCr3t',
27 'info_dict': {
28 'id': 'J5N7H11wofDN1jZUCr3t',
29 'ext': 'mp4',
30 'uploader': 'Scott Piesen',
31 'description': '',
32 'title': 'Lesson Recording 1-17 Burrr...',
34 'params': {
35 'skip_download': 'm3u8',
37 }, {
38 'url': 'https://app.screencastify.com/v2/watch/BQ26VbUdfbQLhKzkktOk',
39 'only_matching': True,
42 def _real_extract(self, url):
43 video_id = self._match_id(url)
44 info = self._download_json(
45 f'https://umbrella.svc.screencastify.com/api/umbrellaService/watch/{video_id}', video_id)
47 query_string = traverse_obj(info, ('manifest', 'auth', 'query'))
48 query = urllib.parse.parse_qs(query_string)
49 formats = []
50 dash_manifest_url = traverse_obj(info, ('manifest', 'url'))
51 if dash_manifest_url:
52 formats.extend(
53 self._extract_mpd_formats(
54 dash_manifest_url, video_id, mpd_id='dash', query=query, fatal=False))
55 hls_manifest_url = traverse_obj(info, ('manifest', 'hlsUrl'))
56 if hls_manifest_url:
57 formats.extend(
58 self._extract_m3u8_formats(
59 hls_manifest_url, video_id, ext='mp4', m3u8_id='hls', query=query, fatal=False))
60 for f in formats:
61 f['url'] = update_url_query(f['url'], query)
63 return {
64 'id': video_id,
65 'title': info.get('title'),
66 'description': info.get('description'),
67 'uploader': info.get('userName'),
68 'formats': formats,
69 'extra_param_to_segment_url': query_string,