fix(videos): real ffmpeg progress via -progress pipe, exclude .converting.mp4
- ffmpeg -progress pipe:1 streams out_time_ms lines; we parse them in the reading loop so % = out_time_s / duration_s (actual encode position) - find_video_files() skips *.converting.mp4 temp files so they are never listed, uploaded, or shown in the UI Co-authored-by: Copilot <[email protected]>
This commit is contained in:
+19
-4
@@ -71,19 +71,33 @@ def _convert_bg(relative_path):
|
||||
if relative_path in _converting:
|
||||
_converting[relative_path]["duration_s"] = duration_s
|
||||
_converting[relative_path]["tmp_path"] = tmp_path
|
||||
_converting[relative_path]["out_time_s"] = 0.0
|
||||
cmd = [
|
||||
"ffmpeg", "-nostdin", "-loglevel", "error", "-y",
|
||||
"-i", source_path,
|
||||
"-c:v", "h264_v4l2m2m",
|
||||
"-b:v", "4M", # 4 Mbps — good quality, ~100MB per 3-min clip
|
||||
"-b:v", "4M",
|
||||
"-c:a", "aac",
|
||||
"-b:a", "128k",
|
||||
"-movflags", "faststart",
|
||||
"-f", "mp4",
|
||||
"-progress", "pipe:1",
|
||||
tmp_path,
|
||||
]
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
proc.wait() # real thread — blocking wait is fine
|
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,
|
||||
text=True, bufsize=1)
|
||||
# Read progress lines from stdout
|
||||
for line in proc.stdout:
|
||||
line = line.strip()
|
||||
if line.startswith("out_time_ms="):
|
||||
try:
|
||||
ms = int(line.split("=", 1)[1])
|
||||
with _converting_lock:
|
||||
if relative_path in _converting:
|
||||
_converting[relative_path]["out_time_s"] = ms / 1_000_000.0
|
||||
except (ValueError, IndexError):
|
||||
pass
|
||||
proc.wait()
|
||||
if proc.returncode == 0 and os.path.isfile(tmp_path) and os.path.getsize(tmp_path) > 0:
|
||||
os.replace(tmp_path, mp4_path)
|
||||
# Delete original now that MP4 is ready
|
||||
@@ -152,7 +166,8 @@ def list_local_videos():
|
||||
if converting and conv_info:
|
||||
elapsed = time.time() - conv_info["started_at"]
|
||||
duration_s = conv_info.get("duration_s", 0)
|
||||
pct = min(round(elapsed / duration_s * 100), 99) if duration_s > 0 else 0
|
||||
out_time_s = conv_info.get("out_time_s", 0.0)
|
||||
pct = min(round(out_time_s / duration_s * 100), 99) if duration_s > 0 else 0
|
||||
convert_progress = {
|
||||
"elapsed_s": int(elapsed),
|
||||
"pct": pct,
|
||||
|
||||
Reference in New Issue
Block a user