refactor: persist stream selection in .stream_state instead of config.toml

This commit is contained in:
Honney OC committed 2026-09-14 02:09:02 +00:00
1 parent 2aa6d03810
commit 5ec94cc4dd
3 files changed
+33 -31

No files matched your search

+1
View File
@@ -224,3 +224,4 @@ extracted/*.mp3
extracted/*.mkv extracted/*.mkv
extracted/*.wav extracted/*.wav
cache/ cache/
.stream_state
+18 -28
View File
@@ -493,33 +493,23 @@ for _file_idx, INPUT_FILE in enumerate(INPUT_FILES):
print(f"-" * 50) print(f"-" * 50)
print(f"All done. Files are in:", OUT_DIR) print(f"All done. Files are in:", OUT_DIR)
# ─── Save selected audio stream indices to config.toml ─── # ─── Save selected audio stream indices to .stream_state (gitignored) ───
if len(_audio_stream_selections) >= 2 and CONFIG_PATH and os.path.exists(CONFIG_PATH): if len(_audio_stream_selections) >= 2:
try: try:
with open(CONFIG_PATH, "r") as f: import json
cfg_text = f.read() state_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".stream_state")
# Update or add audio_stream_a and audio_stream_b in [extract] section state = {}
import re if os.path.exists(state_path):
def _cfg_set(key: str, val) -> str: with open(state_path, "r") as f:
nonlocal cfg_text state = json.load(f)
pat = re.compile(rf'(^{key}\s*=\s*).*$') # Record which files these selections belong to
replacement = f'{key} = {val}' state["file_a"] = INPUT_FILES[0]
if pat.search(cfg_text): state["file_b"] = INPUT_FILES[1]
cfg_text = pat.sub(replacement, cfg_text, count=1) for i, sel in enumerate(_audio_stream_selections):
else: key = f"audio_stream_{chr(ord('a') + i)}"
# Insert before the next section header or at end of [extract] state[key] = sel if sel is not None else None
ins_pat = re.compile(r'(\[audio\])') with open(state_path, "w") as f:
if ins_pat.search(cfg_text): json.dump(state, f, indent=2)
cfg_text = ins_pat.sub(f'{replacement}\n\n\\1', cfg_text, count=1) print(f"[state] saved stream selection → {state_path}")
else:
cfg_text += f"\n{replacement}\n"
_cfg_set("audio_stream_a", _audio_stream_selections[0]
if _audio_stream_selections[0] is not None else "null")
_cfg_set("audio_stream_b", _audio_stream_selections[1]
if _audio_stream_selections[1] is not None else "null")
with open(CONFIG_PATH, "w") as f:
f.write(cfg_text)
print(f"[config] saved audio_stream_a={_audio_stream_selections[0]}, "
f"audio_stream_b={_audio_stream_selections[1]} → {CONFIG_PATH}")
except Exception as e: except Exception as e:
print(f"[config] warn: could not save stream indices: {e}", file=sys.stderr) print(f"[state] warn: could not save stream indices: {e}", file=sys.stderr)
+14 -3
View File
@@ -660,7 +660,6 @@ def main():
args = ap.parse_args() args = ap.parse_args()
cfg = load_config(args.config) cfg = load_config(args.config)
ext = cfg.get("extract", {})
sync_cfg = cfg.get("sync", {}) sync_cfg = cfg.get("sync", {})
audio_cfg = cfg.get("audio", {}) audio_cfg = cfg.get("audio", {})
@@ -669,6 +668,17 @@ def main():
out_dir = args.out or sync_cfg.get("out_dir", "output") out_dir = args.out or sync_cfg.get("out_dir", "output")
lag_sec = args.lag lag_sec = args.lag
# Load stream selection from .stream_state (created by extract.py)
_state_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".stream_state")
_state = {}
if os.path.exists(_state_path):
try:
import json
with open(_state_path, "r") as _sf:
_state = json.load(_sf)
except Exception:
pass
if args.mode == "full": if args.mode == "full":
synced = args.synced synced = args.synced
if not synced: if not synced:
@@ -691,11 +701,12 @@ def main():
# Determine which streams to extract from synced MKV # Determine which streams to extract from synced MKV
# A's streams are first, B's delayed streams follow # A's streams are first, B's delayed streams follow
ext = cfg.get("extract", {})
video_a = ext.get("file_a", "") video_a = ext.get("file_a", "")
a_streams_in = probe_audio_streams(video_a) if os.path.exists(video_a) else [] a_streams_in = probe_audio_streams(video_a) if os.path.exists(video_a) else []
n_a = len(a_streams_in) n_a = len(a_streams_in)
sel_a = ext.get("audio_stream_a", 0) or 0 sel_a = _state.get("audio_stream_a", 0) or 0
sel_b = ext.get("audio_stream_b", 0) or 0 sel_b = _state.get("audio_stream_b", 0) or 0
sel_a = int(sel_a) sel_a = int(sel_a)
sel_b = int(sel_b) sel_b = int(sel_b)
# Output indices: A's selected stream stays at sel_a, B's becomes n_a + sel_b # Output indices: A's selected stream stays at sel_a, B's becomes n_a + sel_b