diff --git a/modules/app_dash.py b/modules/app_dash.py index a301d75..c906a5a 100644 --- a/modules/app_dash.py +++ b/modules/app_dash.py @@ -232,10 +232,12 @@ def unmount_device(mount_point=DEFAULT_MOUNT_POINT): def find_video_files(source_folder): """Walk source_folder, returning (absolute_path, relative_path) for every - file whose extension looks like a video, regardless of folder layout.""" + file whose extension looks like a video, excluding in-progress conversion temps.""" found = [] for root, _dirs, files in os.walk(source_folder): for file in files: + if file.endswith(".converting.mp4"): + continue if os.path.splitext(file)[1].lower() in VIDEO_EXTENSIONS: abs_path = os.path.join(root, file) rel_path = os.path.relpath(abs_path, source_folder) diff --git a/modules/app_video.py b/modules/app_video.py index 8419e87..e45ab66 100644 --- a/modules/app_video.py +++ b/modules/app_video.py @@ -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,