1
0
mirror of https://github.com/yt-dlp/yt-dlp.git synced 2025-05-07 22:39:45 +00:00

[ie/twitcasting] Fix livestream extraction (#12977)

Closes #12966
Authored by: bashonly
This commit is contained in:
bashonly 2025-04-22 18:54:41 -05:00 committed by GitHub
parent d596824c2f
commit de271a06fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -14,12 +14,13 @@ from ..utils import (
parse_duration, parse_duration,
qualities, qualities,
str_to_int, str_to_int,
traverse_obj,
try_get, try_get,
unified_timestamp, unified_timestamp,
url_or_none,
urlencode_postdata, urlencode_postdata,
urljoin, urljoin,
) )
from ..utils.traversal import traverse_obj
class TwitCastingIE(InfoExtractor): class TwitCastingIE(InfoExtractor):
@ -138,13 +139,7 @@ class TwitCastingIE(InfoExtractor):
r'data-toggle="true"[^>]+datetime="([^"]+)"', r'data-toggle="true"[^>]+datetime="([^"]+)"',
webpage, 'datetime', None)) 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"']) 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 = { base_dict = {
'title': title, 'title': title,
@ -165,28 +160,37 @@ class TwitCastingIE(InfoExtractor):
return [data_movie_url] return [data_movie_url]
m3u8_urls = (try_get(webpage, find_dmu, list) m3u8_urls = (try_get(webpage, find_dmu, list)
or traverse_obj(video_js_data, (..., 'source', 'url')) 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')
if is_live: if is_live:
m3u8_url = m3u8_urls[0] stream_data = self._download_json(
formats = self._extract_m3u8_formats( 'https://twitcasting.tv/streamserver.php',
m3u8_url, video_id, ext='mp4', m3u8_id='hls', video_id, 'Downloading live info', query={
live=True, headers=self._M3U8_HEADERS) 'target': uploader_id,
'mode': 'client',
'player': 'pc_web',
})
if traverse_obj(stream_server_data, ('hls', 'source')): formats = []
formats.extend(self._extract_m3u8_formats( # low: 640x360, medium: 1280x720, high: 1920x1080
m3u8_url, video_id, ext='mp4', m3u8_id='source', qq = qualities(['low', 'medium', 'high'])
live=True, query={'mode': 'source'}, for quality, m3u8_url in traverse_obj(stream_data, (
note='Downloading source quality m3u8', 'tc-hls', 'streams', {dict.items}, lambda _, v: url_or_none(v[1]),
headers=self._M3U8_HEADERS, fatal=False)) )):
formats.append({
'url': m3u8_url,
'format_id': f'hls-{quality}',
'ext': 'mp4',
'quality': qq(quality),
'protocol': 'm3u8',
'http_headers': self._M3U8_HEADERS,
})
if websockets: if websockets:
qq = qualities(['base', 'mobilesource', 'main']) qq = qualities(['base', 'mobilesource', 'main'])
streams = traverse_obj(stream_server_data, ('llfmp4', 'streams')) or {} for mode, ws_url in traverse_obj(stream_data, (
for mode, ws_url in streams.items(): 'llfmp4', 'streams', {dict.items}, lambda _, v: url_or_none(v[1]),
)):
formats.append({ formats.append({
'url': ws_url, 'url': ws_url,
'format_id': f'ws-{mode}', 'format_id': f'ws-{mode}',
@ -197,10 +201,15 @@ class TwitCastingIE(InfoExtractor):
'protocol': 'websocket_frag', 'protocol': 'websocket_frag',
}) })
if not formats:
self.raise_login_required()
infodict = { infodict = {
'formats': formats, 'formats': formats,
'_format_sort_fields': ('source', ), '_format_sort_fields': ('source', ),
} }
elif not m3u8_urls:
raise ExtractorError('Failed to get m3u8 playlist')
elif len(m3u8_urls) == 1: elif len(m3u8_urls) == 1:
formats = self._extract_m3u8_formats( formats = self._extract_m3u8_formats(
m3u8_urls[0], video_id, 'mp4', headers=self._M3U8_HEADERS) m3u8_urls[0], video_id, 'mp4', headers=self._M3U8_HEADERS)