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