fix(videos): base convert % on elapsed/duration not file size

File size ratio was wrong since output bitrate != input bitrate.
Now uses ffprobe to get video duration, then elapsed/duration for %.

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Mathieu Moran
2026-08-10 01:50:49 -04:00
co-authored by Copilot
parent 1fde8732c2
commit 414fb78543
+19 -13
View File
@@ -36,12 +36,25 @@ def queue_convert(relative_path, force=False):
with _converting_lock:
if relative_path in _converting:
return False
_converting[relative_path] = {"started_at": time.time(), "source_size": 0, "tmp_path": ""}
_converting[relative_path] = {"started_at": time.time(), "duration_s": 0, "tmp_path": ""}
t = threading.Thread(target=_convert_bg, args=(relative_path,), daemon=True)
t.start()
return True
def _get_duration_s(path):
"""Return video duration in seconds via ffprobe, or None on failure."""
try:
result = subprocess.run(
["ffprobe", "-v", "error", "-show_entries", "format=duration",
"-of", "default=noprint_wrappers=1:nokey=1", path],
capture_output=True, text=True, timeout=10,
)
return float(result.stdout.strip())
except Exception:
return None
def _convert_bg(relative_path):
try:
source_path = _local_path(relative_path)
@@ -53,10 +66,10 @@ def _convert_bg(relative_path):
try:
tmp_path = mp4_path + ".converting.mp4"
source_size = os.path.getsize(source_path) if os.path.exists(source_path) else 0
duration_s = _get_duration_s(source_path) or 0
with _converting_lock:
if relative_path in _converting:
_converting[relative_path]["source_size"] = source_size
_converting[relative_path]["duration_s"] = duration_s
_converting[relative_path]["tmp_path"] = tmp_path
cmd = [
"ffmpeg", "-nostdin", "-loglevel", "error", "-y",
@@ -138,18 +151,11 @@ def list_local_videos():
convert_progress = None
if converting and conv_info:
elapsed = time.time() - conv_info["started_at"]
source_size = conv_info["source_size"]
tmp_path = conv_info["tmp_path"]
tmp_size = 0
if tmp_path and os.path.exists(tmp_path):
try:
tmp_size = os.path.getsize(tmp_path)
except OSError:
pass
pct = round(tmp_size / source_size * 100) if source_size > 0 else 0
duration_s = conv_info.get("duration_s", 0)
pct = min(round(elapsed / duration_s * 100), 99) if duration_s > 0 else 0
convert_progress = {
"elapsed_s": int(elapsed),
"pct": min(pct, 99), # never show 100% until done
"pct": pct,
}
files.append(
{