diff --git a/config.toml b/config.toml index f539ef3..f828418 100644 --- a/config.toml +++ b/config.toml @@ -5,9 +5,6 @@ # Input files — relative to repo root or absolute. Same as extract.py inputs. file_a = "/home/honney/Videos/Drachenzähmen/Drachenzaehmen.mp4" file_b = "/home/honney/Videos/Drachenzähmen/How to Train Your Dragon.mkv" -# Output stem names (without extension). If omitted, derived from input filename. -stem_a = "file_a" -stem_b = "file_b" # Window to extract (seconds). This is the ONLY duration needed. duration = 30 # Start offset in file (seconds, 0 = file start). ffmpeg -ss before -i for fast seek. diff --git a/extract.py b/extract.py index 14d96ab..803d81d 100644 --- a/extract.py +++ b/extract.py @@ -26,7 +26,6 @@ _cfg_target_lufs = -14 _cfg_target_tp = -1.0 _cfg_target_lra = 11 _cfg_audio_stream = None # None = prompt, int = index, "skip" = no audio extraction -_cfg_stems = [None, None] # stem_a, stem_b from config try: try: import tomllib # py3.11+ @@ -72,10 +71,6 @@ try: _cfg_audio_stream = "skip" elif isinstance(val, (int, float)): _cfg_audio_stream = int(val) - if _ex.get("stem_a"): - _cfg_stems[0] = str(_ex["stem_a"]) - if _ex.get("stem_b"): - _cfg_stems[1] = str(_ex["stem_b"]) if _cfg_inputs: print(f"[config] loaded {CONFIG_PATH}: duration={_cfg_duration}s start={_cfg_start}s target_fps={_cfg_target_fps}") except Exception as _e: @@ -383,14 +378,42 @@ if len(valid_fps) >= 2: elif not all_match: print(f"NOTE: inputs share fps {valid_fps[0]:.3f} but differ from target {TARGET_FPS} — both will be normalized to {TARGET_FPS}.") +# ─── Derive output stems from path divergence ─── +def _derive_stems(paths: list[str]) -> list[str]: + """For each path, give a stem: if filenames differ, just use filename stem. + If filenames match, walk up dirs until parents diverge and use the remaining relative path.""" + stems = [] + # first strip extensions, get bare names + basenames = [os.path.splitext(os.path.basename(p))[0] for p in paths] + if len(paths) == 1 or basenames[0] != basenames[1]: + # different filenames — just use them directly + return basenames + # same filename — walk up until parent dirs differ + parts_a = os.path.normpath(paths[0]).split(os.sep) + parts_b = os.path.normpath(paths[1]).split(os.sep) + # find divergence point from the end (walk up from file) + common = 0 + for a, b in zip(reversed(parts_a), reversed(parts_b)): + if a == b: + common += 1 + else: + break + # remaining parts after divergence = relative unique path (dirs + filename) + rel_a = parts_a[len(parts_a) - common:] # includes filename + rel_b = parts_b[len(parts_b) - common:] + stem_a = os.path.join(*rel_a) if len(rel_a) > 1 else rel_a[0] + stem_b = os.path.join(*rel_b) if len(rel_b) > 1 else rel_b[0] + return [stem_a, stem_b] + +_stems = _derive_stems(INPUT_FILES) + # ─── Prepare output folder ─── os.makedirs(OUT_DIR, exist_ok=True) for _file_idx, INPUT_FILE in enumerate(INPUT_FILES): # ─── Derive output filenames ─── - cfg_stem = _cfg_stems[_file_idx] if _file_idx < len(_cfg_stems) else None - stem = cfg_stem if cfg_stem else os.path.splitext(os.path.basename(INPUT_FILE))[0] + stem = _stems[_file_idx] video_out = os.path.join(OUT_DIR, f"{stem}_video.mkv") # FFV1 audio_out = os.path.join(OUT_DIR, f"{stem}_audio.wav") # PCM f32