diff --git a/config.toml b/config.toml index 11978e5..4385fe9 100644 --- a/config.toml +++ b/config.toml @@ -5,6 +5,9 @@ # Input files — relative to repo root or absolute. Same as extract.py inputs. file_a = "/path/to/movie_b.mp4" file_b = "/path/to/movie_a.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 d5609de..f22d7d8 100644 --- a/extract.py +++ b/extract.py @@ -26,6 +26,7 @@ _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+ @@ -71,6 +72,10 @@ 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: @@ -381,10 +386,11 @@ if len(valid_fps) >= 2: # ─── Prepare output folder ─── os.makedirs(OUT_DIR, exist_ok=True) -for INPUT_FILE in INPUT_FILES: +for _file_idx, INPUT_FILE in enumerate(INPUT_FILES): # ─── Derive output filenames ─── - stem = os.path.splitext(os.path.basename(INPUT_FILE))[0] + 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] 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 diff --git a/sync_audio_test.py b/sync_audio_test.py index 87dc77a..91e6e17 100644 --- a/sync_audio_test.py +++ b/sync_audio_test.py @@ -24,7 +24,7 @@ except ModuleNotFoundError: try: import pyqtgraph as pg - from PyQt6 import QtWidgets, QtCore + from PyQt6 import QtWidgets, QtCore, QtGui HAS_PG = True except ImportError as e: print("ERROR: pyqtgraph/PyQt6 not installed — run make install", file=sys.stderr) @@ -477,7 +477,26 @@ def main(): print(f"ERROR: B not found {b_path}", file=sys.stderr); sys.exit(1) app = QtWidgets.QApplication(sys.argv) - pg.setConfigOptions(antialias=True, background="#121212", foreground="#eee") + # Dark theme: Fusion style + dark palette (works without kvantum) + app.setStyle("Fusion") + dark = QtWidgets.QPalette() + dark.setColor(QtWidgets.QPalette.ColorRole.Window, QtGui.QColor(45, 45, 45)) + dark.setColor(QtWidgets.QPalette.ColorRole.WindowText, QtGui.QColor(220, 220, 220)) + dark.setColor(QtWidgets.QPalette.ColorRole.Base, QtGui.QColor(30, 30, 30)) + dark.setColor(QtWidgets.QPalette.ColorRole.AlternateBase, QtGui.QColor(45, 45, 45)) + dark.setColor(QtWidgets.QPalette.ColorRole.ToolTipBase, QtGui.QColor(45, 45, 45)) + dark.setColor(QtWidgets.QPalette.ColorRole.ToolTipText, QtGui.QColor(220, 220, 220)) + dark.setColor(QtWidgets.QPalette.ColorRole.Text, QtGui.QColor(220, 220, 220)) + dark.setColor(QtWidgets.QPalette.ColorRole.Button, QtGui.QColor(45, 45, 45)) + dark.setColor(QtWidgets.QPalette.ColorRole.ButtonText, QtGui.QColor(220, 220, 220)) + dark.setColor(QtWidgets.QPalette.ColorRole.BrightText, QtGui.QColor(255, 50, 50)) + dark.setColor(QtWidgets.QPalette.ColorRole.Link, QtGui.QColor(100, 180, 255)) + dark.setColor(QtWidgets.QPalette.ColorRole.Highlight, QtGui.QColor(60, 120, 200)) + dark.setColor(QtWidgets.QPalette.ColorRole.HighlightedText, QtGui.QColor(255, 255, 255)) + dark.setColor(QtWidgets.QPalette.ColorRole.Disabled, QtWidgets.QPalette.ColorRole.Text, QtGui.QColor(120, 120, 120)) + dark.setColor(QtWidgets.QPalette.ColorRole.Disabled, QtWidgets.QPalette.ColorRole.ButtonText, QtGui.QColor(120, 120, 120)) + app.setPalette(dark) + pg.setConfigOptions(antialias=True, background="#1e1e1e", foreground="#ddd") w = SyncWindow(a_path, b_path, sr=sr, method=method, device=device) w.show() sys.exit(app.exec())