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:
parent
d596824c2f
commit
de271a06fd
@ -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)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user