281 lines
8.9 KiB
Markdown
281 lines
8.9 KiB
Markdown
# 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.
|