|
6 | 6 | from .common import InfoExtractor
|
7 | 7 | from ..compat import compat_urlparse
|
8 | 8 | from ..utils import (
|
9 |
| - determine_ext, |
10 | 9 | ExtractorError,
|
11 | 10 | float_or_none,
|
12 | 11 | int_or_none,
|
13 |
| - mimetype2ext, |
14 | 12 | parse_iso8601,
|
15 |
| - strip_jsonp, |
| 13 | + try_get, |
16 | 14 | )
|
17 | 15 |
|
18 | 16 |
|
19 | 17 | class ArkenaIE(InfoExtractor):
|
20 | 18 | _VALID_URL = r'''(?x)
|
21 | 19 | https?://
|
22 | 20 | (?:
|
23 |
| - video\.arkena\.com/play2/embed/player\?| |
| 21 | + video\.(?:arkena|qbrick)\.com/play2/embed/player\?| |
24 | 22 | play\.arkena\.com/(?:config|embed)/avp/v\d/player/media/(?P<id>[^/]+)/[^/]+/(?P<account_id>\d+)
|
25 | 23 | )
|
26 | 24 | '''
|
27 | 25 | _TESTS = [{
|
28 |
| - 'url': 'https://play.arkena.com/embed/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411', |
29 |
| - 'md5': 'b96f2f71b359a8ecd05ce4e1daa72365', |
| 26 | + 'url': 'https://video.qbrick.com/play2/embed/player?accountId=1034090&mediaId=d8ab4607-00090107-aab86310', |
| 27 | + 'md5': '97f117754e5f3c020f5f26da4a44ebaf', |
30 | 28 | 'info_dict': {
|
31 |
| - 'id': 'b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe', |
| 29 | + 'id': 'd8ab4607-00090107-aab86310', |
32 | 30 | 'ext': 'mp4',
|
33 |
| - 'title': 'Big Buck Bunny', |
34 |
| - 'description': 'Royalty free test video', |
35 |
| - 'timestamp': 1432816365, |
36 |
| - 'upload_date': '20150528', |
37 |
| - 'is_live': False, |
| 31 | + 'title': 'EM_HT20_117_roslund_v2.mp4', |
| 32 | + 'timestamp': 1608285912, |
| 33 | + 'upload_date': '20201218', |
| 34 | + 'duration': 1429.162667, |
| 35 | + 'subtitles': { |
| 36 | + 'sv': 'count:3', |
| 37 | + }, |
38 | 38 | },
|
| 39 | + }, { |
| 40 | + 'url': 'https://play.arkena.com/embed/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411', |
| 41 | + 'only_matching': True, |
39 | 42 | }, {
|
40 | 43 | 'url': 'https://play.arkena.com/config/avp/v2/player/media/b41dda37-d8e7-4d3f-b1b5-9a9db578bdfe/1/129411/?callbackMethod=jQuery1111023664739129262213_1469227693893',
|
41 | 44 | 'only_matching': True,
|
@@ -72,62 +75,89 @@ def _real_extract(self, url):
|
72 | 75 | if not video_id or not account_id:
|
73 | 76 | raise ExtractorError('Invalid URL', expected=True)
|
74 | 77 |
|
75 |
| - playlist = self._download_json( |
76 |
| - 'https://play.arkena.com/config/avp/v2/player/media/%s/0/%s/?callbackMethod=_' |
77 |
| - % (video_id, account_id), |
78 |
| - video_id, transform_source=strip_jsonp)['Playlist'][0] |
79 |
| - |
80 |
| - media_info = playlist['MediaInfo'] |
81 |
| - title = media_info['Title'] |
82 |
| - media_files = playlist['MediaFiles'] |
| 78 | + media = self._download_json( |
| 79 | + 'https://video.qbrick.com/api/v1/public/accounts/%s/medias/%s' % (account_id, video_id), |
| 80 | + video_id, query={ |
| 81 | + # https://video.qbrick.com/docs/api/examples/library-api.html |
| 82 | + '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', |
| 83 | + }) |
| 84 | + metadata = media.get('metadata') or {} |
| 85 | + title = metadata['title'] |
83 | 86 |
|
84 |
| - is_live = False |
| 87 | + duration = None |
85 | 88 | formats = []
|
86 |
| - for kind_case, kind_formats in media_files.items(): |
87 |
| - kind = kind_case.lower() |
88 |
| - for f in kind_formats: |
89 |
| - f_url = f.get('Url') |
90 |
| - if not f_url: |
91 |
| - continue |
92 |
| - is_live = f.get('Live') == 'true' |
93 |
| - exts = (mimetype2ext(f.get('Type')), determine_ext(f_url, None)) |
94 |
| - if kind == 'm3u8' or 'm3u8' in exts: |
95 |
| - formats.extend(self._extract_m3u8_formats( |
96 |
| - f_url, video_id, 'mp4', 'm3u8_native', |
97 |
| - m3u8_id=kind, fatal=False, live=is_live)) |
98 |
| - elif kind == 'flash' or 'f4m' in exts: |
99 |
| - formats.extend(self._extract_f4m_formats( |
100 |
| - f_url, video_id, f4m_id=kind, fatal=False)) |
101 |
| - elif kind == 'dash' or 'mpd' in exts: |
102 |
| - formats.extend(self._extract_mpd_formats( |
103 |
| - f_url, video_id, mpd_id=kind, fatal=False)) |
104 |
| - elif kind == 'silverlight': |
105 |
| - # TODO: process when ism is supported (see |
106 |
| - # https://github.com/ytdl-org/youtube-dl/issues/8118) |
107 |
| - continue |
108 |
| - else: |
109 |
| - tbr = float_or_none(f.get('Bitrate'), 1000) |
110 |
| - formats.append({ |
111 |
| - 'url': f_url, |
112 |
| - 'format_id': '%s-%d' % (kind, tbr) if tbr else kind, |
113 |
| - 'tbr': tbr, |
114 |
| - }) |
| 89 | + thumbnails = [] |
| 90 | + subtitles = {} |
| 91 | + for resource in media['asset']['resources']: |
| 92 | + for rendition in (resource.get('renditions') or []): |
| 93 | + rendition_type = rendition.get('type') |
| 94 | + for i, link in enumerate(rendition.get('links') or []): |
| 95 | + href = link.get('href') |
| 96 | + if not href: |
| 97 | + continue |
| 98 | + if rendition_type == 'image': |
| 99 | + thumbnails.append({ |
| 100 | + 'filesize': int_or_none(rendition.get('size')), |
| 101 | + 'height': int_or_none(rendition.get('height')), |
| 102 | + 'id': rendition.get('id'), |
| 103 | + 'url': href, |
| 104 | + 'width': int_or_none(rendition.get('width')), |
| 105 | + }) |
| 106 | + elif rendition_type == 'subtitle': |
| 107 | + subtitles.setdefault(rendition.get('language') or 'en', []).append({ |
| 108 | + 'url': href, |
| 109 | + }) |
| 110 | + elif rendition_type == 'video': |
| 111 | + f = { |
| 112 | + 'filesize': int_or_none(rendition.get('size')), |
| 113 | + 'format_id': rendition.get('id'), |
| 114 | + 'url': href, |
| 115 | + } |
| 116 | + video = try_get(rendition, lambda x: x['videos'][i], dict) |
| 117 | + if video: |
| 118 | + if not duration: |
| 119 | + duration = float_or_none(video.get('duration')) |
| 120 | + f.update({ |
| 121 | + 'height': int_or_none(video.get('height')), |
| 122 | + 'tbr': int_or_none(video.get('bitrate'), 1000), |
| 123 | + 'vcodec': video.get('codec'), |
| 124 | + 'width': int_or_none(video.get('width')), |
| 125 | + }) |
| 126 | + audio = try_get(video, lambda x: x['audios'][0], dict) |
| 127 | + if audio: |
| 128 | + f.update({ |
| 129 | + 'acodec': audio.get('codec'), |
| 130 | + 'asr': int_or_none(audio.get('sampleRate')), |
| 131 | + }) |
| 132 | + formats.append(f) |
| 133 | + elif rendition_type == 'index': |
| 134 | + mime_type = link.get('mimeType') |
| 135 | + if mime_type == 'application/smil+xml': |
| 136 | + formats.extend(self._extract_smil_formats( |
| 137 | + href, video_id, fatal=False)) |
| 138 | + elif mime_type == 'application/x-mpegURL': |
| 139 | + formats.extend(self._extract_m3u8_formats( |
| 140 | + href, video_id, 'mp4', 'm3u8_native', |
| 141 | + m3u8_id='hls', fatal=False)) |
| 142 | + elif mime_type == 'application/hds+xml': |
| 143 | + formats.extend(self._extract_f4m_formats( |
| 144 | + href, video_id, f4m_id='hds', fatal=False)) |
| 145 | + elif mime_type == 'application/dash+xml': |
| 146 | + formats.extend(self._extract_f4m_formats( |
| 147 | + href, video_id, f4m_id='hds', fatal=False)) |
| 148 | + elif mime_type == 'application/vnd.ms-sstr+xml': |
| 149 | + formats.extend(self._extract_ism_formats( |
| 150 | + href, video_id, ism_id='mss', fatal=False)) |
115 | 151 | self._sort_formats(formats)
|
116 | 152 |
|
117 |
| - description = media_info.get('Description') |
118 |
| - video_id = media_info.get('VideoId') or video_id |
119 |
| - timestamp = parse_iso8601(media_info.get('PublishDate')) |
120 |
| - thumbnails = [{ |
121 |
| - 'url': thumbnail['Url'], |
122 |
| - 'width': int_or_none(thumbnail.get('Size')), |
123 |
| - } for thumbnail in (media_info.get('Poster') or []) if thumbnail.get('Url')] |
124 |
| - |
125 | 153 | return {
|
126 | 154 | 'id': video_id,
|
127 | 155 | 'title': title,
|
128 |
| - 'description': description, |
129 |
| - 'timestamp': timestamp, |
130 |
| - 'is_live': is_live, |
| 156 | + 'description': metadata.get('description'), |
| 157 | + 'timestamp': parse_iso8601(media.get('created')), |
131 | 158 | 'thumbnails': thumbnails,
|
| 159 | + 'subtitles': subtitles, |
| 160 | + 'duration': duration, |
| 161 | + 'tags': media.get('tags'), |
132 | 162 | 'formats': formats,
|
133 | 163 | }
|
0 commit comments