]>
Commit | Line | Data |
---|---|---|
bbe1f363 S |
1 | from .common import InfoExtractor |
2 | from ..utils import ( | |
1f766b6e | 3 | ExtractorError, |
bbe1f363 S |
4 | float_or_none, |
5 | int_or_none, | |
bbe1f363 | 6 | parse_iso8601, |
4dfbf869 | 7 | parse_qs, |
29f7c58a | 8 | try_get, |
bbe1f363 S |
9 | ) |
10 | ||
11 | ||
12 | class ArkenaIE(InfoExtractor): | |
1f766b6e S |
13 | _VALID_URL = r'''(?x) |
14 | https?:// | |
15 | (?: | |
29f7c58a | 16 | video\.(?:arkena|qbrick)\.com/play2/embed/player\?| |
1f766b6e S |
17 | play\.arkena\.com/(?:config|embed)/avp/v\d/player/media/(?P<id>[^/]+)/[^/]+/(?P<account_id>\d+) |
18 | ) | |
19 | ''' | |
bfd973ec | 20 | # See https://support.arkena.com/display/PLAY/Ways+to+embed+your+video |
21 | _EMBED_REGEX = [r'<iframe[^>]+src=(["\'])(?P<url>(?:https?:)?//play\.arkena\.com/embed/avp/.+?)\1'] | |
bbe1f363 | 22 | _TESTS = [{ |
29f7c58a | 23 | 'url': 'https://video.qbrick.com/play2/embed/player?accountId=1034090&mediaId=d8ab4607-00090107-aab86310', |
24 | 'md5': '97f117754e5f3c020f5f26da4a44ebaf', | |
bbe1f363 | 25 | 'info_dict': { |
29f7c58a | 26 | 'id': 'd8ab4607-00090107-aab86310', |
bbe1f363 | 27 | 'ext': 'mp4', |
29f7c58a | 28 | 'title': 'EM_HT20_117_roslund_v2.mp4', |
29 | 'timestamp': 1608285912, | |
30 | 'upload_date': '20201218', | |
31 | 'duration': 1429.162667, | |
32 | 'subtitles': { | |
33 | 'sv': 'count:3', | |
34 | }, | |
bbe1f363 | 35 | }, |
29f7c58a | 36 | }, { |
37 | 'url': 'https://play.arkena.com/embed/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411', | |
38 | 'only_matching': True, | |
bbe1f363 S |
39 | }, { |
40 | 'url': 'https://play.arkena.com/config/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411/?callbackMethod=jQuery1111023664739129262213_1469227693893', | |
41 | 'only_matching': True, | |
42 | }, { | |
43 | 'url': 'http://play.arkena.com/config/avp/v1/player/media/327336/darkmatter/131064/?callbackMethod=jQuery1111002221189684892677_1469227595972', | |
44 | 'only_matching': True, | |
45 | }, { | |
46 | 'url': 'http://play.arkena.com/embed/avp/v1/player/media/327336/darkmatter/131064/', | |
47 | 'only_matching': True, | |
1f766b6e S |
48 | }, { |
49 | 'url': 'http://video.arkena.com/play2/embed/player?accountId=472718&mediaId=35763b3b-00090078-bf604299&pageStyling=styled', | |
50 | 'only_matching': True, | |
bbe1f363 S |
51 | }] |
52 | ||
bbe1f363 | 53 | def _real_extract(self, url): |
5ad28e7f | 54 | mobj = self._match_valid_url(url) |
bbe1f363 S |
55 | video_id = mobj.group('id') |
56 | account_id = mobj.group('account_id') | |
57 | ||
1f766b6e S |
58 | # Handle http://video.arkena.com/play2/embed/player URL |
59 | if not video_id: | |
4dfbf869 | 60 | qs = parse_qs(url) |
1f766b6e S |
61 | video_id = qs.get('mediaId', [None])[0] |
62 | account_id = qs.get('accountId', [None])[0] | |
63 | if not video_id or not account_id: | |
64 | raise ExtractorError('Invalid URL', expected=True) | |
65 | ||
29f7c58a | 66 | media = self._download_json( |
add96eb9 | 67 | f'https://video.qbrick.com/api/v1/public/accounts/{account_id}/medias/{video_id}', |
29f7c58a | 68 | video_id, query={ |
69 | # https://video.qbrick.com/docs/api/examples/library-api.html | |
70 | 'fields': 'asset/resources/*/renditions/*(height,id,language,links/*(href,mimeType),type,size,videos/*(audios/*(codec,sampleRate),bitrate,codec,duration,height,width),width),created,metadata/*(title,description),tags', | |
71 | }) | |
72 | metadata = media.get('metadata') or {} | |
73 | title = metadata['title'] | |
bbe1f363 | 74 | |
29f7c58a | 75 | duration = None |
bbe1f363 | 76 | formats = [] |
29f7c58a | 77 | thumbnails = [] |
78 | subtitles = {} | |
79 | for resource in media['asset']['resources']: | |
80 | for rendition in (resource.get('renditions') or []): | |
81 | rendition_type = rendition.get('type') | |
82 | for i, link in enumerate(rendition.get('links') or []): | |
83 | href = link.get('href') | |
84 | if not href: | |
85 | continue | |
86 | if rendition_type == 'image': | |
87 | thumbnails.append({ | |
88 | 'filesize': int_or_none(rendition.get('size')), | |
89 | 'height': int_or_none(rendition.get('height')), | |
90 | 'id': rendition.get('id'), | |
91 | 'url': href, | |
92 | 'width': int_or_none(rendition.get('width')), | |
93 | }) | |
94 | elif rendition_type == 'subtitle': | |
95 | subtitles.setdefault(rendition.get('language') or 'en', []).append({ | |
96 | 'url': href, | |
97 | }) | |
98 | elif rendition_type == 'video': | |
99 | f = { | |
100 | 'filesize': int_or_none(rendition.get('size')), | |
101 | 'format_id': rendition.get('id'), | |
102 | 'url': href, | |
103 | } | |
104 | video = try_get(rendition, lambda x: x['videos'][i], dict) | |
105 | if video: | |
106 | if not duration: | |
107 | duration = float_or_none(video.get('duration')) | |
108 | f.update({ | |
109 | 'height': int_or_none(video.get('height')), | |
110 | 'tbr': int_or_none(video.get('bitrate'), 1000), | |
111 | 'vcodec': video.get('codec'), | |
112 | 'width': int_or_none(video.get('width')), | |
113 | }) | |
114 | audio = try_get(video, lambda x: x['audios'][0], dict) | |
115 | if audio: | |
116 | f.update({ | |
117 | 'acodec': audio.get('codec'), | |
118 | 'asr': int_or_none(audio.get('sampleRate')), | |
119 | }) | |
120 | formats.append(f) | |
121 | elif rendition_type == 'index': | |
122 | mime_type = link.get('mimeType') | |
123 | if mime_type == 'application/smil+xml': | |
124 | formats.extend(self._extract_smil_formats( | |
125 | href, video_id, fatal=False)) | |
126 | elif mime_type == 'application/x-mpegURL': | |
127 | formats.extend(self._extract_m3u8_formats( | |
128 | href, video_id, 'mp4', 'm3u8_native', | |
129 | m3u8_id='hls', fatal=False)) | |
130 | elif mime_type == 'application/hds+xml': | |
131 | formats.extend(self._extract_f4m_formats( | |
132 | href, video_id, f4m_id='hds', fatal=False)) | |
133 | elif mime_type == 'application/dash+xml': | |
134 | formats.extend(self._extract_f4m_formats( | |
135 | href, video_id, f4m_id='hds', fatal=False)) | |
136 | elif mime_type == 'application/vnd.ms-sstr+xml': | |
137 | formats.extend(self._extract_ism_formats( | |
138 | href, video_id, ism_id='mss', fatal=False)) | |
bbe1f363 | 139 | |
bbe1f363 S |
140 | return { |
141 | 'id': video_id, | |
142 | 'title': title, | |
29f7c58a | 143 | 'description': metadata.get('description'), |
144 | 'timestamp': parse_iso8601(media.get('created')), | |
bbe1f363 | 145 | 'thumbnails': thumbnails, |
29f7c58a | 146 | 'subtitles': subtitles, |
147 | 'duration': duration, | |
148 | 'tags': media.get('tags'), | |
bbe1f363 S |
149 | 'formats': formats, |
150 | } |