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