logo

youtube-dl

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

telequebec.py (9308B)


  1. # coding: utf-8
  2. from __future__ import unicode_literals
  3. from .common import InfoExtractor
  4. from ..compat import compat_str
  5. from ..utils import (
  6. int_or_none,
  7. smuggle_url,
  8. try_get,
  9. unified_timestamp,
  10. )
  11. class TeleQuebecBaseIE(InfoExtractor):
  12. BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/%s/%s_default/index.html?videoId=%s'
  13. @staticmethod
  14. def _brightcove_result(brightcove_id, player_id, account_id='6150020952001'):
  15. return {
  16. '_type': 'url_transparent',
  17. 'url': smuggle_url(TeleQuebecBaseIE.BRIGHTCOVE_URL_TEMPLATE % (account_id, player_id, brightcove_id), {'geo_countries': ['CA']}),
  18. 'ie_key': 'BrightcoveNew',
  19. }
  20. class TeleQuebecIE(TeleQuebecBaseIE):
  21. _VALID_URL = r'''(?x)
  22. https?://
  23. (?:
  24. zonevideo\.telequebec\.tv/media|
  25. coucou\.telequebec\.tv/videos
  26. )/(?P<id>\d+)
  27. '''
  28. _TESTS = [{
  29. # available till 01.01.2023
  30. 'url': 'http://zonevideo.telequebec.tv/media/37578/un-petit-choc-et-puis-repart/un-chef-a-la-cabane',
  31. 'info_dict': {
  32. 'id': '6155972771001',
  33. 'ext': 'mp4',
  34. 'title': 'Un petit choc et puis repart!',
  35. 'description': 'md5:b04a7e6b3f74e32d7b294cffe8658374',
  36. 'timestamp': 1589262469,
  37. 'uploader_id': '6150020952001',
  38. 'upload_date': '20200512',
  39. },
  40. 'params': {
  41. 'format': 'bestvideo',
  42. },
  43. 'add_ie': ['BrightcoveNew'],
  44. }, {
  45. 'url': 'https://zonevideo.telequebec.tv/media/55267/le-soleil/passe-partout',
  46. 'info_dict': {
  47. 'id': '6167180337001',
  48. 'ext': 'mp4',
  49. 'title': 'Le soleil',
  50. 'description': 'md5:64289c922a8de2abbe99c354daffde02',
  51. 'uploader_id': '6150020952001',
  52. 'upload_date': '20200625',
  53. 'timestamp': 1593090307,
  54. },
  55. 'params': {
  56. 'format': 'bestvideo',
  57. },
  58. 'add_ie': ['BrightcoveNew'],
  59. }, {
  60. # no description
  61. 'url': 'http://zonevideo.telequebec.tv/media/30261',
  62. 'only_matching': True,
  63. }, {
  64. 'url': 'https://coucou.telequebec.tv/videos/41788/idee-de-genie/l-heure-du-bain',
  65. 'only_matching': True,
  66. }]
  67. def _real_extract(self, url):
  68. media_id = self._match_id(url)
  69. media = self._download_json(
  70. 'https://mnmedias.api.telequebec.tv/api/v3/media/' + media_id,
  71. media_id)['media']
  72. source_id = next(source_info['sourceId'] for source_info in media['streamInfos'] if source_info.get('source') == 'Brightcove')
  73. info = self._brightcove_result(source_id, '22gPKdt7f')
  74. product = media.get('product') or {}
  75. season = product.get('season') or {}
  76. info.update({
  77. 'description': try_get(media, lambda x: x['descriptions'][-1]['text'], compat_str),
  78. 'series': try_get(season, lambda x: x['serie']['titre']),
  79. 'season': season.get('name'),
  80. 'season_number': int_or_none(season.get('seasonNo')),
  81. 'episode': product.get('titre'),
  82. 'episode_number': int_or_none(product.get('episodeNo')),
  83. })
  84. return info
  85. class TeleQuebecSquatIE(InfoExtractor):
  86. _VALID_URL = r'https://squat\.telequebec\.tv/videos/(?P<id>\d+)'
  87. _TESTS = [{
  88. 'url': 'https://squat.telequebec.tv/videos/9314',
  89. 'info_dict': {
  90. 'id': 'd59ae78112d542e793d83cc9d3a5b530',
  91. 'ext': 'mp4',
  92. 'title': 'Poupeflekta',
  93. 'description': 'md5:2f0718f8d2f8fece1646ee25fb7bce75',
  94. 'duration': 1351,
  95. 'timestamp': 1569057600,
  96. 'upload_date': '20190921',
  97. 'series': 'Miraculous : Les Aventures de Ladybug et Chat Noir',
  98. 'season': 'Saison 3',
  99. 'season_number': 3,
  100. 'episode_number': 57,
  101. },
  102. 'params': {
  103. 'skip_download': True,
  104. },
  105. }]
  106. def _real_extract(self, url):
  107. video_id = self._match_id(url)
  108. video = self._download_json(
  109. 'https://squat.api.telequebec.tv/v1/videos/%s' % video_id,
  110. video_id)
  111. media_id = video['sourceId']
  112. return {
  113. '_type': 'url_transparent',
  114. 'url': 'http://zonevideo.telequebec.tv/media/%s' % media_id,
  115. 'ie_key': TeleQuebecIE.ie_key(),
  116. 'id': media_id,
  117. 'title': video.get('titre'),
  118. 'description': video.get('description'),
  119. 'timestamp': unified_timestamp(video.get('datePublication')),
  120. 'series': video.get('container'),
  121. 'season': video.get('saison'),
  122. 'season_number': int_or_none(video.get('noSaison')),
  123. 'episode_number': int_or_none(video.get('episode')),
  124. }
  125. class TeleQuebecEmissionIE(InfoExtractor):
  126. _VALID_URL = r'''(?x)
  127. https?://
  128. (?:
  129. [^/]+\.telequebec\.tv/emissions/|
  130. (?:www\.)?telequebec\.tv/
  131. )
  132. (?P<id>[^?#&]+)
  133. '''
  134. _TESTS = [{
  135. 'url': 'http://lindicemcsween.telequebec.tv/emissions/100430013/des-soins-esthetiques-a-377-d-interets-annuels-ca-vous-tente',
  136. 'info_dict': {
  137. 'id': '6154476028001',
  138. 'ext': 'mp4',
  139. 'title': 'Des soins esthétiques à 377 % d’intérêts annuels, ça vous tente?',
  140. 'description': 'md5:cb4d378e073fae6cce1f87c00f84ae9f',
  141. 'upload_date': '20200505',
  142. 'timestamp': 1588713424,
  143. 'uploader_id': '6150020952001',
  144. },
  145. 'params': {
  146. 'format': 'bestvideo',
  147. },
  148. }, {
  149. 'url': 'http://bancpublic.telequebec.tv/emissions/emission-49/31986/jeunes-meres-sous-pression',
  150. 'only_matching': True,
  151. }, {
  152. 'url': 'http://www.telequebec.tv/masha-et-michka/epi059masha-et-michka-3-053-078',
  153. 'only_matching': True,
  154. }, {
  155. 'url': 'http://www.telequebec.tv/documentaire/bebes-sur-mesure/',
  156. 'only_matching': True,
  157. }]
  158. def _real_extract(self, url):
  159. display_id = self._match_id(url)
  160. webpage = self._download_webpage(url, display_id)
  161. media_id = self._search_regex(
  162. r'mediaId\s*:\s*(?P<id>\d+)', webpage, 'media id')
  163. return self.url_result(
  164. 'http://zonevideo.telequebec.tv/media/' + media_id,
  165. TeleQuebecIE.ie_key())
  166. class TeleQuebecLiveIE(TeleQuebecBaseIE):
  167. _VALID_URL = r'https?://zonevideo\.telequebec\.tv/(?P<id>endirect)'
  168. _TEST = {
  169. 'url': 'http://zonevideo.telequebec.tv/endirect/',
  170. 'info_dict': {
  171. 'id': '6159095684001',
  172. 'ext': 'mp4',
  173. 'title': 're:^Télé-Québec [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
  174. 'is_live': True,
  175. 'description': 'Canal principal de Télé-Québec',
  176. 'uploader_id': '6150020952001',
  177. 'timestamp': 1590439901,
  178. 'upload_date': '20200525',
  179. },
  180. 'params': {
  181. 'skip_download': True,
  182. },
  183. }
  184. def _real_extract(self, url):
  185. return self._brightcove_result('6159095684001', 'skCsmi2Uw')
  186. class TeleQuebecVideoIE(TeleQuebecBaseIE):
  187. _VALID_URL = r'https?://video\.telequebec\.tv/player(?:-live)?/(?P<id>\d+)'
  188. _TESTS = [{
  189. 'url': 'https://video.telequebec.tv/player/31110/stream',
  190. 'info_dict': {
  191. 'id': '6202570652001',
  192. 'ext': 'mp4',
  193. 'title': 'Le coût du véhicule le plus vendu au Canada / Tous les frais liés à la procréation assistée',
  194. 'description': 'md5:685a7e4c450ba777c60adb6e71e41526',
  195. 'upload_date': '20201019',
  196. 'timestamp': 1603115930,
  197. 'uploader_id': '6101674910001',
  198. },
  199. 'params': {
  200. 'format': 'bestvideo',
  201. },
  202. }, {
  203. 'url': 'https://video.telequebec.tv/player-live/28527',
  204. 'only_matching': True,
  205. }]
  206. def _call_api(self, path, video_id):
  207. return self._download_json(
  208. 'http://beacon.playback.api.brightcove.com/telequebec/api/assets/' + path,
  209. video_id, query={'device_layout': 'web', 'device_type': 'web'})['data']
  210. def _real_extract(self, url):
  211. asset_id = self._match_id(url)
  212. asset = self._call_api(asset_id, asset_id)['asset']
  213. stream = self._call_api(
  214. asset_id + '/streams/' + asset['streams'][0]['id'], asset_id)['stream']
  215. stream_url = stream['url']
  216. account_id = try_get(
  217. stream, lambda x: x['video_provider_details']['account_id']) or '6101674910001'
  218. info = self._brightcove_result(stream_url, 'default', account_id)
  219. info.update({
  220. 'description': asset.get('long_description') or asset.get('short_description'),
  221. 'series': asset.get('series_original_name'),
  222. 'season_number': int_or_none(asset.get('season_number')),
  223. 'episode': asset.get('original_name'),
  224. 'episode_number': int_or_none(asset.get('episode_number')),
  225. })
  226. return info