fix: DASH multi-phase progress + HLS fragment progress + indeterminate animation

This commit is contained in:
mini
2026-02-19 00:51:15 +08:00
parent deae827252
commit d419158c80
3 changed files with 39 additions and 9 deletions

View File

@@ -39,17 +39,38 @@ def cleanup_task(task_id: str):
def _make_hook(task_id: str):
"""yt-dlp progress hook with real-time tracking and cancel support."""
"""yt-dlp progress hook: handles DASH multi-phase + HLS fragments + cancel."""
state = {"phase": 0} # counts "finished" events (video phase, audio phase…)
PHASE_WEIGHTS = [0.80, 0.19] # phase-0 → 0-80%, phase-1 → 80-99%
def hook(d):
flag = _cancel_flags.get(task_id)
if flag and flag.is_set():
raise yt_dlp.utils.DownloadCancelled("Cancelled by user")
if d["status"] == "downloading":
total = d.get("total_bytes") or d.get("total_bytes_estimate") or 0
done = d.get("downloaded_bytes", 0)
_download_progress[task_id] = int(done * 100 / total) if total else 0
done = d.get("downloaded_bytes", 0)
if total > 0:
phase_pct = done / total # 0.01.0
else:
# HLS / unknown size: use fragment index
fc = d.get("fragment_count") or 0
fi = d.get("fragment_index") or 0
phase_pct = (fi / fc) if fc > 0 else 0.5 # 0.5 = "working"
ph = min(state["phase"], len(PHASE_WEIGHTS) - 1)
base = sum(PHASE_WEIGHTS[:ph]) * 100
span = PHASE_WEIGHTS[ph] * 100
pct = int(base + phase_pct * span)
_download_progress[task_id] = max(1, pct) # at least 1 to show activity
elif d["status"] == "finished":
_download_progress[task_id] = 99 # merging, not 100 yet
state["phase"] += 1
done_pct = int(sum(PHASE_WEIGHTS[:state["phase"]]) * 100)
_download_progress[task_id] = min(done_pct, 99)
return hook
VIDEO_BASE_PATH = os.getenv("VIDEO_BASE_PATH", "/home/xdl/xdl_videos")