feat(gui): implement GUI edit mode with atomic clip operations

Phase 2 complete - GUI editing layer on top of Phase 1 CLI:

Config:
- config.py now only has API keys (API_KEY, API_HOST, PYTHON, CLI_DIR)
- Project paths (video_src, ppt_path, max_total_duration) in generated_config.yaml

Atomic clip operations (Pipeline methods):
- reextract_clip(clip_index, new_title) - re-match title in transcript
- delete_clip(clip_index) - remove clip and its intermediate files
- add_clip_by_title(new_title) - match new title, handle overlaps
- reburn_titles() - re-burn title track from updated clips
- reburn_subtitles(user_texts) - burn user-edited subtitles directly
- _find_title_in_transcript() - substring match in corrected transcript

GUI:
- Two startup modes: new project / open existing project
- Clip list with double-click rename, right-click delete, + add
- Subtitle preview with direct text editing
- Apply button orchestrates reburn_titles/reburn_subtitles
- Unmatched clips shown with warning label, excluded from burn

CLI/GUI interoperability:
- Both use same generated_config.yaml as single source of truth
- CLI: run.bat for full pipeline, burn.bat for quick reburn
- GUI: open project dir, edit, apply

Docs:
- USAGE.md updated with GUI edit mode documentation
This commit is contained in:
hmo
2026-05-04 01:06:59 +08:00
parent 086ce358a5
commit 9d0ed5820d
5 changed files with 742 additions and 30 deletions
+24 -17
View File
@@ -4,19 +4,18 @@
直接用已有的 clips + title.srt + content.srt 合并烧录
用法:
python burn_only.py
python burn_only.py "D:\\path\\to\\output_dir"
"""
import sys
import os
# 导入统一配置
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import config
# 必须指定输出目录
if len(sys.argv) < 2:
print("用法: python burn_only.py <output_dir>")
print("示例: python burn_only.py \"D:\\path\\to\\output_dir\"")
sys.exit(1)
OUTPUT = config.OUTPUT
if len(sys.argv) > 1:
OUTPUT = sys.argv[1]
OUTPUT = sys.argv[1]
TITLE_SRT = os.path.join(OUTPUT, "subs", "v1_title.srt")
CONTENT_SRT = os.path.join(OUTPUT, "subs", "v1_content.srt")
@@ -40,16 +39,24 @@ src_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "src")
sys.path.insert(0, src_dir)
from core import Pipeline
# 构造 minimal config(只需要 output_dir 和 video_params
pipeline_config = {
'output_dir': OUTPUT,
'clips': [],
'video_src': None,
'video_params': {},
'term_corrections': {},
'api_key': '',
'api_host': '',
}
# 尝试从 generated_config.yaml 加载配置
config_path = os.path.join(OUTPUT, 'generated_config.yaml')
if os.path.exists(config_path):
import yaml
with open(config_path, 'r', encoding='utf-8') as f:
pipeline_config = yaml.safe_load(f) or {}
pipeline_config['output_dir'] = OUTPUT
else:
# 构造 minimal config
pipeline_config = {
'output_dir': OUTPUT,
'clips': [],
'video_src': None,
'video_params': {},
'term_corrections': {},
'api_key': '',
'api_host': '',
}
pipeline = Pipeline(pipeline_config)