[prosiebensat1] add support for new API(closes #21272)
This commit is contained in:
		| @@ -16,6 +16,11 @@ from ..utils import ( | |||||||
|  |  | ||||||
|  |  | ||||||
| class ProSiebenSat1BaseIE(InfoExtractor): | class ProSiebenSat1BaseIE(InfoExtractor): | ||||||
|  |     _GEO_COUNTRIES = ['DE'] | ||||||
|  |     _ACCESS_ID = None | ||||||
|  |     _SUPPORTED_PROTOCOLS = 'dash:clear,hls:clear,progressive:clear' | ||||||
|  |     _V4_BASE_URL = 'https://vas-v4.p7s1video.net/4.0/get' | ||||||
|  |  | ||||||
|     def _extract_video_info(self, url, clip_id): |     def _extract_video_info(self, url, clip_id): | ||||||
|         client_location = url |         client_location = url | ||||||
|  |  | ||||||
| @@ -31,93 +36,128 @@ class ProSiebenSat1BaseIE(InfoExtractor): | |||||||
|         if video.get('is_protected') is True: |         if video.get('is_protected') is True: | ||||||
|             raise ExtractorError('This video is DRM protected.', expected=True) |             raise ExtractorError('This video is DRM protected.', expected=True) | ||||||
|  |  | ||||||
|         duration = float_or_none(video.get('duration')) |  | ||||||
|         source_ids = [compat_str(source['id']) for source in video['sources']] |  | ||||||
|  |  | ||||||
|         client_id = self._SALT[:2] + sha1(''.join([clip_id, self._SALT, self._TOKEN, client_location, self._SALT, self._CLIENT_NAME]).encode('utf-8')).hexdigest() |  | ||||||
|  |  | ||||||
|         sources = self._download_json( |  | ||||||
|             'http://vas.sim-technik.de/vas/live/v2/videos/%s/sources' % clip_id, |  | ||||||
|             clip_id, 'Downloading sources JSON', query={ |  | ||||||
|                 'access_token': self._TOKEN, |  | ||||||
|                 'client_id': client_id, |  | ||||||
|                 'client_location': client_location, |  | ||||||
|                 'client_name': self._CLIENT_NAME, |  | ||||||
|             }) |  | ||||||
|         server_id = sources['server_id'] |  | ||||||
|  |  | ||||||
|         def fix_bitrate(bitrate): |  | ||||||
|             bitrate = int_or_none(bitrate) |  | ||||||
|             if not bitrate: |  | ||||||
|                 return None |  | ||||||
|             return (bitrate // 1000) if bitrate % 1000 == 0 else bitrate |  | ||||||
|  |  | ||||||
|         formats = [] |         formats = [] | ||||||
|         for source_id in source_ids: |         if self._ACCESS_ID: | ||||||
|             client_id = self._SALT[:2] + sha1(''.join([self._SALT, clip_id, self._TOKEN, server_id, client_location, source_id, self._SALT, self._CLIENT_NAME]).encode('utf-8')).hexdigest() |             raw_ct = self._ENCRYPTION_KEY + clip_id + self._IV + self._ACCESS_ID | ||||||
|             urls = self._download_json( |             server_token = (self._download_json( | ||||||
|                 'http://vas.sim-technik.de/vas/live/v2/videos/%s/sources/url' % clip_id, |                 self._V4_BASE_URL + 'protocols', clip_id, | ||||||
|                 clip_id, 'Downloading urls JSON', fatal=False, query={ |                 'Downloading protocols JSON', | ||||||
|  |                 headers=self.geo_verification_headers(), query={ | ||||||
|  |                     'access_id': self._ACCESS_ID, | ||||||
|  |                     'client_token': sha1((raw_ct).encode()).hexdigest(), | ||||||
|  |                     'video_id': clip_id, | ||||||
|  |                 }, fatal=False) or {}).get('server_token') | ||||||
|  |             if server_token: | ||||||
|  |                 urls = (self._download_json( | ||||||
|  |                     self._V4_BASE_URL + 'urls', clip_id, 'Downloading urls JSON', query={ | ||||||
|  |                         'access_id': self._ACCESS_ID, | ||||||
|  |                         'client_token': sha1((raw_ct + server_token + self._SUPPORTED_PROTOCOLS).encode()).hexdigest(), | ||||||
|  |                         'protocols': self._SUPPORTED_PROTOCOLS, | ||||||
|  |                         'server_token': server_token, | ||||||
|  |                         'video_id': clip_id, | ||||||
|  |                     }, fatal=False) or {}).get('urls') or {} | ||||||
|  |                 for protocol, variant in urls.items(): | ||||||
|  |                     source_url = variant.get('clear', {}).get('url') | ||||||
|  |                     if not source_url: | ||||||
|  |                         continue | ||||||
|  |                     if protocol == 'dash': | ||||||
|  |                         formats.extend(self._extract_mpd_formats( | ||||||
|  |                             source_url, clip_id, mpd_id=protocol, fatal=False)) | ||||||
|  |                     elif protocol == 'hls': | ||||||
|  |                         formats.extend(self._extract_m3u8_formats( | ||||||
|  |                             source_url, clip_id, 'mp4', 'm3u8_native', | ||||||
|  |                             m3u8_id=protocol, fatal=False)) | ||||||
|  |                     else: | ||||||
|  |                         formats.append({ | ||||||
|  |                             'url': source_url, | ||||||
|  |                             'format_id': protocol, | ||||||
|  |                         }) | ||||||
|  |         if not formats: | ||||||
|  |             source_ids = [compat_str(source['id']) for source in video['sources']] | ||||||
|  |  | ||||||
|  |             client_id = self._SALT[:2] + sha1(''.join([clip_id, self._SALT, self._TOKEN, client_location, self._SALT, self._CLIENT_NAME]).encode('utf-8')).hexdigest() | ||||||
|  |  | ||||||
|  |             sources = self._download_json( | ||||||
|  |                 'http://vas.sim-technik.de/vas/live/v2/videos/%s/sources' % clip_id, | ||||||
|  |                 clip_id, 'Downloading sources JSON', query={ | ||||||
|                     'access_token': self._TOKEN, |                     'access_token': self._TOKEN, | ||||||
|                     'client_id': client_id, |                     'client_id': client_id, | ||||||
|                     'client_location': client_location, |                     'client_location': client_location, | ||||||
|                     'client_name': self._CLIENT_NAME, |                     'client_name': self._CLIENT_NAME, | ||||||
|                     'server_id': server_id, |  | ||||||
|                     'source_ids': source_id, |  | ||||||
|                 }) |                 }) | ||||||
|             if not urls: |             server_id = sources['server_id'] | ||||||
|                 continue |  | ||||||
|             if urls.get('status_code') != 0: |             def fix_bitrate(bitrate): | ||||||
|                 raise ExtractorError('This video is unavailable', expected=True) |                 bitrate = int_or_none(bitrate) | ||||||
|             urls_sources = urls['sources'] |                 if not bitrate: | ||||||
|             if isinstance(urls_sources, dict): |                     return None | ||||||
|                 urls_sources = urls_sources.values() |                 return (bitrate // 1000) if bitrate % 1000 == 0 else bitrate | ||||||
|             for source in urls_sources: |  | ||||||
|                 source_url = source.get('url') |             for source_id in source_ids: | ||||||
|                 if not source_url: |                 client_id = self._SALT[:2] + sha1(''.join([self._SALT, clip_id, self._TOKEN, server_id, client_location, source_id, self._SALT, self._CLIENT_NAME]).encode('utf-8')).hexdigest() | ||||||
|  |                 urls = self._download_json( | ||||||
|  |                     'http://vas.sim-technik.de/vas/live/v2/videos/%s/sources/url' % clip_id, | ||||||
|  |                     clip_id, 'Downloading urls JSON', fatal=False, query={ | ||||||
|  |                         'access_token': self._TOKEN, | ||||||
|  |                         'client_id': client_id, | ||||||
|  |                         'client_location': client_location, | ||||||
|  |                         'client_name': self._CLIENT_NAME, | ||||||
|  |                         'server_id': server_id, | ||||||
|  |                         'source_ids': source_id, | ||||||
|  |                     }) | ||||||
|  |                 if not urls: | ||||||
|                     continue |                     continue | ||||||
|                 protocol = source.get('protocol') |                 if urls.get('status_code') != 0: | ||||||
|                 mimetype = source.get('mimetype') |                     raise ExtractorError('This video is unavailable', expected=True) | ||||||
|                 if mimetype == 'application/f4m+xml' or 'f4mgenerator' in source_url or determine_ext(source_url) == 'f4m': |                 urls_sources = urls['sources'] | ||||||
|                     formats.extend(self._extract_f4m_formats( |                 if isinstance(urls_sources, dict): | ||||||
|                         source_url, clip_id, f4m_id='hds', fatal=False)) |                     urls_sources = urls_sources.values() | ||||||
|                 elif mimetype == 'application/x-mpegURL': |                 for source in urls_sources: | ||||||
|                     formats.extend(self._extract_m3u8_formats( |                     source_url = source.get('url') | ||||||
|                         source_url, clip_id, 'mp4', 'm3u8_native', |                     if not source_url: | ||||||
|                         m3u8_id='hls', fatal=False)) |                         continue | ||||||
|                 elif mimetype == 'application/dash+xml': |                     protocol = source.get('protocol') | ||||||
|                     formats.extend(self._extract_mpd_formats( |                     mimetype = source.get('mimetype') | ||||||
|                         source_url, clip_id, mpd_id='dash', fatal=False)) |                     if mimetype == 'application/f4m+xml' or 'f4mgenerator' in source_url or determine_ext(source_url) == 'f4m': | ||||||
|                 else: |                         formats.extend(self._extract_f4m_formats( | ||||||
|                     tbr = fix_bitrate(source['bitrate']) |                             source_url, clip_id, f4m_id='hds', fatal=False)) | ||||||
|                     if protocol in ('rtmp', 'rtmpe'): |                     elif mimetype == 'application/x-mpegURL': | ||||||
|                         mobj = re.search(r'^(?P<url>rtmpe?://[^/]+)/(?P<path>.+)$', source_url) |                         formats.extend(self._extract_m3u8_formats( | ||||||
|                         if not mobj: |                             source_url, clip_id, 'mp4', 'm3u8_native', | ||||||
|                             continue |                             m3u8_id='hls', fatal=False)) | ||||||
|                         path = mobj.group('path') |                     elif mimetype == 'application/dash+xml': | ||||||
|                         mp4colon_index = path.rfind('mp4:') |                         formats.extend(self._extract_mpd_formats( | ||||||
|                         app = path[:mp4colon_index] |                             source_url, clip_id, mpd_id='dash', fatal=False)) | ||||||
|                         play_path = path[mp4colon_index:] |  | ||||||
|                         formats.append({ |  | ||||||
|                             'url': '%s/%s' % (mobj.group('url'), app), |  | ||||||
|                             'app': app, |  | ||||||
|                             'play_path': play_path, |  | ||||||
|                             'player_url': 'http://livepassdl.conviva.com/hf/ver/2.79.0.17083/LivePassModuleMain.swf', |  | ||||||
|                             'page_url': 'http://www.prosieben.de', |  | ||||||
|                             'tbr': tbr, |  | ||||||
|                             'ext': 'flv', |  | ||||||
|                             'format_id': 'rtmp%s' % ('-%d' % tbr if tbr else ''), |  | ||||||
|                         }) |  | ||||||
|                     else: |                     else: | ||||||
|                         formats.append({ |                         tbr = fix_bitrate(source['bitrate']) | ||||||
|                             'url': source_url, |                         if protocol in ('rtmp', 'rtmpe'): | ||||||
|                             'tbr': tbr, |                             mobj = re.search(r'^(?P<url>rtmpe?://[^/]+)/(?P<path>.+)$', source_url) | ||||||
|                             'format_id': 'http%s' % ('-%d' % tbr if tbr else ''), |                             if not mobj: | ||||||
|                         }) |                                 continue | ||||||
|  |                             path = mobj.group('path') | ||||||
|  |                             mp4colon_index = path.rfind('mp4:') | ||||||
|  |                             app = path[:mp4colon_index] | ||||||
|  |                             play_path = path[mp4colon_index:] | ||||||
|  |                             formats.append({ | ||||||
|  |                                 'url': '%s/%s' % (mobj.group('url'), app), | ||||||
|  |                                 'app': app, | ||||||
|  |                                 'play_path': play_path, | ||||||
|  |                                 'player_url': 'http://livepassdl.conviva.com/hf/ver/2.79.0.17083/LivePassModuleMain.swf', | ||||||
|  |                                 'page_url': 'http://www.prosieben.de', | ||||||
|  |                                 'tbr': tbr, | ||||||
|  |                                 'ext': 'flv', | ||||||
|  |                                 'format_id': 'rtmp%s' % ('-%d' % tbr if tbr else ''), | ||||||
|  |                             }) | ||||||
|  |                         else: | ||||||
|  |                             formats.append({ | ||||||
|  |                                 'url': source_url, | ||||||
|  |                                 'tbr': tbr, | ||||||
|  |                                 'format_id': 'http%s' % ('-%d' % tbr if tbr else ''), | ||||||
|  |                             }) | ||||||
|         self._sort_formats(formats) |         self._sort_formats(formats) | ||||||
|  |  | ||||||
|         return { |         return { | ||||||
|             'duration': duration, |             'duration': float_or_none(video.get('duration')), | ||||||
|             'formats': formats, |             'formats': formats, | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -344,6 +384,11 @@ class ProSiebenSat1IE(ProSiebenSat1BaseIE): | |||||||
|     _TOKEN = 'prosieben' |     _TOKEN = 'prosieben' | ||||||
|     _SALT = '01!8d8F_)r9]4s[qeuXfP%' |     _SALT = '01!8d8F_)r9]4s[qeuXfP%' | ||||||
|     _CLIENT_NAME = 'kolibri-2.0.19-splec4' |     _CLIENT_NAME = 'kolibri-2.0.19-splec4' | ||||||
|  |  | ||||||
|  |     _ACCESS_ID = 'x_prosiebenmaxx-de' | ||||||
|  |     _ENCRYPTION_KEY = 'Eeyeey9oquahthainoofashoyoikosag' | ||||||
|  |     _IV = 'Aeluchoc6aevechuipiexeeboowedaok' | ||||||
|  |  | ||||||
|     _CLIPID_REGEXES = [ |     _CLIPID_REGEXES = [ | ||||||
|         r'"clip_id"\s*:\s+"(\d+)"', |         r'"clip_id"\s*:\s+"(\d+)"', | ||||||
|         r'clipid: "(\d+)"', |         r'clipid: "(\d+)"', | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Remita Amine
					Remita Amine