mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 06:35:12 +00:00 
			
		
		
		
	[ie/twitcasting] Fix livestream extraction (#12977)
Closes #12966 Authored by: bashonly
This commit is contained in:
		| @@ -14,12 +14,13 @@ from ..utils import ( | ||||
|     parse_duration, | ||||
|     qualities, | ||||
|     str_to_int, | ||||
|     traverse_obj, | ||||
|     try_get, | ||||
|     unified_timestamp, | ||||
|     url_or_none, | ||||
|     urlencode_postdata, | ||||
|     urljoin, | ||||
| ) | ||||
| from ..utils.traversal import traverse_obj | ||||
| 
 | ||||
| 
 | ||||
| class TwitCastingIE(InfoExtractor): | ||||
| @@ -138,13 +139,7 @@ class TwitCastingIE(InfoExtractor): | ||||
|             r'data-toggle="true"[^>]+datetime="([^"]+)"', | ||||
|             webpage, 'datetime', None)) | ||||
| 
 | ||||
|         stream_server_data = self._download_json( | ||||
|             f'https://twitcasting.tv/streamserver.php?target={uploader_id}&mode=client', video_id, | ||||
|             'Downloading live info', fatal=False) | ||||
| 
 | ||||
|         is_live = any(f'data-{x}' in webpage for x in ['is-onlive="true"', 'live-type="live"', 'status="online"']) | ||||
|         if not traverse_obj(stream_server_data, 'llfmp4') and is_live: | ||||
|             self.raise_login_required(method='cookies') | ||||
| 
 | ||||
|         base_dict = { | ||||
|             'title': title, | ||||
| @@ -165,28 +160,37 @@ class TwitCastingIE(InfoExtractor): | ||||
|                 return [data_movie_url] | ||||
| 
 | ||||
|         m3u8_urls = (try_get(webpage, find_dmu, list) | ||||
|                      or traverse_obj(video_js_data, (..., 'source', 'url')) | ||||
|                      or ([f'https://twitcasting.tv/{uploader_id}/metastream.m3u8'] if is_live else None)) | ||||
|         if not m3u8_urls: | ||||
|             raise ExtractorError('Failed to get m3u8 playlist') | ||||
|                      or traverse_obj(video_js_data, (..., 'source', 'url'))) | ||||
| 
 | ||||
|         if is_live: | ||||
|             m3u8_url = m3u8_urls[0] | ||||
|             formats = self._extract_m3u8_formats( | ||||
|                 m3u8_url, video_id, ext='mp4', m3u8_id='hls', | ||||
|                 live=True, headers=self._M3U8_HEADERS) | ||||
|             stream_data = self._download_json( | ||||
|                 'https://twitcasting.tv/streamserver.php', | ||||
|                 video_id, 'Downloading live info', query={ | ||||
|                     'target': uploader_id, | ||||
|                     'mode': 'client', | ||||
|                     'player': 'pc_web', | ||||
|                 }) | ||||
| 
 | ||||
|             if traverse_obj(stream_server_data, ('hls', 'source')): | ||||
|                 formats.extend(self._extract_m3u8_formats( | ||||
|                     m3u8_url, video_id, ext='mp4', m3u8_id='source', | ||||
|                     live=True, query={'mode': 'source'}, | ||||
|                     note='Downloading source quality m3u8', | ||||
|                     headers=self._M3U8_HEADERS, fatal=False)) | ||||
|             formats = [] | ||||
|             # low: 640x360, medium: 1280x720, high: 1920x1080 | ||||
|             qq = qualities(['low', 'medium', 'high']) | ||||
|             for quality, m3u8_url in traverse_obj(stream_data, ( | ||||
|                 'tc-hls', 'streams', {dict.items}, lambda _, v: url_or_none(v[1]), | ||||
|             )): | ||||
|                 formats.append({ | ||||
|                     'url': m3u8_url, | ||||
|                     'format_id': f'hls-{quality}', | ||||
|                     'ext': 'mp4', | ||||
|                     'quality': qq(quality), | ||||
|                     'protocol': 'm3u8', | ||||
|                     'http_headers': self._M3U8_HEADERS, | ||||
|                 }) | ||||
| 
 | ||||
|             if websockets: | ||||
|                 qq = qualities(['base', 'mobilesource', 'main']) | ||||
|                 streams = traverse_obj(stream_server_data, ('llfmp4', 'streams')) or {} | ||||
|                 for mode, ws_url in streams.items(): | ||||
|                 for mode, ws_url in traverse_obj(stream_data, ( | ||||
|                     'llfmp4', 'streams', {dict.items}, lambda _, v: url_or_none(v[1]), | ||||
|                 )): | ||||
|                     formats.append({ | ||||
|                         'url': ws_url, | ||||
|                         'format_id': f'ws-{mode}', | ||||
| @@ -197,10 +201,15 @@ class TwitCastingIE(InfoExtractor): | ||||
|                         'protocol': 'websocket_frag', | ||||
|                     }) | ||||
| 
 | ||||
|             if not formats: | ||||
|                 self.raise_login_required() | ||||
| 
 | ||||
|             infodict = { | ||||
|                 'formats': formats, | ||||
|                 '_format_sort_fields': ('source', ), | ||||
|             } | ||||
|         elif not m3u8_urls: | ||||
|             raise ExtractorError('Failed to get m3u8 playlist') | ||||
|         elif len(m3u8_urls) == 1: | ||||
|             formats = self._extract_m3u8_formats( | ||||
|                 m3u8_urls[0], video_id, 'mp4', headers=self._M3U8_HEADERS) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bashonly
					bashonly