You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

547 lines
25 KiB

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