Skip to content

Commit

Permalink
fix live stream buffered range auto alignment
Browse files Browse the repository at this point in the history
  • Loading branch information
coletdjnz committed Nov 8, 2024
1 parent 35928e5 commit 828e3e6
Showing 1 changed file with 17 additions and 5 deletions.
22 changes: 17 additions & 5 deletions yt_dlp_plugins/extractor/_ytse/downloader/sabr.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def __init__(self, fd, server_abr_streaming_url: str, video_playback_ustreamer_c

self.sabr_seeked = False
self.live_segment_target_duration_sec = live_segment_target_duration_sec
self._request_had_data = False

def download(self):
video_formats = [format for format in self.requestedFormats if format.format_type == FormatType.VIDEO]
Expand All @@ -110,6 +111,8 @@ def download(self):
media_type=media_type,
)

requests_no_data = 0

request_number = 0
while self.live_metadata or not self.total_duration_ms or self.client_abr_state.start_time_ms < self.total_duration_ms:
po_token = self.po_token_fn()
Expand Down Expand Up @@ -151,10 +154,19 @@ def download(self):
self.fd.report_warning('Extraneous header IDs left')
self.header_ids.clear()

if not self._request_had_data:
if requests_no_data >= 2:
if self.client_abr_state.start_time_ms < self.total_duration_ms:
raise DownloadError('No data found in three consecutive requests')
break # stream finished?
requests_no_data += 1

current_buffered_ranges = [initialized_format.buffered_ranges[-1] for initialized_format in self.initialized_formats.values() if initialized_format.buffered_ranges]

# choose format that is the most behind
min_buffered_duration_ms = min(current_buffered_ranges, key=lambda x: x.duration_ms).duration_ms if current_buffered_ranges else 0
lowest_buffered_range = min(current_buffered_ranges, key=lambda x: x.start_time_ms + x.duration_ms) if current_buffered_ranges else None

min_buffered_duration_ms = lowest_buffered_range.start_time_ms + lowest_buffered_range.duration_ms if lowest_buffered_range else 0

next_request_backoff_ms = (self.next_request_policy and self.next_request_policy.backoff_time_ms) or 0

Expand All @@ -172,6 +184,7 @@ def download(self):

self.next_request_policy = None
self.sabr_seeked = False
self._request_had_data = False

request_number += 1

Expand Down Expand Up @@ -301,10 +314,8 @@ def process_media_header(self, part: UMPPart):
# The server seems to care more about the segment index than the duration.
if current_buffered_range.start_time_ms > start_ms:
raise DownloadError(f'Buffered range start time mismatch: {current_buffered_range.start_time_ms} > {start_ms}')
current_buffered_range.duration_ms = current_buffered_range.time_range.duration = start_ms + duration_ms

if not current_buffered_range.duration_ms - duration_ms == start_ms:
raise DownloadError(f'Buffered range duration mismatch: {current_buffered_range.duration_ms - duration_ms} != {start_ms}')
new_duration = (start_ms - current_buffered_range.start_time_ms) + duration_ms
current_buffered_range.duration_ms = current_buffered_range.time_range.duration = new_duration

def process_media(self, part: UMPPart):
header_id = part.data[0]
Expand All @@ -323,6 +334,7 @@ def process_media(self, part: UMPPart):
# todo: improve write callback
write_callback = initialized_format.requested_format.write_callback
write_callback(part.data[1:], SABRStatus(fragment_index=current_sequence.sequence_number, fragment_count=self.live_metadata and self.live_metadata.latest_sequence_number))
self._request_had_data = True

def process_media_end(self, part: UMPPart):
header_id = part.data[0]
Expand Down

0 comments on commit 828e3e6

Please # to comment.