1
0

Refactor src layout and add logging lifecycle + tests

This commit is contained in:
2026-04-02 12:32:02 +02:00
parent e3c2b9ddee
commit a0a66264d2
13 changed files with 172 additions and 202 deletions

85
src/concat_merged.py Normal file
View File

@@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""Concatenate merged_*.mp4 files into a single output using ffmpeg concat demuxer."""
from __future__ import annotations
import argparse
import logging
import re
import subprocess
import tempfile
from pathlib import Path
from logging_config import configure_logging, debug_log_lifecycle
SCRIPT_DIR = Path(__file__).resolve().parent
DEFAULT_BASE_DIR = SCRIPT_DIR.parents[1]
DEFAULT_MERGED_DIR = DEFAULT_BASE_DIR / "merged"
DEFAULT_OUTPUT = DEFAULT_BASE_DIR / "results" / "run_3" / "final_output.mp4"
LOGGER = logging.getLogger(__name__)
def shot_number(path: Path) -> int:
match = re.search(r"merged_(\d+)\.mp4$", path.name)
return int(match.group(1)) if match else -1
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--merged-dir", type=Path, default=DEFAULT_MERGED_DIR)
parser.add_argument("--output", type=Path, default=DEFAULT_OUTPUT)
parser.add_argument(
"--log-level",
default=None,
help="Logging level (overrides LOG_LEVEL env var)",
)
return parser.parse_args()
@debug_log_lifecycle
def main() -> int:
args = parse_args()
configure_logging(args.log_level)
videos = sorted(args.merged_dir.glob("merged_*.mp4"), key=shot_number)
if not videos:
LOGGER.warning("No merged videos found in %s", args.merged_dir)
return 1
args.output.parent.mkdir(parents=True, exist_ok=True)
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as tmp:
filelist = Path(tmp.name)
for video in videos:
tmp.write(f"file '{video}'\\n")
try:
LOGGER.info("Concatenating the following files:\n%s", filelist.read_text().rstrip())
subprocess.run(
[
"ffmpeg",
"-f",
"concat",
"-safe",
"0",
"-i",
str(filelist),
"-c",
"copy",
"-y",
str(args.output),
],
check=True,
)
finally:
filelist.unlink(missing_ok=True)
LOGGER.info("Done")
return 0
if __name__ == "__main__":
raise SystemExit(main())