logo

youtube-dl

[mirror] Download/Watch videos from video hostersgit clone https://hacktivis.me/git/mirror/youtube-dl.git

arkena.py (7525B)


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