389 lines
13 KiB
Markdown
389 lines
13 KiB
Markdown
# Transcoding Removal & Local Player Implementation Design
|
|
|
|
## Executive Summary
|
|
|
|
This document outlines the complete technical design for removing all transcoding functionality from NextAV and implementing a local video player fallback system. The goal is to eliminate server-side CPU overhead while maintaining full video format support through local player integration.
|
|
|
|
## Current State Analysis
|
|
|
|
### Existing Transcoding Infrastructure
|
|
|
|
**Active Components:**
|
|
- `/api/stream/[id]/transcode` - Full FFmpeg transcoding endpoint
|
|
- `/api/stream/[id]` - Main streaming with transcoding redirect logic
|
|
- `src/lib/ffmpeg/process-registry.ts` - Process management for FFmpeg
|
|
- Video format detection with transcoding fallback
|
|
|
|
**Transcoding Features:**
|
|
- Real-time H.264 encoding with libx264
|
|
- Multi-quality output (480p, 720p, 1080p)
|
|
- Seek-optimized transcoding with -ss parameter
|
|
- Process registry for concurrent session management
|
|
- Quality-based bitrate adaptation
|
|
|
|
**Dependencies:**
|
|
- fluent-ffmpeg library
|
|
- FFmpeg binary with libx264 support
|
|
- Complex process lifecycle management
|
|
|
|
### Browser Security Constraints
|
|
|
|
**Critical Limitation:** Modern browsers prohibit automatic local application launching without explicit user interaction (click/keypress). This is a fundamental security requirement that cannot be bypassed.
|
|
|
|
**Compliance Requirements:**
|
|
- All local player launches require user gesture context
|
|
- Custom protocol handlers need one-time user authorization
|
|
- Browser security policies must be respected
|
|
|
|
## New Architecture Design
|
|
|
|
### System Architecture Overview
|
|
|
|
```
|
|
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
|
│ User Click │───▶│ Format Detection │───▶│ Decision Point │
|
|
└─────────────────┘ └──────────────────┘ └─────────────────┘
|
|
│
|
|
┌─────────────────┐ │
|
|
│ Local Player UI │◀─────────────┤
|
|
└─────────────────┘ │
|
|
│ │
|
|
┌─────────────────┐ │
|
|
│ Player Launch │◀─────────────┘
|
|
└─────────────────┘
|
|
│
|
|
┌─────────────────┐
|
|
│ HTTP Streaming │
|
|
└─────────────────┘
|
|
```
|
|
|
|
### Format Classification Matrix
|
|
|
|
| Format | Extension | Browser Support | Action Required |
|
|
|--------|-----------|-----------------|-----------------|
|
|
| **Tier 1: Native** |
|
|
| MP4 H.264 | .mp4 | ✅ Universal | Direct ArtPlayer |
|
|
| WebM VP9 | .webm | ✅ Chrome/Firefox/Edge | Direct ArtPlayer |
|
|
| MP4 HEVC | .mp4 | ⚠️ Platform dependent | Direct ArtPlayer |
|
|
| **Tier 2: Local Player** |
|
|
| MKV | .mkv | ❌ None | Local Player Required |
|
|
| AVI | .avi | ❌ None | Local Player Required |
|
|
| WMV | .wmv | ❌ None | Local Player Required |
|
|
| FLV | .flv | ❌ None | Local Player Required |
|
|
| MOV* | .mov | ⚠️ Limited | Local Player Required |
|
|
| TS/M2TS | .ts/.m2ts | ❌ None | Local Player Required |
|
|
| **Tier 3: Special Handling** |
|
|
| HLS Streams | .m3u8 | ✅ With plugin | ArtPlayer + HLS.js |
|
|
|
|
*Note: Some MOV files may work in browsers but reliability is low
|
|
|
|
### API Response Changes
|
|
|
|
#### Current Transcoding Response
|
|
```typescript
|
|
// OLD: Redirects to transcoding
|
|
{
|
|
type: 'fallback',
|
|
supportLevel: 'limited',
|
|
url: '/api/stream/123', // Redirects to transcode
|
|
warning: 'Limited playback features for this format'
|
|
}
|
|
```
|
|
|
|
#### New Local Player Response
|
|
```typescript
|
|
// NEW: Direct local player guidance
|
|
{
|
|
type: 'local-player',
|
|
supportLevel: 'local-player-required',
|
|
url: '/api/stream/direct/123',
|
|
action: 'launch-local-player',
|
|
recommendedPlayers: ['vlc', 'elmedia', 'potplayer'],
|
|
streamInfo: {
|
|
contentType: 'video/mp4',
|
|
acceptRanges: 'bytes',
|
|
supportsSeek: true
|
|
}
|
|
}
|
|
```
|
|
|
|
## Detailed Implementation Plan
|
|
|
|
### Phase 1: API Endpoint Modifications (Priority: Critical)
|
|
|
|
**Task ID: API-001**
|
|
- **Description**: Disable transcoding endpoint with informative response
|
|
- **File**: `/src/app/api/stream/[id]/transcode/route.ts`
|
|
- **Changes**:
|
|
- Return HTTP 410 Gone with explanatory message
|
|
- Include local player recommendations
|
|
- Provide direct stream URL for manual access
|
|
- **Testing**: Verify 410 response and message content
|
|
|
|
**Task ID: API-002**
|
|
- **Description**: Remove transcoding redirect from main stream endpoint
|
|
- **File**: `/src/app/api/stream/[id]/route.ts`
|
|
- **Changes**:
|
|
- Remove lines 58-68 (transcoding redirect logic)
|
|
- Return local player required response for unsupported formats
|
|
- Maintain direct streaming for supported formats
|
|
- **Testing**: Test both supported and unsupported format responses
|
|
|
|
**Task ID: API-003**
|
|
- **Description**: Create direct streaming endpoint for local players
|
|
- **File**: `/src/app/api/stream/direct/[id]/route.ts` (new)
|
|
- **Features**:
|
|
- HTTP range request support
|
|
- Proper content headers
|
|
- CORS headers for external players
|
|
- Authentication tokens
|
|
- **Testing**: Verify range requests and headers
|
|
|
|
### Phase 2: Format Detection Overhaul (Priority: High)
|
|
|
|
**Task ID: FORMAT-001**
|
|
- **Description**: Redesign format detection logic
|
|
- **File**: `/src/lib/video-format-detector.ts`
|
|
- **Changes**:
|
|
- Remove transcoding fallback
|
|
- Binary decision: native browser OR local player
|
|
- Add local player format type
|
|
- Update all format creation functions
|
|
- **Testing**: Test format detection for all file types
|
|
|
|
**Task ID: FORMAT-002**
|
|
- **Description**: Create local player format configuration
|
|
- **Implementation**:
|
|
```typescript
|
|
interface LocalPlayerFormat {
|
|
type: 'local-player';
|
|
supportLevel: 'local-player-required';
|
|
url: string;
|
|
action: 'launch-local-player';
|
|
recommendedPlayers: string[];
|
|
streamInfo: StreamInfo;
|
|
}
|
|
```
|
|
|
|
### Phase 3: UI Component Development (Priority: High)
|
|
|
|
**Task ID: UI-001**
|
|
- **Description**: Create local player launcher component
|
|
- **File**: `/src/components/local-player-launcher.tsx`
|
|
- **Features**:
|
|
- Player selection buttons (VLC, Elmedia, PotPlayer)
|
|
- Stream URL display with copy button
|
|
- Launch instructions
|
|
- Cross-platform compatibility
|
|
|
|
**Task ID: UI-002**
|
|
- **Description**: Update video card indicators
|
|
- **File**: `/src/components/video-card.tsx` (modify existing)
|
|
- **Changes**:
|
|
- Show local player required badge
|
|
- Update hover states
|
|
- Modify click behavior for unsupported formats
|
|
|
|
**Task ID: UI-003**
|
|
- **Description**: Modify unified video player
|
|
- **File**: `/src/components/unified-video-player.tsx`
|
|
- **Changes**:
|
|
- Remove ArtPlayer fallback logic
|
|
- Add local player detection
|
|
- Show appropriate UI for each format type
|
|
|
|
### Phase 4: Player Launch System (Priority: Medium)
|
|
|
|
**Task ID: LAUNCH-001**
|
|
- **Description**: Implement cross-platform player launch logic
|
|
- **File**: `/src/lib/local-player-launcher.ts`
|
|
- **Features**:
|
|
- OS detection (macOS/Windows/Linux)
|
|
- Protocol-based launching (vlc://, potplayer://)
|
|
- Command-line fallbacks
|
|
- Error handling and user feedback
|
|
|
|
**Task ID: LAUNCH-002**
|
|
- **Description**: Create player availability detection
|
|
- **Implementation**:
|
|
```typescript
|
|
async function detectAvailablePlayers(): Promise<string[]> {
|
|
// Test protocol handlers
|
|
// Check common installation paths
|
|
// Return available player list
|
|
}
|
|
```
|
|
|
|
### Phase 5: Settings and Preferences (Priority: Medium)
|
|
|
|
**Task ID: SETTINGS-001**
|
|
- **Description**: Add local player preferences
|
|
- **File**: Settings component (existing)
|
|
- **Features**:
|
|
- Preferred player selection
|
|
- Auto-launch toggle
|
|
- Player path configuration
|
|
- Confirmation prompt settings
|
|
|
|
**Task ID: SETTINGS-002**
|
|
- **Description**: Implement preference persistence
|
|
- **Storage**: localStorage + database user preferences
|
|
- **Data**:
|
|
```typescript
|
|
interface LocalPlayerPreferences {
|
|
preferredPlayer: 'auto' | 'vlc' | 'elmedia' | 'potplayer';
|
|
autoLaunch: boolean;
|
|
showConfirmation: boolean;
|
|
customPaths?: Record<string, string>;
|
|
}
|
|
```
|
|
|
|
### Phase 6: Cleanup and Optimization (Priority: Low)
|
|
|
|
**Task ID: CLEANUP-001**
|
|
- **Description**: Remove FFmpeg transcoding dependencies
|
|
- **Actions**:
|
|
- Comment out fluent-ffmpeg imports
|
|
- Remove process registry references
|
|
- Delete transcoding-specific utility functions
|
|
- Keep FFmpeg for thumbnails only
|
|
|
|
**Task ID: CLEANUP-002**
|
|
- **Description**: Update package.json
|
|
- **Changes**:
|
|
- Remove @types/fluent-ffmpeg (if unused)
|
|
- Keep ffmpeg binary for thumbnails
|
|
- Update build scripts if needed
|
|
|
|
**Task ID: CLEANUP-003**
|
|
- **Description**: Update documentation
|
|
- **Files**: README.md, deployment guides
|
|
- **Content**:
|
|
- Local player requirements
|
|
- Installation instructions
|
|
- Troubleshooting guide
|
|
|
|
## User Experience Design
|
|
|
|
### First-Time Setup Flow
|
|
|
|
```
|
|
1. User clicks unsupported video
|
|
2. System shows: "This format requires a local video player"
|
|
3. Display player options with "Remember my choice" checkbox
|
|
4. User selects player and clicks "Launch"
|
|
5. Browser asks: "Allow this site to open [Player]?"
|
|
6. User clicks "Allow" (one-time authorization)
|
|
7. Player opens with video stream
|
|
8. Future launches happen automatically
|
|
```
|
|
|
|
### Settings Panel Integration
|
|
|
|
**Local Player Section**:
|
|
- Preferred Player: [Dropdown with auto-detect/available players]
|
|
- Auto-launch unsupported formats: [Toggle]
|
|
- Show confirmation before launch: [Toggle]
|
|
- Player Installation Links: [VLC | Elmedia | PotPlayer]
|
|
- Test Player Launch: [Button]
|
|
|
|
### Visual Indicators
|
|
|
|
**Video Cards**:
|
|
- 🔗 Icon for local player required
|
|
- Hover tooltip: "Opens in external player"
|
|
- Different border color for unsupported formats
|
|
|
|
**Player Interface**:
|
|
- Clean launch overlay
|
|
- Stream URL with copy button
|
|
- Player selection if multiple available
|
|
- Cancel option to return to grid
|
|
|
|
## Testing Strategy
|
|
|
|
### Unit Tests
|
|
|
|
**Task ID: TEST-001**
|
|
- Format detection accuracy
|
|
- Player launch logic
|
|
- URL generation and authentication
|
|
- Cross-platform compatibility
|
|
|
|
### Integration Tests
|
|
|
|
**Task ID: TEST-002**
|
|
- End-to-end video playback flow
|
|
- Settings persistence
|
|
- Player availability detection
|
|
- Error handling scenarios
|
|
|
|
### Manual Testing Matrix
|
|
|
|
| OS | Browser | Player | Expected Result |
|
|
|----|---------|---------|-----------------|
|
|
| macOS | Chrome | VLC | ✅ Launches successfully |
|
|
| macOS | Safari | Elmedia | ✅ Launches successfully |
|
|
| Windows | Chrome | PotPlayer | ✅ Launches successfully |
|
|
| Windows | Edge | VLC | ✅ Launches successfully |
|
|
| Linux | Firefox | VLC | ✅ Launches successfully |
|
|
|
|
## Success Criteria
|
|
|
|
### Functional Requirements
|
|
- [ ] All transcoding endpoints return 410 Gone
|
|
- [ ] Unsupported formats show local player UI
|
|
- [ ] Supported formats work with ArtPlayer
|
|
- [ ] Player launch works on macOS and Windows
|
|
- [ ] Settings persist across sessions
|
|
- [ ] Stream URLs support range requests
|
|
|
|
### Performance Requirements
|
|
- [ ] Zero server CPU usage for video playback
|
|
- [ ] Player launch under 2 seconds
|
|
- [ ] No memory leaks from removed processes
|
|
- [ ] Responsive UI during player launch
|
|
|
|
### Security Requirements
|
|
- [ ] No automatic launches without user interaction
|
|
- [ ] Proper URL authentication
|
|
- [ ] Clear user consent for protocol handlers
|
|
- [ ] No player enumeration vulnerabilities
|
|
|
|
## Migration Strategy
|
|
|
|
### Deployment Plan
|
|
|
|
1. **Phase 1** (Week 1): Disable transcoding endpoints
|
|
2. **Phase 2** (Week 2): Deploy format detection changes
|
|
3. **Phase 3** (Week 3): Release local player UI
|
|
4. **Phase 4** (Week 4): Cleanup and optimization
|
|
|
|
### Rollback Plan
|
|
|
|
**If Critical Issues Found**:
|
|
1. Revert API endpoints to original transcoding logic
|
|
2. Restore original format detection
|
|
3. Keep new UI components disabled via feature flag
|
|
4. Investigate and fix issues before re-deployment
|
|
|
|
**Feature Flag Implementation**:
|
|
```typescript
|
|
const USE_LOCAL_PLAYER_ONLY = process.env.LOCAL_PLAYER_MODE === 'true';
|
|
```
|
|
|
|
## Risk Assessment
|
|
|
|
### High-Risk Items
|
|
1. **Browser Security Restrictions**: Cannot bypass user interaction requirement
|
|
2. **Player Installation Dependencies**: Users must have players installed
|
|
3. **Network Configuration**: Firewalls may block HTTP streaming
|
|
|
|
### Mitigation Strategies
|
|
1. **Clear User Education**: Provide installation links and setup instructions
|
|
2. **Fallback Options**: Always provide stream URL for manual copy/paste
|
|
3. **Network Detection**: Provide troubleshooting for common network issues
|
|
|
|
## Conclusion
|
|
|
|
This design completely eliminates server-side transcoding while maintaining full video format support through local player integration. The solution respects browser security requirements and provides a seamless user experience through thoughtful UI design and clear user guidance. |