mirror of
https://github.com/yt-dlp/yt-dlp.git
synced 2024-11-28 18:21:26 +01:00
Compare commits
2 Commits
ca4bd6746a
...
b6668a4ea0
Author | SHA1 | Date | |
---|---|---|---|
|
b6668a4ea0 | ||
|
e474be6b38 |
|
@ -4,8 +4,12 @@ from ..utils import (
|
||||||
clean_html,
|
clean_html,
|
||||||
get_element_by_id,
|
get_element_by_id,
|
||||||
urljoin,
|
urljoin,
|
||||||
|
js_to_json,
|
||||||
|
traverse_obj,
|
||||||
|
int_or_none,
|
||||||
|
url_or_none,
|
||||||
)
|
)
|
||||||
from ..compat import compat_parse_qs
|
from urllib.parse import parse_qs
|
||||||
|
|
||||||
|
|
||||||
class KukuluLiveIE(InfoExtractor):
|
class KukuluLiveIE(InfoExtractor):
|
||||||
|
@ -26,39 +30,32 @@ class KukuluLiveIE(InfoExtractor):
|
||||||
},
|
},
|
||||||
note=f'Downloading {description} quality metadata',
|
note=f'Downloading {description} quality metadata',
|
||||||
errnote=f'Unable to download {description} quality metadata')
|
errnote=f'Unable to download {description} quality metadata')
|
||||||
return compat_parse_qs(qs)
|
return parse_qs(qs)
|
||||||
|
|
||||||
def _add_quality_formats(self, formats, quality_meta):
|
def _add_quality_formats(self, formats, quality_meta):
|
||||||
vcodec = quality_meta.get('vcodec')[0]
|
vcodec = traverse_obj(quality_meta, ('vcodec', 0))
|
||||||
quality = quality_meta.get('now_quality')[0]
|
quality = traverse_obj(quality_meta, ('now_quality', 0))
|
||||||
quality_priority = {
|
quality_priority = {
|
||||||
'high': 3,
|
'high': 3,
|
||||||
'h264': 2,
|
'h264': 2,
|
||||||
'low': 1,
|
'low': 1,
|
||||||
}
|
}.get(quality, 0)
|
||||||
formats.extend([
|
if traverse_obj(quality_meta, ('hlsaddr', 0, {url_or_none})):
|
||||||
{
|
formats.append({
|
||||||
'format_id': quality,
|
'format_id': quality,
|
||||||
'url': quality_meta.get('hlsaddr')[0],
|
'url': quality_meta['hlsaddr'][0],
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'vcodec': vcodec,
|
'vcodec': vcodec,
|
||||||
'quality': quality_priority[quality],
|
'quality': quality_priority,
|
||||||
},
|
})
|
||||||
{
|
if traverse_obj(quality_meta, ('hlsaddr_audioonly', 0, {url_or_none})):
|
||||||
'format_id': f'{quality}-rtmp',
|
formats.append({
|
||||||
'url': quality_meta.get('streamaddr')[0],
|
|
||||||
'ext': 'mp4',
|
|
||||||
'vcodec': vcodec,
|
|
||||||
'quality': quality_priority[quality] - 5,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
'format_id': f'{quality}-audioonly',
|
'format_id': f'{quality}-audioonly',
|
||||||
'url': quality_meta.get('hlsaddr_audioonly')[0],
|
'url': quality_meta['hlsaddr_audioonly'][0],
|
||||||
'ext': 'aac',
|
'ext': 'm4a',
|
||||||
'vcodec': 'none',
|
'vcodec': 'none',
|
||||||
'quality': quality_priority[quality] - 10,
|
'quality': quality_priority,
|
||||||
},
|
})
|
||||||
])
|
|
||||||
|
|
||||||
def _real_extract(self, url):
|
def _real_extract(self, url):
|
||||||
video_id = self._match_id(url)
|
video_id = self._match_id(url)
|
||||||
|
@ -100,26 +97,38 @@ class KukuluLiveIE(InfoExtractor):
|
||||||
note='Downloading player html',
|
note='Downloading player html',
|
||||||
errnote='Unable to download player html')
|
errnote='Unable to download player html')
|
||||||
|
|
||||||
# https://regex101.com/r/3AXpSA/3
|
sources_json = self._search_json(
|
||||||
sources = self._search_regex(r'var fplayer_source = ([^;]+)', player_html, 'sources')
|
r'var\s+fplayer_source\s*=', player_html, 'stream data', video_id,
|
||||||
sources_json = self._parse_json(sources.replace('.mp4",', '.mp4"'), video_id)
|
contains_pattern=r'\[(?s:.+)\]', transform_source=js_to_json)
|
||||||
|
|
||||||
formats = []
|
def _parse_segment(segment, id, title):
|
||||||
for source in sources_json:
|
path = segment.get('file')
|
||||||
path = source.get('file')
|
if not path:
|
||||||
formats.append({
|
return None
|
||||||
|
formats = [{
|
||||||
'url': urljoin('https://live.erinn.biz', path),
|
'url': urljoin('https://live.erinn.biz', path),
|
||||||
'ext': 'mp4',
|
'ext': 'mp4',
|
||||||
'protocol': 'm3u8_native',
|
'protocol': 'm3u8_native',
|
||||||
})
|
}]
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'title': title,
|
||||||
|
'description': description,
|
||||||
|
'timestamp': traverse_obj(segment, ('time_start', {int_or_none})),
|
||||||
|
'thumbnail': thumbnail,
|
||||||
|
'formats': formats,
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
is_playlist = len(sources_json) > 1
|
||||||
'id': video_id,
|
if is_playlist:
|
||||||
'title': title,
|
entries = []
|
||||||
'description': description,
|
for i, segment in enumerate(sources_json):
|
||||||
'timestamp': sources_json[0].get('time_start'),
|
entry = _parse_segment(segment, f'{video_id}_{i}', f'{title} (Part {i + 1})')
|
||||||
'thumbnail': thumbnail,
|
if not entry:
|
||||||
'formats': formats,
|
continue
|
||||||
}
|
entries.append(entry)
|
||||||
|
return self.playlist_result(entries, video_id, title, description, multi_video=True)
|
||||||
|
else:
|
||||||
|
return _parse_segment(sources_json[0], video_id, title)
|
||||||
|
|
||||||
raise ExtractorError('Cannot parse live stream or VOD', expected=True)
|
raise ExtractorError('Could not detect media type')
|
||||||
|
|
Loading…
Reference in New Issue
Block a user