mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-30 22:25:19 +00:00 
			
		
		
		
	[ie/digitalconcerthall] Extract HEVC and FLAC formats (#10470)
Authored by: bashonly
This commit is contained in:
		| @@ -1,6 +1,8 @@ | ||||
| from .common import InfoExtractor | ||||
| from ..networking.exceptions import HTTPError | ||||
| from ..utils import ( | ||||
|     ExtractorError, | ||||
|     parse_codecs, | ||||
|     try_get, | ||||
|     url_or_none, | ||||
|     urlencode_postdata, | ||||
| @@ -12,6 +14,7 @@ class DigitalConcertHallIE(InfoExtractor): | ||||
|     IE_DESC = 'DigitalConcertHall extractor' | ||||
|     _VALID_URL = r'https?://(?:www\.)?digitalconcerthall\.com/(?P<language>[a-z]+)/(?P<type>film|concert|work)/(?P<id>[0-9]+)-?(?P<part>[0-9]+)?' | ||||
|     _OAUTH_URL = 'https://api.digitalconcerthall.com/v2/oauth2/token' | ||||
|     _USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.5 Safari/605.1.15' | ||||
|     _ACCESS_TOKEN = None | ||||
|     _NETRC_MACHINE = 'digitalconcerthall' | ||||
|     _TESTS = [{ | ||||
| @@ -68,33 +71,42 @@ class DigitalConcertHallIE(InfoExtractor): | ||||
|     }] | ||||
| 
 | ||||
|     def _perform_login(self, username, password): | ||||
|         token_response = self._download_json( | ||||
|         login_token = self._download_json( | ||||
|             self._OAUTH_URL, | ||||
|             None, 'Obtaining token', errnote='Unable to obtain token', data=urlencode_postdata({ | ||||
|                 'affiliate': 'none', | ||||
|                 'grant_type': 'device', | ||||
|                 'device_vendor': 'unknown', | ||||
|                 # device_model 'Safari' gets split streams of 4K/HEVC video and lossless/FLAC audio | ||||
|                 'device_model': 'unknown' if self._configuration_arg('prefer_combined_hls') else 'Safari', | ||||
|                 'app_id': 'dch.webapp', | ||||
|                 'app_version': '1.0.0', | ||||
|                 'app_distributor': 'berlinphil', | ||||
|                 'app_version': '1.84.0', | ||||
|                 'client_secret': '2ySLN+2Fwb', | ||||
|             }), headers={ | ||||
|                 'Content-Type': 'application/x-www-form-urlencoded', | ||||
|             }) | ||||
|         self._ACCESS_TOKEN = token_response['access_token'] | ||||
|                 'Accept': 'application/json', | ||||
|                 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', | ||||
|                 'User-Agent': self._USER_AGENT, | ||||
|             })['access_token'] | ||||
|         try: | ||||
|             self._download_json( | ||||
|             login_response = self._download_json( | ||||
|                 self._OAUTH_URL, | ||||
|                 None, note='Logging in', errnote='Unable to login', data=urlencode_postdata({ | ||||
|                     'grant_type': 'password', | ||||
|                     'username': username, | ||||
|                     'password': password, | ||||
|                 }), headers={ | ||||
|                     'Content-Type': 'application/x-www-form-urlencoded', | ||||
|                     'Accept': 'application/json', | ||||
|                     'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', | ||||
|                     'Referer': 'https://www.digitalconcerthall.com', | ||||
|                     'Authorization': f'Bearer {self._ACCESS_TOKEN}', | ||||
|                     'Authorization': f'Bearer {login_token}', | ||||
|                     'User-Agent': self._USER_AGENT, | ||||
|                 }) | ||||
|         except ExtractorError: | ||||
|             self.raise_login_required(msg='Login info incorrect') | ||||
|         except ExtractorError as error: | ||||
|             if isinstance(error.cause, HTTPError) and error.cause.status == 401: | ||||
|                 raise ExtractorError('Invalid username or password', expected=True) | ||||
|             raise | ||||
|         self._ACCESS_TOKEN = login_response['access_token'] | ||||
| 
 | ||||
|     def _real_initialize(self): | ||||
|         if not self._ACCESS_TOKEN: | ||||
| @@ -108,11 +120,15 @@ class DigitalConcertHallIE(InfoExtractor): | ||||
|                     'Accept': 'application/json', | ||||
|                     'Authorization': f'Bearer {self._ACCESS_TOKEN}', | ||||
|                     'Accept-Language': language, | ||||
|                     'User-Agent': self._USER_AGENT, | ||||
|                 }) | ||||
| 
 | ||||
|             formats = [] | ||||
|             for m3u8_url in traverse_obj(stream_info, ('channel', ..., 'stream', ..., 'url', {url_or_none})): | ||||
|                 formats.extend(self._extract_m3u8_formats(m3u8_url, video_id, 'mp4', fatal=False)) | ||||
|                 formats.extend(self._extract_m3u8_formats(m3u8_url, video_id, 'mp4', m3u8_id='hls', fatal=False)) | ||||
|             for fmt in formats: | ||||
|                 if fmt.get('format_note') and fmt.get('vcodec') == 'none': | ||||
|                     fmt.update(parse_codecs(fmt['format_note'])) | ||||
| 
 | ||||
|             yield { | ||||
|                 'id': video_id, | ||||
| @@ -140,13 +156,15 @@ class DigitalConcertHallIE(InfoExtractor): | ||||
|             f'https://api.digitalconcerthall.com/v2/{api_type}/{video_id}', video_id, headers={ | ||||
|                 'Accept': 'application/json', | ||||
|                 'Accept-Language': language, | ||||
|                 'User-Agent': self._USER_AGENT, | ||||
|                 'Authorization': f'Bearer {self._ACCESS_TOKEN}', | ||||
|             }) | ||||
|         album_artists = traverse_obj(vid_info, ('_links', 'artist', ..., 'name')) | ||||
|         videos = [vid_info] if type_ == 'film' else traverse_obj(vid_info, ('_embedded', ..., ...)) | ||||
| 
 | ||||
|         if type_ == 'work': | ||||
|             videos = [videos[int(part) - 1]] | ||||
| 
 | ||||
|         album_artists = traverse_obj(vid_info, ('_links', 'artist', ..., 'name', {str})) | ||||
|         thumbnail = traverse_obj(vid_info, ( | ||||
|             'image', ..., {self._proto_relative_url}, {url_or_none}, | ||||
|             {lambda x: x.format(width=0, height=0)}, any))  # NB: 0x0 is the original size | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bashonly
					bashonly