]>
Commit | Line | Data |
---|---|---|
c561b75c S |
1 | # coding: utf-8 |
2 | from __future__ import unicode_literals | |
3 | ||
6bd499e8 S |
4 | import re |
5 | ||
c561b75c S |
6 | from .common import InfoExtractor |
7 | from ..compat import compat_str | |
8 | from ..utils import ( | |
9 | int_or_none, | |
10 | parse_resolution, | |
ac379fa2 | 11 | str_or_none, |
c561b75c S |
12 | try_get, |
13 | unified_timestamp, | |
3052a30d | 14 | url_or_none, |
c561b75c S |
15 | urljoin, |
16 | ) | |
17 | ||
18 | ||
19 | class PeerTubeIE(InfoExtractor): | |
6bd499e8 | 20 | _INSTANCES_RE = r'''(?: |
c561b75c | 21 | # Taken from https://instances.joinpeertube.org/instances |
b64045cd AM |
22 | peertube\.rainbowswingers\.net| |
23 | tube\.stanisic\.nl| | |
24 | peer\.suiri\.us| | |
25 | medias\.libox\.fr| | |
26 | videomensoif\.ynh\.fr| | |
27 | peertube\.travelpandas\.eu| | |
28 | peertube\.rachetjay\.fr| | |
29 | peertube\.montecsys\.fr| | |
30 | tube\.eskuero\.me| | |
31 | peer\.tube| | |
32 | peertube\.umeahackerspace\.se| | |
33 | tube\.nx-pod\.de| | |
34 | video\.monsieurbidouille\.fr| | |
c561b75c | 35 | tube\.openalgeria\.org| |
b64045cd AM |
36 | vid\.lelux\.fi| |
37 | video\.anormallostpod\.ovh| | |
38 | tube\.crapaud-fou\.org| | |
39 | peertube\.stemy\.me| | |
40 | lostpod\.space| | |
41 | exode\.me| | |
42 | peertube\.snargol\.com| | |
43 | vis\.ion\.ovh| | |
44 | videosdulib\.re| | |
45 | v\.mbius\.io| | |
46 | videos\.judrey\.eu| | |
47 | peertube\.osureplayviewer\.xyz| | |
48 | peertube\.mathieufamily\.ovh| | |
49 | www\.videos-libr\.es| | |
50 | fightforinfo\.com| | |
51 | peertube\.fediverse\.ru| | |
52 | peertube\.oiseauroch\.fr| | |
53 | video\.nesven\.eu| | |
54 | v\.bearvideo\.win| | |
55 | video\.qoto\.org| | |
56 | justporn\.cc| | |
57 | video\.vny\.fr| | |
58 | peervideo\.club| | |
59 | tube\.taker\.fr| | |
60 | peertube\.chantierlibre\.org| | |
61 | tube\.ipfixe\.info| | |
62 | tube\.kicou\.info| | |
63 | tube\.dodsorf\.as| | |
64 | videobit\.cc| | |
65 | video\.yukari\.moe| | |
66 | videos\.elbinario\.net| | |
67 | hkvideo\.live| | |
68 | pt\.tux\.tf| | |
69 | www\.hkvideo\.live| | |
70 | FIGHTFORINFO\.com| | |
71 | pt\.765racing\.com| | |
72 | peertube\.gnumeria\.eu\.org| | |
73 | nordenmedia\.com| | |
74 | peertube\.co\.uk| | |
75 | tube\.darfweb\.eu| | |
76 | tube\.kalah-france\.org| | |
77 | 0ch\.in| | |
78 | vod\.mochi\.academy| | |
79 | film\.node9\.org| | |
80 | peertube\.hatthieves\.es| | |
81 | video\.fitchfamily\.org| | |
82 | peertube\.ddns\.net| | |
83 | video\.ifuncle\.kr| | |
84 | video\.fdlibre\.eu| | |
85 | tube\.22decembre\.eu| | |
86 | peertube\.harmoniescreatives\.com| | |
87 | tube\.fabrigli\.fr| | |
88 | video\.thedwyers\.co| | |
89 | video\.bruitbruit\.com| | |
90 | peertube\.foxfam\.club| | |
91 | peer\.philoxweb\.be| | |
92 | videos\.bugs\.social| | |
93 | peertube\.malbert\.xyz| | |
94 | peertube\.bilange\.ca| | |
95 | libretube\.net| | |
96 | diytelevision\.com| | |
97 | peertube\.fedilab\.app| | |
98 | libre\.video| | |
99 | video\.mstddntfdn\.online| | |
100 | us\.tv| | |
101 | peertube\.sl-network\.fr| | |
102 | peertube\.dynlinux\.io| | |
103 | peertube\.david\.durieux\.family| | |
104 | peertube\.linuxrocks\.online| | |
105 | peerwatch\.xyz| | |
106 | v\.kretschmann\.social| | |
107 | tube\.otter\.sh| | |
108 | yt\.is\.nota\.live| | |
109 | tube\.dragonpsi\.xyz| | |
110 | peertube\.boneheadmedia\.com| | |
111 | videos\.funkwhale\.audio| | |
112 | watch\.44con\.com| | |
113 | peertube\.gcaillaut\.fr| | |
114 | peertube\.icu| | |
115 | pony\.tube| | |
116 | spacepub\.space| | |
117 | tube\.stbr\.io| | |
118 | v\.mom-gay\.faith| | |
119 | tube\.port0\.xyz| | |
120 | peertube\.simounet\.net| | |
121 | play\.jergefelt\.se| | |
122 | peertube\.zeteo\.me| | |
123 | tube\.danq\.me| | |
124 | peertube\.kerenon\.com| | |
125 | tube\.fab-l3\.org| | |
126 | tube\.calculate\.social| | |
127 | peertube\.mckillop\.org| | |
128 | tube\.netzspielplatz\.de| | |
129 | vod\.ksite\.de| | |
130 | peertube\.laas\.fr| | |
131 | tube\.govital\.net| | |
132 | peertube\.stephenson\.cc| | |
133 | bistule\.nohost\.me| | |
134 | peertube\.kajalinifi\.de| | |
135 | video\.ploud\.jp| | |
136 | video\.omniatv\.com| | |
137 | peertube\.ffs2play\.fr| | |
138 | peertube\.leboulaire\.ovh| | |
139 | peertube\.tronic-studio\.com| | |
140 | peertube\.public\.cat| | |
141 | peertube\.metalbanana\.net| | |
142 | video\.1000i100\.fr| | |
143 | peertube\.alter-nativ-voll\.de| | |
144 | tube\.pasa\.tf| | |
145 | tube\.worldofhauru\.xyz| | |
146 | pt\.kamp\.site| | |
147 | peertube\.teleassist\.fr| | |
148 | videos\.mleduc\.xyz| | |
149 | conf\.tube| | |
150 | media\.privacyinternational\.org| | |
151 | pt\.forty-two\.nl| | |
152 | video\.halle-leaks\.de| | |
153 | video\.grosskopfgames\.de| | |
154 | peertube\.schaeferit\.de| | |
155 | peertube\.jackbot\.fr| | |
156 | tube\.extinctionrebellion\.fr| | |
157 | peertube\.f-si\.org| | |
158 | video\.subak\.ovh| | |
159 | videos\.koweb\.fr| | |
160 | peertube\.zergy\.net| | |
161 | peertube\.roflcopter\.fr| | |
162 | peertube\.floss-marketing-school\.com| | |
163 | vloggers\.social| | |
164 | peertube\.iriseden\.eu| | |
165 | videos\.ubuntu-paris\.org| | |
166 | peertube\.mastodon\.host| | |
167 | armstube\.com| | |
168 | peertube\.s2s\.video| | |
169 | peertube\.lol| | |
170 | tube\.open-plug\.eu| | |
171 | open\.tube| | |
172 | peertube\.ch| | |
173 | peertube\.normandie-libre\.fr| | |
174 | peertube\.slat\.org| | |
175 | video\.lacaveatonton\.ovh| | |
176 | peertube\.uno| | |
177 | peertube\.servebeer\.com| | |
178 | peertube\.fedi\.quebec| | |
179 | tube\.h3z\.jp| | |
180 | tube\.plus200\.com| | |
181 | peertube\.eric\.ovh| | |
182 | tube\.metadocs\.cc| | |
183 | tube\.unmondemeilleur\.eu| | |
184 | gouttedeau\.space| | |
185 | video\.antirep\.net| | |
186 | nrop\.cant\.at| | |
187 | tube\.ksl-bmx\.de| | |
188 | tube\.plaf\.fr| | |
189 | tube\.tchncs\.de| | |
190 | video\.devinberg\.com| | |
191 | hitchtube\.fr| | |
192 | peertube\.kosebamse\.com| | |
193 | yunopeertube\.myddns\.me| | |
194 | peertube\.varney\.fr| | |
195 | peertube\.anon-kenkai\.com| | |
196 | tube\.maiti\.info| | |
197 | tubee\.fr| | |
198 | videos\.dinofly\.com| | |
199 | toobnix\.org| | |
200 | videotape\.me| | |
201 | voca\.tube| | |
202 | video\.heromuster\.com| | |
203 | video\.lemediatv\.fr| | |
204 | video\.up\.edu\.ph| | |
205 | balafon\.video| | |
206 | video\.ivel\.fr| | |
207 | thickrips\.cloud| | |
208 | pt\.laurentkruger\.fr| | |
209 | video\.monarch-pass\.net| | |
210 | peertube\.artica\.center| | |
211 | video\.alternanet\.fr| | |
212 | indymotion\.fr| | |
213 | fanvid\.stopthatimp\.net| | |
214 | video\.farci\.org| | |
215 | v\.lesterpig\.com| | |
216 | video\.okaris\.de| | |
217 | tube\.pawelko\.net| | |
218 | peertube\.mablr\.org| | |
219 | tube\.fede\.re| | |
220 | pytu\.be| | |
221 | evertron\.tv| | |
222 | devtube\.dev-wiki\.de| | |
223 | raptube\.antipub\.org| | |
224 | video\.selea\.se| | |
225 | peertube\.mygaia\.org| | |
226 | video\.oh14\.de| | |
227 | peertube\.livingutopia\.org| | |
228 | peertube\.the-penguin\.de| | |
229 | tube\.thechangebook\.org| | |
230 | tube\.anjara\.eu| | |
231 | pt\.pube\.tk| | |
232 | video\.samedi\.pm| | |
233 | mplayer\.demouliere\.eu| | |
234 | widemus\.de| | |
235 | peertube\.me| | |
236 | peertube\.zapashcanon\.fr| | |
237 | video\.latavernedejohnjohn\.fr| | |
238 | peertube\.pcservice46\.fr| | |
239 | peertube\.mazzonetto\.eu| | |
240 | video\.irem\.univ-paris-diderot\.fr| | |
241 | video\.livecchi\.cloud| | |
242 | alttube\.fr| | |
243 | video\.coop\.tools| | |
244 | video\.cabane-libre\.org| | |
245 | peertube\.openstreetmap\.fr| | |
246 | videos\.alolise\.org| | |
247 | irrsinn\.video| | |
248 | video\.antopie\.org| | |
249 | scitech\.video| | |
250 | tube2\.nemsia\.org| | |
251 | video\.amic37\.fr| | |
252 | peertube\.freeforge\.eu| | |
253 | video\.arbitrarion\.com| | |
254 | video\.datsemultimedia\.com| | |
255 | stoptrackingus\.tv| | |
256 | peertube\.ricostrongxxx\.com| | |
257 | docker\.videos\.lecygnenoir\.info| | |
258 | peertube\.togart\.de| | |
259 | tube\.postblue\.info| | |
260 | videos\.domainepublic\.net| | |
261 | peertube\.cyber-tribal\.com| | |
262 | video\.gresille\.org| | |
263 | peertube\.dsmouse\.net| | |
264 | cinema\.yunohost\.support| | |
265 | tube\.theocevaer\.fr| | |
266 | repro\.video| | |
267 | tube\.4aem\.com| | |
268 | quaziinc\.com| | |
269 | peertube\.metawurst\.space| | |
270 | videos\.wakapo\.com| | |
271 | video\.ploud\.fr| | |
272 | video\.freeradical\.zone| | |
273 | tube\.valinor\.fr| | |
274 | refuznik\.video| | |
275 | pt\.kircheneuenburg\.de| | |
276 | peertube\.asrun\.eu| | |
277 | peertube\.lagob\.fr| | |
278 | videos\.side-ways\.net| | |
279 | 91video\.online| | |
280 | video\.valme\.io| | |
281 | video\.taboulisme\.com| | |
282 | videos-libr\.es| | |
283 | tv\.mooh\.fr| | |
284 | nuage\.acostey\.fr| | |
285 | video\.monsieur-a\.fr| | |
286 | peertube\.librelois\.fr| | |
287 | videos\.pair2jeux\.tube| | |
288 | videos\.pueseso\.club| | |
289 | peer\.mathdacloud\.ovh| | |
290 | media\.assassinate-you\.net| | |
291 | vidcommons\.org| | |
292 | ptube\.rousset\.nom\.fr| | |
293 | tube\.cyano\.at| | |
294 | videos\.squat\.net| | |
295 | video\.iphodase\.fr| | |
296 | peertube\.makotoworkshop\.org| | |
297 | peertube\.serveur\.slv-valbonne\.fr| | |
298 | vault\.mle\.party| | |
299 | hostyour\.tv| | |
300 | videos\.hack2g2\.fr| | |
301 | libre\.tube| | |
302 | pire\.artisanlogiciel\.net| | |
303 | videos\.numerique-en-commun\.fr| | |
304 | video\.netsyms\.com| | |
305 | video\.die-partei\.social| | |
306 | video\.writeas\.org| | |
307 | peertube\.swarm\.solvingmaz\.es| | |
308 | tube\.pericoloso\.ovh| | |
309 | watching\.cypherpunk\.observer| | |
310 | videos\.adhocmusic\.com| | |
311 | tube\.rfc1149\.net| | |
312 | peertube\.librelabucm\.org| | |
313 | videos\.numericoop\.fr| | |
314 | peertube\.koehn\.com| | |
315 | peertube\.anarchmusicall\.net| | |
316 | tube\.kampftoast\.de| | |
317 | vid\.y-y\.li| | |
318 | peertube\.xtenz\.xyz| | |
319 | diode\.zone| | |
320 | tube\.egf\.mn| | |
321 | peertube\.nomagic\.uk| | |
322 | visionon\.tv| | |
323 | videos\.koumoul\.com| | |
324 | video\.rastapuls\.com| | |
325 | video\.mantlepro\.com| | |
326 | video\.deadsuperhero\.com| | |
327 | peertube\.musicstudio\.pro| | |
328 | peertube\.we-keys\.fr| | |
329 | artitube\.artifaille\.fr| | |
330 | peertube\.ethernia\.net| | |
331 | tube\.midov\.pl| | |
332 | peertube\.fr| | |
333 | watch\.snoot\.tube| | |
334 | peertube\.donnadieu\.fr| | |
335 | argos\.aquilenet\.fr| | |
336 | tube\.nemsia\.org| | |
337 | tube\.bruniau\.net| | |
338 | videos\.darckoune\.moe| | |
339 | tube\.traydent\.info| | |
340 | dev\.videos\.lecygnenoir\.info| | |
341 | peertube\.nayya\.org| | |
342 | peertube\.live| | |
343 | peertube\.mofgao\.space| | |
344 | video\.lequerrec\.eu| | |
345 | peertube\.amicale\.net| | |
346 | aperi\.tube| | |
347 | tube\.ac-lyon\.fr| | |
348 | video\.lw1\.at| | |
349 | www\.yiny\.org| | |
350 | videos\.pofilo\.fr| | |
351 | tube\.lou\.lt| | |
352 | choob\.h\.etbus\.ch| | |
353 | tube\.hoga\.fr| | |
354 | peertube\.heberge\.fr| | |
355 | video\.obermui\.de| | |
356 | videos\.cloudfrancois\.fr| | |
357 | betamax\.video| | |
358 | video\.typica\.us| | |
359 | tube\.piweb\.be| | |
360 | video\.blender\.org| | |
361 | peertube\.cat| | |
362 | tube\.kdy\.ch| | |
363 | pe\.ertu\.be| | |
364 | peertube\.social| | |
365 | videos\.lescommuns\.org| | |
366 | tv\.datamol\.org| | |
367 | videonaute\.fr| | |
368 | dialup\.express| | |
c561b75c | 369 | peertube\.nogafa\.org| |
c561b75c S |
370 | megatube\.lilomoino\.fr| |
371 | peertube\.tamanoir\.foucry\.net| | |
c561b75c S |
372 | peertube\.devosi\.org| |
373 | peertube\.1312\.media| | |
c561b75c S |
374 | tube\.bootlicker\.party| |
375 | skeptikon\.fr| | |
c561b75c S |
376 | video\.blueline\.mg| |
377 | tube\.homecomputing\.fr| | |
c561b75c S |
378 | tube\.ouahpiti\.info| |
379 | video\.tedomum\.net| | |
380 | video\.g3l\.org| | |
381 | fontube\.fr| | |
382 | peertube\.gaialabs\.ch| | |
c561b75c S |
383 | tube\.kher\.nl| |
384 | peertube\.qtg\.fr| | |
c561b75c | 385 | video\.migennes\.net| |
c561b75c | 386 | tube\.p2p\.legal| |
c561b75c | 387 | troll\.tv| |
c561b75c S |
388 | videos\.iut-orsay\.fr| |
389 | peertube\.solidev\.net| | |
c561b75c | 390 | videos\.cemea\.org| |
c561b75c S |
391 | video\.passageenseine\.fr| |
392 | videos\.festivalparminous\.org| | |
393 | peertube\.touhoppai\.moe| | |
c561b75c | 394 | sikke\.fi| |
c561b75c S |
395 | peer\.hostux\.social| |
396 | share\.tube| | |
397 | peertube\.walkingmountains\.fr| | |
c561b75c | 398 | videos\.benpro\.fr| |
c561b75c | 399 | peertube\.parleur\.net| |
c561b75c | 400 | peertube\.heraut\.eu| |
c561b75c S |
401 | tube\.aquilenet\.fr| |
402 | peertube\.gegeweb\.eu| | |
403 | framatube\.org| | |
404 | thinkerview\.video| | |
405 | tube\.conferences-gesticulees\.net| | |
406 | peertube\.datagueule\.tv| | |
407 | video\.lqdn\.fr| | |
c561b75c | 408 | tube\.mochi\.academy| |
c561b75c | 409 | media\.zat\.im| |
c561b75c | 410 | video\.colibris-outilslibres\.org| |
c561b75c S |
411 | tube\.svnet\.fr| |
412 | peertube\.video| | |
c561b75c S |
413 | peertube3\.cpy\.re| |
414 | peertube2\.cpy\.re| | |
415 | videos\.tcit\.fr| | |
7c60c33e | 416 | peertube\.cpy\.re| |
417 | canard\.tube | |
6bd499e8 | 418 | )''' |
8b4b400a | 419 | _UUID_RE = r'[\da-fA-F]{8}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{4}-[\da-fA-F]{12}' |
1e1c1960 | 420 | _API_BASE = 'https://%s/api/v1/videos/%s/%s' |
6bd499e8 | 421 | _VALID_URL = r'''(?x) |
8b4b400a S |
422 | (?: |
423 | peertube:(?P<host>[^:]+):| | |
424 | https?://(?P<host_2>%s)/(?:videos/(?:watch|embed)|api/v\d/videos)/ | |
425 | ) | |
426 | (?P<id>%s) | |
427 | ''' % (_INSTANCES_RE, _UUID_RE) | |
c561b75c | 428 | _TESTS = [{ |
ac379fa2 | 429 | 'url': 'https://framatube.org/videos/watch/9c9de5e8-0a1e-484a-b099-e80766180a6d', |
430 | 'md5': '9bed8c0137913e17b86334e5885aacff', | |
c561b75c | 431 | 'info_dict': { |
ac379fa2 | 432 | 'id': '9c9de5e8-0a1e-484a-b099-e80766180a6d', |
c561b75c | 433 | 'ext': 'mp4', |
ac379fa2 | 434 | 'title': 'What is PeerTube?', |
1e1c1960 | 435 | 'description': 'md5:3fefb8dde2b189186ce0719fda6f7b10', |
c561b75c | 436 | 'thumbnail': r're:https?://.*\.(?:jpg|png)', |
ac379fa2 | 437 | 'timestamp': 1538391166, |
438 | 'upload_date': '20181001', | |
439 | 'uploader': 'Framasoft', | |
440 | 'uploader_id': '3', | |
441 | 'uploader_url': 'https://framatube.org/accounts/framasoft', | |
442 | 'channel': 'Les vidéos de Framasoft', | |
443 | 'channel_id': '2', | |
444 | 'channel_url': 'https://framatube.org/video-channels/bf54d359-cfad-4935-9d45-9d6be93f63e8', | |
445 | 'language': 'en', | |
446 | 'license': 'Attribution - Share Alike', | |
447 | 'duration': 113, | |
c561b75c S |
448 | 'view_count': int, |
449 | 'like_count': int, | |
450 | 'dislike_count': int, | |
ac379fa2 | 451 | 'tags': ['framasoft', 'peertube'], |
452 | 'categories': ['Science & Technology'], | |
c561b75c | 453 | } |
30a074c2 | 454 | }, { |
455 | # Issue #26002 | |
456 | 'url': 'peertube:spacepub.space:d8943b2d-8280-497b-85ec-bc282ec2afdc', | |
457 | 'info_dict': { | |
458 | 'id': 'd8943b2d-8280-497b-85ec-bc282ec2afdc', | |
459 | 'ext': 'mp4', | |
460 | 'title': 'Dot matrix printer shell demo', | |
461 | 'uploader_id': '3', | |
462 | 'timestamp': 1587401293, | |
463 | 'upload_date': '20200420', | |
464 | 'uploader': 'Drew DeVault', | |
465 | } | |
c561b75c S |
466 | }, { |
467 | 'url': 'https://peertube.tamanoir.foucry.net/videos/watch/0b04f13d-1e18-4f1d-814e-4979aa7c9c44', | |
468 | 'only_matching': True, | |
469 | }, { | |
470 | # nsfw | |
471 | 'url': 'https://tube.22decembre.eu/videos/watch/9bb88cd3-9959-46d9-9ab9-33d2bb704c39', | |
472 | 'only_matching': True, | |
f2fc63a5 S |
473 | }, { |
474 | 'url': 'https://tube.22decembre.eu/videos/embed/fed67262-6edb-4d1c-833b-daa9085c71d7', | |
475 | 'only_matching': True, | |
476 | }, { | |
477 | 'url': 'https://tube.openalgeria.org/api/v1/videos/c1875674-97d0-4c94-a058-3f7e64c962e8', | |
478 | 'only_matching': True, | |
8b4b400a S |
479 | }, { |
480 | 'url': 'peertube:video.blender.org:b37a5b9f-e6b5-415c-b700-04a5cd6ec205', | |
481 | 'only_matching': True, | |
c561b75c S |
482 | }] |
483 | ||
6bd499e8 | 484 | @staticmethod |
8b4b400a S |
485 | def _extract_peertube_url(webpage, source_url): |
486 | mobj = re.match( | |
d18003a1 | 487 | r'https?://(?P<host>[^/]+)/videos/(?:watch|embed)/(?P<id>%s)' |
8b4b400a S |
488 | % PeerTubeIE._UUID_RE, source_url) |
489 | if mobj and any(p in webpage for p in ( | |
490 | '<title>PeerTube<', | |
491 | 'There will be other non JS-based clients to access PeerTube', | |
492 | '>We are sorry but it seems that PeerTube is not compatible with your web browser.<')): | |
493 | return 'peertube:%s:%s' % mobj.group('host', 'id') | |
494 | ||
495 | @staticmethod | |
496 | def _extract_urls(webpage, source_url): | |
497 | entries = re.findall( | |
498 | r'''(?x)<iframe[^>]+\bsrc=["\'](?P<url>(?:https?:)?//%s/videos/embed/%s)''' | |
499 | % (PeerTubeIE._INSTANCES_RE, PeerTubeIE._UUID_RE), webpage) | |
500 | if not entries: | |
501 | peertube_url = PeerTubeIE._extract_peertube_url(webpage, source_url) | |
502 | if peertube_url: | |
503 | entries = [peertube_url] | |
504 | return entries | |
6bd499e8 | 505 | |
1e1c1960 S |
506 | def _call_api(self, host, video_id, path, note=None, errnote=None, fatal=True): |
507 | return self._download_json( | |
508 | self._API_BASE % (host, video_id, path), video_id, | |
509 | note=note, errnote=errnote, fatal=fatal) | |
ac379fa2 | 510 | |
1e1c1960 S |
511 | def _get_subtitles(self, host, video_id): |
512 | captions = self._call_api( | |
513 | host, video_id, 'captions', note='Downloading captions JSON', | |
514 | fatal=False) | |
515 | if not isinstance(captions, dict): | |
516 | return | |
517 | data = captions.get('data') | |
518 | if not isinstance(data, list): | |
519 | return | |
ac379fa2 | 520 | subtitles = {} |
1e1c1960 S |
521 | for e in data: |
522 | language_id = try_get(e, lambda x: x['language']['id'], compat_str) | |
523 | caption_url = urljoin('https://%s' % host, e.get('captionPath')) | |
524 | if not caption_url: | |
525 | continue | |
526 | subtitles.setdefault(language_id or 'en', []).append({ | |
527 | 'url': caption_url, | |
528 | }) | |
ac379fa2 | 529 | return subtitles |
530 | ||
c561b75c | 531 | def _real_extract(self, url): |
8b4b400a S |
532 | mobj = re.match(self._VALID_URL, url) |
533 | host = mobj.group('host') or mobj.group('host_2') | |
534 | video_id = mobj.group('id') | |
c561b75c | 535 | |
1e1c1960 S |
536 | video = self._call_api( |
537 | host, video_id, '', note='Downloading video JSON') | |
c561b75c S |
538 | |
539 | title = video['name'] | |
540 | ||
541 | formats = [] | |
30a074c2 | 542 | files = video.get('files') or [] |
543 | for playlist in (video.get('streamingPlaylists') or []): | |
544 | if not isinstance(playlist, dict): | |
545 | continue | |
546 | playlist_files = playlist.get('files') | |
547 | if not (playlist_files and isinstance(playlist_files, list)): | |
548 | continue | |
549 | files.extend(playlist_files) | |
550 | for file_ in files: | |
c561b75c S |
551 | if not isinstance(file_, dict): |
552 | continue | |
3052a30d S |
553 | file_url = url_or_none(file_.get('fileUrl')) |
554 | if not file_url: | |
c561b75c S |
555 | continue |
556 | file_size = int_or_none(file_.get('size')) | |
557 | format_id = try_get( | |
558 | file_, lambda x: x['resolution']['label'], compat_str) | |
559 | f = parse_resolution(format_id) | |
560 | f.update({ | |
561 | 'url': file_url, | |
562 | 'format_id': format_id, | |
563 | 'filesize': file_size, | |
564 | }) | |
29f7c58a | 565 | if format_id == '0p': |
566 | f['vcodec'] = 'none' | |
567 | else: | |
568 | f['fps'] = int_or_none(file_.get('fps')) | |
c561b75c S |
569 | formats.append(f) |
570 | self._sort_formats(formats) | |
571 | ||
51f8a31d | 572 | description = video.get('description') |
573 | if len(description) >= 250: | |
574 | # description is shortened | |
575 | full_description = self._call_api( | |
576 | host, video_id, 'description', note='Downloading description JSON', | |
577 | fatal=False) | |
ac379fa2 | 578 | |
51f8a31d | 579 | if isinstance(full_description, dict): |
580 | description = str_or_none(full_description.get('description')) or description | |
ac379fa2 | 581 | |
582 | subtitles = self.extract_subtitles(host, video_id) | |
583 | ||
584 | def data(section, field, type_): | |
585 | return try_get(video, lambda x: x[section][field], type_) | |
586 | ||
587 | def account_data(field, type_): | |
588 | return data('account', field, type_) | |
589 | ||
590 | def channel_data(field, type_): | |
591 | return data('channel', field, type_) | |
c561b75c | 592 | |
ac379fa2 | 593 | category = data('category', 'label', compat_str) |
c561b75c S |
594 | categories = [category] if category else None |
595 | ||
596 | nsfw = video.get('nsfw') | |
597 | if nsfw is bool: | |
598 | age_limit = 18 if nsfw else 0 | |
599 | else: | |
600 | age_limit = None | |
601 | ||
10db0d2f | 602 | webpage_url = 'https://%s/videos/watch/%s' % (host, video_id) |
603 | ||
c561b75c S |
604 | return { |
605 | 'id': video_id, | |
606 | 'title': title, | |
ac379fa2 | 607 | 'description': description, |
10db0d2f | 608 | 'thumbnail': urljoin(webpage_url, video.get('thumbnailPath')), |
c561b75c | 609 | 'timestamp': unified_timestamp(video.get('publishedAt')), |
ac379fa2 | 610 | 'uploader': account_data('displayName', compat_str), |
1e1c1960 | 611 | 'uploader_id': str_or_none(account_data('id', int)), |
ac379fa2 | 612 | 'uploader_url': url_or_none(account_data('url', compat_str)), |
613 | 'channel': channel_data('displayName', compat_str), | |
1e1c1960 | 614 | 'channel_id': str_or_none(channel_data('id', int)), |
ac379fa2 | 615 | 'channel_url': url_or_none(channel_data('url', compat_str)), |
616 | 'language': data('language', 'id', compat_str), | |
617 | 'license': data('licence', 'label', compat_str), | |
c561b75c S |
618 | 'duration': int_or_none(video.get('duration')), |
619 | 'view_count': int_or_none(video.get('views')), | |
620 | 'like_count': int_or_none(video.get('likes')), | |
621 | 'dislike_count': int_or_none(video.get('dislikes')), | |
622 | 'age_limit': age_limit, | |
623 | 'tags': try_get(video, lambda x: x['tags'], list), | |
624 | 'categories': categories, | |
625 | 'formats': formats, | |
10db0d2f | 626 | 'subtitles': subtitles, |
627 | 'webpage_url': webpage_url, | |
c561b75c | 628 | } |