refactor: persist stream selection in .stream_state instead of config.toml
This commit is contained in:
1 parent
8e3db0d7f4
commit
30015d5cad
3 files changed
+34
-32
No files matched your search
+2
-1
@@ -223,4 +223,5 @@ __marimo__/
|
|||||||
extracted/*.mp3
|
extracted/*.mp3
|
||||||
extracted/*.mkv
|
extracted/*.mkv
|
||||||
extracted/*.wav
|
extracted/*.wav
|
||||||
cache/
|
cache/
|
||||||
|
.stream_state
|
||||||
+18
-28
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in new issue
Block a user