# Interactive Audio Stream Selection - Complete Implementation ## Overview ✅ **COMPLETE** - Interactive audio stream selection feature has been successfully implemented. Users can now view all available audio streams in each video file and select which ones to keep for encoding, providing fine-grained control over audio track inclusion. ## Features Implemented ### 1. Stream Display ✅ - Shows all audio streams with human-readable format - Displays: Stream number, channel count, language code, bitrate - Clear visual separation and organized layout - Example: `Stream #0: 2ch | Lang: eng | Bitrate: 128kbps` ### 2. User Input ✅ - Accepts comma-separated stream indices: `0,1,3` - Accepts single stream: `1` - Accepts blank input (keep all streams) - Input validation with helpful error messages - Optional spaces in comma-separated list: `0, 1, 3` ### 3. Filtering ✅ - Removes non-selected streams from encoding - Preserves original stream indices for FFmpeg mapping - Logs all selections and removals - Falls back to keeping all streams on invalid input ### 4. CLI Integration ✅ - New flag: `--interactive` (boolean) - Works with `--filter-audio` flag - Can be used independently (auto-enables filtering) - Integrated into argument parser with help text ### 5. Processing Pipeline ✅ - Called from `run_ffmpeg()` in encode_engine.py - Executed after stream detection - Executed before codec selection - Per-file prompting (allows different selections per video) ### 6. Logging ✅ - Logs user selections: `User selected X audio stream(s): [0, 1, 3]` - Logs removed streams: `Removed X audio stream(s): [2]` - Logs invalid input attempts - Integrated with project's logging system ## File Changes Summary ### main.py **Added**: - `--interactive` argument to argparse - Pass `args.interactive_audio` to `process_folder()` **Lines Changed**: 2 ### core/process_manager.py **Added**: - `interactive_audio: bool = False` parameter to function signature - Logic to set `audio_filter_config["interactive"]` based on CLI args - Auto-enable filtering if `--interactive` used without `--filter-audio` **Lines Changed**: ~5 ### core/encode_engine.py **Added**: - Import `prompt_user_audio_selection` - Check for `audio_filter_config.get("interactive", False)` - Route to interactive or automatic filtering accordingly **Lines Changed**: ~5 ### core/audio_handler.py **Added**: - `prompt_user_audio_selection()` function (64 lines) - Comprehensive docstring - User-friendly output formatting - Input validation and error handling - Logging integration **Lines Changed**: +64 (new function) ## Code Structure ### Function: `prompt_user_audio_selection(streams: list) -> list` **Location**: `core/audio_handler.py` (line 297) **Parameters**: - `streams`: List of (index, channels, bitrate, language, metadata) tuples **Returns**: - Filtered list containing only user-selected streams **Key Features**: 1. Early return if 0-1 streams (no selection needed) 2. Display header with visual formatting 3. Show each stream with index, channels, language, bitrate 4. Prompt for user input with examples 5. Parse comma-separated input 6. Validate stream indices 7. Handle edge cases (empty input, invalid input) 8. Log results to project logger 9. Return filtered streams ready for encoding **Error Handling**: - ValueError on unparseable input → keep all - No valid selections → keep all with warning - Empty input → keep all (user confirmed) ## Execution Flow ``` User runs: $ python main.py "C:\Videos" --filter-audio --interactive ↓ main.py parses arguments - filter_audio = True (from --filter-audio) - interactive_audio = True (from --interactive) ↓ process_folder() called with both flags ↓ For each video file: └─ run_ffmpeg() called └─ get_audio_streams() detects streams └─ Check audio_filter_config.enabled └─ True: Apply filtering └─ Check audio_filter_config.interactive └─ True: Call prompt_user_audio_selection() └─ [INTERACTIVE PROMPT APPEARS] └─ User sees streams and selects └─ Returns filtered stream list └─ False: Call filter_audio_streams() └─ Automatic filtering (keep best English + Commentary) └─ Process selected streams for encoding ``` ## Usage Examples ### Basic Interactive Mode ```bash python main.py "C:\Videos\Movies" --filter-audio --interactive ``` ### Combined with Other Options ```bash python main.py "C:\Videos\TV" --filter-audio --interactive --cq 28 --r 1080 --language eng ``` ### Interactive Without Explicit --filter-audio ```bash python main.py "C:\Videos\Anime" --interactive ``` (Filtering is auto-enabled with interactive mode) ## Testing Scenarios ### Scenario 1: Multiple Audio Languages **Input**: Video with English (stereo), English (5.1), Spanish, Commentary **Expected**: Prompt shows 4 streams, user can select any combination ### Scenario 2: Invalid Selection **Input**: User types "abc" or non-existent stream number **Expected**: Tool logs warning, keeps all streams, continues ### Scenario 3: Single Audio Stream **Input**: Video with only one audio track **Expected**: Function returns early, no prompt shown ### Scenario 4: Empty Input **Input**: User presses Enter without typing **Expected**: All streams kept, confirmation message shown ## Backward Compatibility ✅ **Fully Backward Compatible** - Existing `--filter-audio` behavior unchanged - New feature is opt-in via `--interactive` flag - Default behavior (no interactive) preserved - No changes to config.xml schema required - All existing scripts/automation continues to work ## Integration Points ### With Audio Language Tagging - `--language eng --filter-audio --interactive` works together - User selects streams, then language metadata applied to all ### With Resolution/CQ Options - `--filter-audio --interactive --cq 28 --r 1080` fully compatible - Interactive selection happens first, encoding follows ### With Test Mode - `--filter-audio --interactive --test` shows interactive prompt on first file - Useful for testing selections before batch encoding ## Performance Impact ✅ **Minimal Impact** - Interactive prompt only appears when user explicitly requests it - No performance overhead when `--interactive` not used - Per-file prompt adds negligible time (user wait for input) - No change to FFmpeg encoding performance ## Documentation Provided 1. **INTERACTIVE_AUDIO.md** - User guide with examples 2. **IMPLEMENTATION_NOTES.md** - Technical implementation details 3. **QUICK_REFERENCE.md** - Quick reference guide and FAQ 4. This summary document ## Completion Checklist ✅ Function implementation (prompt_user_audio_selection) ✅ CLI argument (--interactive) ✅ Integration with process_manager ✅ Integration with encode_engine ✅ Input validation ✅ Error handling ✅ Logging integration ✅ Backward compatibility ✅ Documentation ✅ Syntax validation ✅ Code review ## Example Output When user runs with `--filter-audio --interactive`: ``` ================================================================================ 🎵 AUDIO STREAM SELECTION ================================================================================ Stream #0: 2ch | Lang: eng | Bitrate: 128kbps Stream #1: 6ch | Lang: eng | Bitrate: 448kbps Stream #2: 2ch | Lang: spa | Bitrate: 128kbps Stream #3: 2ch | Lang: comment | Bitrate: 64kbps ──────────────────────────────────────────────────────────────────────────── Enter stream numbers to keep (comma-separated, e.g.: 1,2 or just 2) Leave blank to keep all streams ──────────────────────────────────────────────────────────────────────────── ➜ Keep streams: 1,3 ✅ Keeping 2 stream(s), removing 2 stream(s) 🎬 Running CQ encode: output.mkv ... ``` ## Next Steps (Optional Enhancements) Future improvements could include: - [ ] Preset buttons for common selections (e.g., "Best Audio", "English Only", "All") - [ ] Auto-numbering display for clarity - [ ] Arrow key selection interface (more interactive) - [ ] Save/load selection templates for batch consistency - [ ] GUI interface for stream selection - [ ] Default selection from config for silent/batch operation --- ## Summary The interactive audio stream selection feature is **complete and ready for use**. Users can now: 1. ✅ See all available audio streams with details 2. ✅ Choose which streams to keep for encoding 3. ✅ Get immediate confirmation of their selection 4. ✅ Have per-file control in batch operations 5. ✅ Maintain automatic fallback if input is invalid The implementation is clean, well-documented, backward-compatible, and fully integrated into the existing codebase.