This commit is contained in:
2026-01-16 19:39:45 -08:00
parent 9dce32cbe3
commit 385307c5b9
5 changed files with 47 additions and 12 deletions

View File

@@ -716,6 +716,10 @@ class YtDlpTool:
# Progress + utility helpers for yt-dlp driven downloads (previously in cmdlet/download_media).
_YTDLP_PROGRESS_BAR = ProgressBar()
_YTDLP_TRANSFER_STATE: Dict[str, Dict[str, Any]] = {}
_YTDLP_PROGRESS_ACTIVITY_LOCK = threading.Lock()
_YTDLP_PROGRESS_LAST_ACTIVITY = 0.0
_YTDLP_PROGRESS_ACTIVITY_LOCK = threading.Lock()
_YTDLP_PROGRESS_LAST_ACTIVITY = 0.0
_SUBTITLE_EXTS = (".vtt", ".srt", ".ass", ".ssa", ".lrc")
@@ -744,6 +748,21 @@ def _progress_label(status: Dict[str, Any]) -> str:
return "download"
def _record_progress_activity(timestamp: Optional[float] = None) -> None:
global _YTDLP_PROGRESS_LAST_ACTIVITY
with _YTDLP_PROGRESS_ACTIVITY_LOCK:
_YTDLP_PROGRESS_LAST_ACTIVITY = timestamp if timestamp is not None else time.monotonic()
def _get_last_progress_activity() -> float:
with _YTDLP_PROGRESS_ACTIVITY_LOCK:
return _YTDLP_PROGRESS_LAST_ACTIVITY
def _clear_progress_activity() -> None:
_record_progress_activity(0.0)
def _live_ui_and_pipe_index() -> tuple[Optional[Any], int]:
ui = None
try:
@@ -1117,6 +1136,8 @@ def _progress_callback(status: Dict[str, Any]) -> None:
event = status.get("status")
downloaded = status.get("downloaded_bytes")
total = status.get("total_bytes") or status.get("total_bytes_estimate")
if event == "downloading":
_record_progress_activity()
pipeline = PipelineProgress(pipeline_context)
live_ui, _ = pipeline.ui_and_pipe_index()
@@ -1517,10 +1538,20 @@ def _download_with_timeout(opts: DownloadOptions, timeout_seconds: int = 300) ->
thread = threading.Thread(target=_do_download, daemon=False)
thread.start()
thread.join(timeout=timeout_seconds)
if thread.is_alive():
raise DownloadError(f"Download timeout after {timeout_seconds} seconds for {opts.url}")
start_time = time.monotonic()
_record_progress_activity(start_time)
try:
while thread.is_alive():
thread.join(1)
if not thread.is_alive():
break
last_activity = _get_last_progress_activity()
if last_activity <= 0:
last_activity = start_time
if time.monotonic() - last_activity > timeout_seconds:
raise DownloadError(f"Download timeout after {timeout_seconds} seconds for {opts.url}")
finally:
_clear_progress_activity()
if result_container[1] is not None:
raise cast(Exception, result_container[1])