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.

171 lines
6.2 KiB

  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. import re
  4. from .common import InfoExtractor
  5. from ..compat import compat_HTTPError
  6. from ..utils import (
  7. determine_ext,
  8. ExtractorError,
  9. int_or_none,
  10. unified_strdate,
  11. )
  12. class RadioCanadaIE(InfoExtractor):
  13. IE_NAME = 'radiocanada'
  14. _VALID_URL = r'(?:radiocanada:|https?://ici\.radio-canada\.ca/widgets/mediaconsole/)(?P<app_code>[^:/]+)[:/](?P<id>[0-9]+)'
  15. _TESTS = [
  16. {
  17. 'url': 'http://ici.radio-canada.ca/widgets/mediaconsole/medianet/7184272',
  18. 'info_dict': {
  19. 'id': '7184272',
  20. 'ext': 'mp4',
  21. 'title': 'Le parcours du tireur capté sur vidéo',
  22. 'description': 'Images des caméras de surveillance fournies par la GRC montrant le parcours du tireur d\'Ottawa',
  23. 'upload_date': '20141023',
  24. },
  25. 'params': {
  26. # m3u8 download
  27. 'skip_download': True,
  28. }
  29. },
  30. {
  31. # empty Title
  32. 'url': 'http://ici.radio-canada.ca/widgets/mediaconsole/medianet/7754998/',
  33. 'info_dict': {
  34. 'id': '7754998',
  35. 'ext': 'mp4',
  36. 'title': 'letelejournal22h',
  37. 'description': 'INTEGRALE WEB 22H-TJ',
  38. 'upload_date': '20170720',
  39. },
  40. 'params': {
  41. # m3u8 download
  42. 'skip_download': True,
  43. },
  44. },
  45. {
  46. # with protectionType but not actually DRM protected
  47. 'url': 'radiocanada:toutv:140872',
  48. 'info_dict': {
  49. 'id': '140872',
  50. 'title': 'Épisode 1',
  51. 'series': 'District 31',
  52. },
  53. 'only_matching': True,
  54. }
  55. ]
  56. _GEO_COUNTRIES = ['CA']
  57. _access_token = None
  58. _claims = None
  59. def _call_api(self, path, video_id=None, app_code=None, query=None):
  60. if not query:
  61. query = {}
  62. query.update({
  63. 'client_key': '773aea60-0e80-41bb-9c7f-e6d7c3ad17fb',
  64. 'output': 'json',
  65. })
  66. if video_id:
  67. query.update({
  68. 'appCode': app_code,
  69. 'idMedia': video_id,
  70. })
  71. if self._access_token:
  72. query['access_token'] = self._access_token
  73. try:
  74. return self._download_json(
  75. 'https://services.radio-canada.ca/media/' + path, video_id, query=query)
  76. except ExtractorError as e:
  77. if isinstance(e.cause, compat_HTTPError) and e.cause.code in (401, 422):
  78. data = self._parse_json(e.cause.read().decode(), None)
  79. error = data.get('error_description') or data['errorMessage']['text']
  80. raise ExtractorError(error, expected=True)
  81. raise
  82. def _extract_info(self, app_code, video_id):
  83. metas = self._call_api('meta/v1/index.ashx', video_id, app_code)['Metas']
  84. def get_meta(name):
  85. for meta in metas:
  86. if meta.get('name') == name:
  87. text = meta.get('text')
  88. if text:
  89. return text
  90. # protectionType does not necessarily mean the video is DRM protected (see
  91. # https://github.com/ytdl-org/youtube-dl/pull/18609).
  92. if get_meta('protectionType'):
  93. self.report_warning('This video is probably DRM protected.')
  94. query = {
  95. 'connectionType': 'hd',
  96. 'deviceType': 'ipad',
  97. 'multibitrate': 'true',
  98. }
  99. if self._claims:
  100. query['claims'] = self._claims
  101. v_data = self._call_api('validation/v2/', video_id, app_code, query)
  102. v_url = v_data.get('url')
  103. if not v_url:
  104. error = v_data['message']
  105. if error == "Le contenu sélectionné n'est pas disponible dans votre pays":
  106. raise self.raise_geo_restricted(error, self._GEO_COUNTRIES)
  107. if error == 'Le contenu sélectionné est disponible seulement en premium':
  108. self.raise_login_required(error)
  109. raise ExtractorError(
  110. '%s said: %s' % (self.IE_NAME, error), expected=True)
  111. formats = self._extract_m3u8_formats(v_url, video_id, 'mp4')
  112. self._sort_formats(formats)
  113. subtitles = {}
  114. closed_caption_url = get_meta('closedCaption') or get_meta('closedCaptionHTML5')
  115. if closed_caption_url:
  116. subtitles['fr'] = [{
  117. 'url': closed_caption_url,
  118. 'ext': determine_ext(closed_caption_url, 'vtt'),
  119. }]
  120. return {
  121. 'id': video_id,
  122. 'title': get_meta('Title') or get_meta('AV-nomEmission'),
  123. 'description': get_meta('Description') or get_meta('ShortDescription'),
  124. 'thumbnail': get_meta('imageHR') or get_meta('imageMR') or get_meta('imageBR'),
  125. 'duration': int_or_none(get_meta('length')),
  126. 'series': get_meta('Emission'),
  127. 'season_number': int_or_none('SrcSaison'),
  128. 'episode_number': int_or_none('SrcEpisode'),
  129. 'upload_date': unified_strdate(get_meta('Date')),
  130. 'subtitles': subtitles,
  131. 'formats': formats,
  132. }
  133. def _real_extract(self, url):
  134. return self._extract_info(*re.match(self._VALID_URL, url).groups())
  135. class RadioCanadaAudioVideoIE(InfoExtractor):
  136. IE_NAME = 'radiocanada:audiovideo'
  137. _VALID_URL = r'https?://ici\.radio-canada\.ca/([^/]+/)*media-(?P<id>[0-9]+)'
  138. _TESTS = [{
  139. 'url': 'http://ici.radio-canada.ca/audio-video/media-7527184/barack-obama-au-vietnam',
  140. 'info_dict': {
  141. 'id': '7527184',
  142. 'ext': 'mp4',
  143. 'title': 'Barack Obama au Vietnam',
  144. 'description': 'Les États-Unis lèvent l\'embargo sur la vente d\'armes qui datait de la guerre du Vietnam',
  145. 'upload_date': '20160523',
  146. },
  147. 'params': {
  148. # m3u8 download
  149. 'skip_download': True,
  150. },
  151. }, {
  152. 'url': 'https://ici.radio-canada.ca/info/videos/media-7527184/barack-obama-au-vietnam',
  153. 'only_matching': True,
  154. }]
  155. def _real_extract(self, url):
  156. return self.url_result('radiocanada:medianet:%s' % self._match_id(url))