Skip to content

Commit c8082bb

Browse files
committed
Add comprehensive instructions for GoSubtitle AI Coding Agent
1 parent f17fca8 commit c8082bb

1 file changed

Lines changed: 144 additions & 0 deletions

File tree

.github/copilot-instructions.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# GoSubtitle AI Coding Agent Instructions
2+
3+
## Project Overview
4+
5+
GoSubtitle is a PyQt6 desktop application that converts Movie XML files (containing TTS data) to SRT subtitle format. It features dual interface modes: GUI for interactive editing and console mode for batch processing/automation.
6+
7+
## Architecture Pattern
8+
9+
The codebase follows a clean 3-layer architecture:
10+
11+
- **Presentation Layer**: `modules/window.py` (GUI), `modules/console.py` (CLI)
12+
- **Business Logic**: `modules/subtitle_processor.py` (core XML parsing, subtitle processing)
13+
- **Utilities**: `helpers.py`, `modules/parameters.py` (command-line parsing)
14+
15+
**Key principle**: All subtitle processing logic lives in `SubtitleProcessor` class. GUI and console are thin clients that delegate to this core engine.
16+
17+
## Entry Point & Mode Detection
18+
19+
`main.py` automatically detects execution context:
20+
21+
- Console available → console mode via `Console` class
22+
- No console OR `-g/--gui` flag → GUI mode via `MainWindow`
23+
- Uses `helpers.has_console()` with Windows-specific `ctypes.windll.kernel32.GetConsoleWindow()`
24+
25+
## Critical Development Patterns
26+
27+
### UI File Loading
28+
29+
UI files are loaded from `ui/` directory using `pathlib` for cross-platform compatibility:
30+
31+
```python
32+
BASE_DIR = Path(__file__).resolve().parent.parent
33+
UI_DIR = BASE_DIR / "ui"
34+
uic.loadUi(str(UI_DIR / "main_window.ui"), self)
35+
```
36+
37+
### Frame-Based Timing System
38+
39+
All timing calculations use **frames at 24 FPS** (hardcoded constant):
40+
41+
- XML contains frame numbers, not timestamps
42+
- `SubtitleProcessor.format_time()` converts frames → SRT timestamp format
43+
- Offset operations work in frame units
44+
45+
### Subtitle Processing Pipeline
46+
47+
1. **Parse XML**: Extract TTS sound elements with `tts='1'` attribute
48+
2. **Merge Overlapping**: Combine subtitles with overlapping time ranges
49+
3. **Smart Splitting**: Break long subtitles by sentence boundaries + word count limits
50+
4. **Time Distribution**: Calculate timing based on `words_per_second` rate
51+
52+
### Command-Line Integration
53+
54+
`Parameters` class handles argparse with custom post-processing:
55+
56+
- Speaker replacements: `"old:new"` format → dictionary mapping
57+
- Multiple `-r` flags supported for batch replacements
58+
- Uses `getattr(self.args, param_name)` pattern for parameter access
59+
60+
## Development Workflows
61+
62+
### Building Executables
63+
64+
PyInstaller spec generates TWO executables:
65+
66+
```bash
67+
pyinstaller GoSubtitle.spec
68+
# Creates: dist/GoSubtitle.exe (GUI) and dist/GoSubtitle_CLI.exe (console)
69+
```
70+
71+
Spec includes UI and assets folders as data files.
72+
73+
### Testing Subtitle Processing
74+
75+
Use console mode for quick validation:
76+
77+
```bash
78+
python main.py -f test.xml --verbose # Shows statistics
79+
python main.py -f test.xml -o 24 -r "old:new" --max-words 15
80+
```
81+
82+
### Logging Configuration
83+
84+
Each module configures its own logger:
85+
86+
```python
87+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
88+
logger = logging.getLogger(__name__)
89+
```
90+
91+
## Key Configuration Constants
92+
93+
In `SubtitleProcessor`:
94+
95+
- `FPS = 24`: Fixed frame rate (do not make configurable without XML format changes)
96+
- `DEFAULT_MAX_WORDS_PER_LINE = 10`: Subtitle splitting threshold
97+
- `DEFAULT_WORDS_PER_SECOND = 2.5`: Speaking rate for timing calculations
98+
- `MIN_SUBTITLE_DURATION = 0.5`: Minimum subtitle duration in seconds
99+
100+
## Expected XML Format
101+
102+
```xml
103+
<root duration="[total_frames]">
104+
<sound tts="1">
105+
<start>[start_frame]</start>
106+
<stop>[stop_frame]</stop>
107+
<ttsdata>
108+
<text>[subtitle_text]</text>
109+
<voice>[speaker_name]</voice>
110+
</ttsdata>
111+
</sound>
112+
</root>
113+
```
114+
115+
## Module Import Pattern
116+
117+
Uses `__init__.py` with explicit `__all__` exports:
118+
119+
```python
120+
from .window import MainWindow
121+
from .console import Console
122+
# Import from modules package, not direct file paths
123+
```
124+
125+
## PyQt6 Specifics
126+
127+
- UI files created with Qt Designer, loaded via `uic.loadUi()`
128+
- Icons and assets bundled in `assets/` directory
129+
- Uses `pathlib` for all file operations (Windows + cross-platform)
130+
- No custom widgets - uses standard PyQt6 components
131+
132+
## Common Debugging Points
133+
134+
1. **UI Not Loading**: Check that `ui/` directory is accessible from execution path
135+
2. **XML Parse Errors**: Validate XML has required `duration` attribute and TTS sound elements
136+
3. **Timing Issues**: Remember all operations are frame-based at 24 FPS
137+
4. **Speaker Replacements**: Must use exact string matching (case-sensitive)
138+
139+
## Extension Guidelines
140+
141+
- New features → add to `SubtitleProcessor` first, then expose via GUI/console
142+
- UI changes → modify `.ui` files with Qt Designer, not hand-coding
143+
- CLI options → extend `Parameters` class argument definitions
144+
- Keep frame-based timing system for XML compatibility

0 commit comments

Comments
 (0)