# Interactive Audio Stream Selection - Implementation Summary ## Changes Made ### 1. New Function: `prompt_user_audio_selection()` in audio_handler.py - **Purpose**: Display audio streams and prompt user for selection - **Input**: List of streams with (index, channels, bitrate, language, metadata) - **Output**: Filtered list containing only user-selected streams - **Features**: - Displays stream info: `Stream #X: YYch | Lang: YYY | Bitrate: XYZkbps` - Accepts comma-separated input: `1,2,3` or `1` or empty (keep all) - Validates input and logs selections - Falls back to keeping all streams on invalid input ### 2. Updated: `run_ffmpeg()` in encode_engine.py - Now checks `audio_filter_config.get("interactive", False)` - Routes to interactive prompt if `interactive=True` - Routes to automatic filtering if `interactive=False` - Both modes filter streams before codec selection ### 3. Updated: `process_folder()` in process_manager.py - New parameter: `interactive_audio: bool = False` - Builds audio_filter_config with both `enabled` and `interactive` fields - If `--interactive` used without `--filter-audio`, enables both automatically ### 4. Updated: main.py - New CLI argument: `--interactive` - Action: `store_true` (binary flag) - Passed through to `process_folder()` - Help text: "Interactive mode: show audio streams and let user select which to keep (requires --filter-audio)" ## Usage Examples ### Example 1: Automatic Filtering (Existing) ```bash python main.py "C:\Videos" --filter-audio ``` - Automatically keeps best English + Commentary - No user interaction ### Example 2: Interactive Selection (New) ```bash python main.py "C:\Videos" --filter-audio --interactive ``` - Shows each file's audio streams - User picks which streams to keep - Different selections per file allowed ### Example 3: Interactive Without --filter-audio ```bash python main.py "C:\Videos" --interactive ``` - Same as Example 2 (enables filtering automatically) - More intuitive UX ## Stream Display Format When interactive mode runs, user sees: ``` ================================================================================ 🎵 AUDIO STREAM SELECTION ================================================================================ Stream #0: 2ch | Lang: eng | Bitrate: 128kbps Stream #1: 6ch | Lang: eng | Bitrate: 448kbps Stream #2: 2ch | Lang: spa | Bitrate: 128kbps ──────────────────────────────────────────────────────────────────────────── Enter stream numbers to keep (comma-separated, e.g.: 1,2 or just 2) Leave blank to keep all streams ──────────────────────────────────────────────────────────────────────────── ➜ Keep streams: ``` ## Logging Output When user selects streams: ``` ✅ Keeping 2 stream(s), removing 1 stream(s) User selected 2 audio stream(s): [1, 2] Removed 1 audio stream(s): [0] ``` ## Audio Filter Config Structure **Old (Automatic only)**: ```python { "enabled": True/False } ``` **New (With Interactive)**: ```python { "enabled": True/False, "interactive": True/False } ``` ## Flow Diagram ``` main.py └─ parse args (--filter-audio, --interactive) └─ process_folder() └─ for each file: └─ run_ffmpeg() └─ get_audio_streams() └─ if audio_filter_config.enabled: ├─ if audio_filter_config.interactive: │ └─ prompt_user_audio_selection() ← NEW │ └─ [User sees streams and selects] └─ else: └─ filter_audio_streams() (automatic) └─ encode with selected streams ``` ## Input Validation - **Valid**: `1`, `0,1,3`, `2, 3, 5` (spaces OK) - **Invalid**: `abc`, `1.5`, `1-3` (ranges not supported) - **On Invalid**: Keep all streams, log warning ## Edge Cases Handled 1. **No streams**: Return original (nothing to filter) 2. **Single stream**: Return as-is (no selection needed) 3. **Invalid stream indices**: Keep all streams 4. **Empty input**: Keep all streams 5. **No valid selections**: Keep all streams (with warning) ## Backward Compatibility - Existing `--filter-audio` behavior unchanged (automatic mode) - `--interactive` is optional, defaults to False - No breaking changes to config.xml structure - Language tagging (--language) still works alongside audio filtering