635 lines
16 KiB
Markdown
635 lines
16 KiB
Markdown
# Transcoding Removal Implementation Tasks
|
|
|
|
## Task Tracking System
|
|
|
|
Each task has a unique ID, priority level, dependencies, and completion criteria. Tasks are organized by implementation phase.
|
|
|
|
## Phase 1: API Endpoint Modifications
|
|
|
|
### Task API-001: Disable Transcoding Endpoint
|
|
**Priority**: Critical
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 2 hours
|
|
**Dependencies**: None
|
|
|
|
**Description**: Replace transcoding endpoint with local player guidance
|
|
|
|
**File**: `/src/app/api/stream/[id]/transcode/route.ts`
|
|
|
|
**Changes Required**:
|
|
```typescript
|
|
export async function GET() {
|
|
return NextResponse.json({
|
|
error: 'Transcoding is disabled. This format requires a local video player.',
|
|
suggestedPlayers: ['VLC Media Player', 'Elmedia Player', 'PotPlayer'],
|
|
directStreamUrl: `/api/stream/direct/${id}`,
|
|
helpUrl: '/help/local-players'
|
|
}, { status: 410 }); // 410 Gone
|
|
}
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Returns HTTP 410 Gone status
|
|
- [ ] Includes helpful error message
|
|
- [ ] Lists recommended players
|
|
- [ ] Provides direct stream URL
|
|
- [ ] Tests pass with expected response format
|
|
|
|
---
|
|
|
|
### Task API-002: Remove Transcoding Redirect Logic
|
|
**Priority**: Critical
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 3 hours
|
|
**Dependencies**: API-001
|
|
|
|
**Description**: Eliminate transcoding redirect from main stream endpoint
|
|
|
|
**File**: `/src/app/api/stream/[id]/route.ts`
|
|
|
|
**Remove**: Lines 58-68 (transcoding redirect block)
|
|
**Replace With**:
|
|
```typescript
|
|
if (needsTranscoding) {
|
|
return NextResponse.json({
|
|
error: 'Format not supported in browser',
|
|
solution: 'local-player',
|
|
directStreamUrl: `/api/stream/direct/${id}`,
|
|
recommendedPlayers: ['vlc', 'elmedia', 'potplayer'],
|
|
action: 'use-local-player'
|
|
}, { status: 415 }); // Unsupported Media Type
|
|
}
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] No transcoding redirects occur
|
|
- [ ] Proper 415 status for unsupported formats
|
|
- [ ] Helpful response payload
|
|
- [ ] Maintains direct streaming for supported formats
|
|
|
|
---
|
|
|
|
### Task API-003: Create Direct Streaming Endpoint
|
|
**Priority**: High
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 4 hours
|
|
**Dependencies**: None
|
|
|
|
**Description**: New endpoint for local player HTTP streaming
|
|
|
|
**File**: `/src/app/api/stream/direct/[id]/route.ts` (new file)
|
|
|
|
**Requirements**:
|
|
- Full HTTP range request support
|
|
- Proper CORS headers for external players
|
|
- Content-Type headers based on file extension
|
|
- Optional authentication tokens
|
|
- Support for all video formats
|
|
|
|
**Implementation Template**:
|
|
```typescript
|
|
export async function GET(
|
|
request: NextRequest,
|
|
{ params }: { params: Promise<{ id: string }> }
|
|
) {
|
|
// 1. Validate video ID and permissions
|
|
// 2. Get file path from database
|
|
// 3. Set appropriate headers for external players
|
|
// 4. Handle range requests for seeking
|
|
// 5. Stream file with proper content type
|
|
}
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Supports byte-range requests
|
|
- [ ] Returns correct Content-Type headers
|
|
- [ ] Includes CORS headers for external access
|
|
- [ ] Works with VLC, Elmedia, PotPlayer
|
|
- [ ] Performance tests show minimal overhead
|
|
|
|
## Phase 2: Format Detection System
|
|
|
|
### Task FORMAT-001: Redesign Format Detection Logic
|
|
**Priority**: Critical
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 3 hours
|
|
**Dependencies**: API-002
|
|
|
|
**Description**: Replace transcoding fallback with local player
|
|
|
|
**File**: `/src/lib/video-format-detector.ts`
|
|
|
|
**Key Changes**:
|
|
```typescript
|
|
// Remove this function entirely
|
|
function createFallbackFormat(video: VideoFile): VideoFormat {
|
|
// OLD: Returns transcoding format
|
|
}
|
|
|
|
// Replace with new local player format
|
|
function createLocalPlayerFormat(video: VideoFile): VideoFormat {
|
|
return {
|
|
type: 'local-player',
|
|
supportLevel: 'local-player-required',
|
|
url: `/api/stream/direct/${video.id}`,
|
|
action: 'launch-local-player',
|
|
recommendedPlayers: ['vlc', 'elmedia', 'potplayer'],
|
|
streamInfo: {
|
|
contentType: getMimeType(getFileExtension(video.path)),
|
|
acceptRanges: 'bytes',
|
|
supportsSeek: true
|
|
}
|
|
};
|
|
}
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] No transcoding format types remain
|
|
- [ ] All unsupported formats return local-player type
|
|
- [ ] Binary decision logic (native OR local-player)
|
|
- [ ] Maintains existing HLS and direct streaming logic
|
|
- [ ] Unit tests pass for all format types
|
|
|
|
---
|
|
|
|
### Task FORMAT-002: Update Format Type Definitions
|
|
**Priority**: High
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 1 hour
|
|
**Dependencies**: FORMAT-001
|
|
|
|
**Description**: Update TypeScript interfaces
|
|
|
|
**File**: `/src/lib/video-format-detector.ts`
|
|
|
|
**Interface Updates**:
|
|
```typescript
|
|
export interface VideoFormat {
|
|
type: 'direct' | 'hls' | 'local-player'; // Removed 'fallback'
|
|
url: string;
|
|
mimeType?: string;
|
|
supportLevel: 'native' | 'hls' | 'local-player-required'; // Updated
|
|
action?: 'launch-local-player'; // New
|
|
recommendedPlayers?: string[]; // New
|
|
streamInfo?: StreamInfo; // New
|
|
}
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] All interfaces updated
|
|
- [ ] No TypeScript compilation errors
|
|
- [ ] Backward compatibility maintained where possible
|
|
|
|
## Phase 3: UI Component Development
|
|
|
|
### Task UI-001: Create Local Player Launcher Component
|
|
**Priority**: High
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 6 hours
|
|
**Dependencies**: FORMAT-001
|
|
|
|
**Description**: Primary UI for local player selection and launch
|
|
|
|
**File**: `/src/components/local-player-launcher.tsx`
|
|
|
|
**Component Requirements**:
|
|
```tsx
|
|
interface LocalPlayerLauncherProps {
|
|
video: VideoFile;
|
|
format: VideoFormat;
|
|
onClose: () => void;
|
|
onPlayerSelect: (player: string) => void;
|
|
}
|
|
```
|
|
|
|
**UI Elements**:
|
|
- Header: "This format requires a local video player"
|
|
- Player selection buttons with icons
|
|
- Stream URL display with copy functionality
|
|
- Launch instructions
|
|
- Settings link
|
|
- Cancel button
|
|
|
|
**Styling Requirements**:
|
|
- Consistent with existing design system
|
|
- Responsive layout
|
|
- Loading states
|
|
- Error handling display
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Matches design mockups
|
|
- [ ] All player buttons functional
|
|
- [ ] Copy URL feature works
|
|
- [ ] Responsive on mobile/desktop
|
|
- [ ] Accessibility compliant
|
|
|
|
---
|
|
|
|
### Task UI-002: Update Video Card Indicators
|
|
**Priority**: Medium
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 2 hours
|
|
**Dependencies**: FORMAT-001
|
|
|
|
**Description**: Visual indicators for local player required videos
|
|
|
|
**File**: Video card components (existing)
|
|
|
|
**Changes**:
|
|
```tsx
|
|
{format.type === 'local-player' && (
|
|
<div className="format-badge local-player">
|
|
<ExternalLinkIcon size={16} />
|
|
<span>Local Player</span>
|
|
</div>
|
|
)}
|
|
```
|
|
|
|
**Visual Requirements**:
|
|
- Distinctive badge/icon
|
|
- Hover tooltip explaining requirement
|
|
- Different hover state for unsupported formats
|
|
- Consistent with existing badge styling
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Clear visual distinction
|
|
- [ ] Tooltip provides helpful information
|
|
- [ ] Mobile-friendly display
|
|
- [ ] Consistent with design system
|
|
|
|
---
|
|
|
|
### Task UI-003: Modify Unified Video Player
|
|
**Priority**: High
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 4 hours
|
|
**Dependencies**: UI-001
|
|
|
|
**Description**: Update main player to handle local player formats
|
|
|
|
**File**: `/src/components/unified-video-player.tsx`
|
|
|
|
**Key Changes**:
|
|
```tsx
|
|
// Replace fallback logic
|
|
if (format?.type === 'local-player') {
|
|
return (
|
|
<LocalPlayerLauncher
|
|
video={video}
|
|
format={format}
|
|
onClose={onClose}
|
|
onPlayerSelect={handlePlayerSelect}
|
|
/>
|
|
);
|
|
}
|
|
|
|
// Remove ArtPlayer fallback attempts
|
|
// Keep only native format support
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] No transcoding fallbacks remain
|
|
- [ ] Local player launcher integrates seamlessly
|
|
- [ ] ArtPlayer works for supported formats
|
|
- [ ] Error states handled properly
|
|
|
|
## Phase 4: Player Launch System
|
|
|
|
### Task LAUNCH-001: Cross-Platform Launch Logic
|
|
**Priority**: High
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 5 hours
|
|
**Dependencies**: UI-003
|
|
|
|
**Description**: Implement player launching for all platforms
|
|
|
|
**File**: `/src/lib/local-player-launcher.ts`
|
|
|
|
**Implementation**:
|
|
```typescript
|
|
export async function launchLocalPlayer(
|
|
player: string,
|
|
streamUrl: string
|
|
): Promise<LaunchResult> {
|
|
const os = detectOS();
|
|
const commands = {
|
|
vlc: getVLCLaunchCommand(os, streamUrl),
|
|
elmedia: getElmediaLaunchCommand(os, streamUrl),
|
|
potplayer: getPotPlayerLaunchCommand(os, streamUrl)
|
|
};
|
|
|
|
// Execute launch with error handling
|
|
return executeLaunch(commands[player]);
|
|
}
|
|
```
|
|
|
|
**Platform Support**:
|
|
- macOS: `open -a "VLC" <url>` or `vlc://<url>`
|
|
- Windows: `start vlc.exe <url>` or `vlc://<url>`
|
|
- Linux: `vlc <url>` (if available)
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Works on macOS, Windows, Linux
|
|
- [ ] Protocol handlers work when registered
|
|
- [ ] Command-line fallbacks implemented
|
|
- [ ] Proper error messages for failures
|
|
|
|
---
|
|
|
|
### Task LAUNCH-002: Player Availability Detection
|
|
**Priority**: Medium
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 3 hours
|
|
**Dependencies**: LAUNCH-001
|
|
|
|
**Description**: Detect which players are available on the system
|
|
|
|
**File**: `/src/lib/player-detection.ts`
|
|
|
|
**Detection Methods**:
|
|
1. Protocol handler testing (vlc://, potplayer://)
|
|
2. Common installation path checking
|
|
3. User preference storage
|
|
4. Browser extension integration (future)
|
|
|
|
**Implementation**:
|
|
```typescript
|
|
export async function detectAvailablePlayers(): Promise<Player[]> {
|
|
const players: Player[] = [];
|
|
|
|
// Test protocol handlers
|
|
if (await testProtocolHandler('vlc://')) {
|
|
players.push({ id: 'vlc', name: 'VLC Media Player', available: true });
|
|
}
|
|
|
|
// Check common paths
|
|
if (await checkInstallationPath('/Applications/VLC.app')) {
|
|
players.push({ id: 'vlc', name: 'VLC Media Player', available: true });
|
|
}
|
|
|
|
return players;
|
|
}
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Accurately detects installed players
|
|
- [ ] Handles permission denials gracefully
|
|
- [ ] Caches results for performance
|
|
- [ ] Updates detection when players installed
|
|
|
|
## Phase 5: Settings and Preferences
|
|
|
|
### Task SETTINGS-001: Local Player Preferences UI
|
|
**Priority**: Medium
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 3 hours
|
|
**Dependencies**: LAUNCH-002
|
|
|
|
**Description**: Add local player section to settings
|
|
|
|
**File**: Settings component (existing)
|
|
|
|
**UI Components**:
|
|
- Player preference dropdown
|
|
- Auto-launch toggle
|
|
- Confirmation prompt option
|
|
- Player installation links
|
|
- Test launch button
|
|
|
|
**Layout**:
|
|
```tsx
|
|
<SettingsSection title="Local Video Player">
|
|
<Select
|
|
label="Preferred Player"
|
|
options={availablePlayers}
|
|
value={preferredPlayer}
|
|
onChange={setPreferredPlayer}
|
|
/>
|
|
<Toggle
|
|
label="Auto-launch for unsupported formats"
|
|
checked={autoLaunch}
|
|
onChange={setAutoLaunch}
|
|
/>
|
|
<Toggle
|
|
label="Show confirmation before launch"
|
|
checked={showConfirmation}
|
|
onChange={setShowConfirmation}
|
|
/>
|
|
<Button onClick={testPlayerLaunch}>
|
|
Test Player Launch
|
|
</Button>
|
|
</SettingsSection>
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Integrates with existing settings
|
|
- [ ] All controls functional
|
|
- [ ] Saves preferences correctly
|
|
- [ ] Test button works
|
|
|
|
---
|
|
|
|
### Task SETTINGS-002: Preference Persistence
|
|
**Priority**: Medium
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 2 hours
|
|
**Dependencies**: SETTINGS-001
|
|
|
|
**Description**: Store and retrieve user preferences
|
|
|
|
**Storage Implementation**:
|
|
```typescript
|
|
interface LocalPlayerPreferences {
|
|
preferredPlayer: string;
|
|
autoLaunch: boolean;
|
|
showConfirmation: boolean;
|
|
lastDetection: number;
|
|
availablePlayers: Player[];
|
|
}
|
|
|
|
// localStorage for immediate access
|
|
// Database for cross-device sync (future)
|
|
```
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Persists across browser sessions
|
|
- [ ] Loads immediately on app start
|
|
- [ ] Handles missing/corrupt data gracefully
|
|
- [ ] Syncs with UI state correctly
|
|
|
|
## Phase 6: Cleanup and Optimization
|
|
|
|
### Task CLEANUP-001: Remove Transcoding Dependencies
|
|
**Priority**: Low
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 4 hours
|
|
**Dependencies**: All Phase 1-5 complete
|
|
|
|
**Description**: Clean removal of transcoding code
|
|
|
|
**Files to Update**:
|
|
- Remove fluent-ffmpeg imports
|
|
- Delete process registry references
|
|
- Comment out transcoding utilities
|
|
- Keep FFmpeg for thumbnails only
|
|
|
|
**Safety Measures**:
|
|
- Comment rather than delete initially
|
|
- Add feature flags for rollback
|
|
- Document removed functionality
|
|
- Keep backup of working code
|
|
|
|
**Completion Criteria**:
|
|
- [ ] No transcoding code executes
|
|
- [ ] Build process works correctly
|
|
- [ ] No runtime errors
|
|
- [ ] Easy rollback possible
|
|
|
|
---
|
|
|
|
### Task CLEANUP-002: Update Dependencies
|
|
**Priority**: Low
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 1 hour
|
|
**Dependencies**: CLEANUP-001
|
|
|
|
**Description**: Clean up package.json
|
|
|
|
**Changes**:
|
|
- Remove @types/fluent-ffmpeg (if unused elsewhere)
|
|
- Keep ffmpeg binary for thumbnails
|
|
- Update any build scripts
|
|
- Verify all imports work
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Package.json updated correctly
|
|
- [ ] All builds pass
|
|
- [ ] No unused dependencies
|
|
- [ ] Thumbnail generation still works
|
|
|
|
---
|
|
|
|
### Task CLEANUP-003: Documentation Update
|
|
**Priority**: Low
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 2 hours
|
|
**Dependencies**: CLEANUP-002
|
|
|
|
**Description**: Update all relevant documentation
|
|
|
|
**Files to Update**:
|
|
- README.md - Local player requirements
|
|
- Deployment guides - Remove transcoding setup
|
|
- API documentation - New response formats
|
|
- User guides - Player installation help
|
|
|
|
**Completion Criteria**:
|
|
- [ ] All docs reflect new architecture
|
|
- [ ] Installation instructions clear
|
|
- [ ] API documentation updated
|
|
- [ ] Troubleshooting guide included
|
|
|
|
## Testing Tasks
|
|
|
|
### Task TEST-001: Unit Test Suite
|
|
**Priority**: High
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 6 hours
|
|
**Dependencies**: Phase 2 complete
|
|
|
|
**Test Coverage**:
|
|
- Format detection accuracy
|
|
- Player launch logic
|
|
- URL generation and authentication
|
|
- Cross-platform compatibility
|
|
- Error handling scenarios
|
|
|
|
**Test Files**:
|
|
- `video-format-detector.test.ts`
|
|
- `local-player-launcher.test.ts`
|
|
- `player-detection.test.ts`
|
|
|
|
**Completion Criteria**:
|
|
- [ ] 90%+ code coverage
|
|
- [ ] All edge cases handled
|
|
- [ ] Mock external dependencies
|
|
- [ ] Tests run in CI/CD
|
|
|
|
### Task TEST-002: Integration Testing
|
|
**Priority**: Medium
|
|
**Status**: ⏳ Pending
|
|
**Assignee**: TBD
|
|
**Estimated Time**: 4 hours
|
|
**Dependencies**: Phase 4 complete
|
|
|
|
**Test Scenarios**:
|
|
- End-to-end video playback flow
|
|
- Settings persistence
|
|
- Player availability detection
|
|
- Error recovery
|
|
|
|
**Completion Criteria**:
|
|
- [ ] Manual testing matrix complete
|
|
- [ ] Automated integration tests pass
|
|
- [ ] Cross-browser compatibility verified
|
|
- [ ] Performance benchmarks met
|
|
|
|
## Task Status Legend
|
|
- ⏳ **Pending**: Not started
|
|
- 🔄 **In Progress**: Currently being worked on
|
|
- ✅ **Completed**: Finished and tested
|
|
- ❌ **Blocked**: Cannot proceed due to dependencies/issues
|
|
- ⚠️ **At Risk**: May not complete on time
|
|
|
|
## Task Dependencies Graph
|
|
|
|
```
|
|
API-001 → API-002 → FORMAT-001 → UI-001 → LAUNCH-001 → SETTINGS-001 → CLEANUP-001
|
|
↓ ↓ ↓ ↓ ↓ ↓
|
|
FORMAT-002 → UI-002 → LAUNCH-002 → SETTINGS-002 → CLEANUP-002 → CLEANUP-003
|
|
↓ ↓ ↓ ↓ ↓ ↓
|
|
TEST-001 ────────────────────────────────────────────────────────→ TEST-002
|
|
```
|
|
|
|
## Risk Mitigation
|
|
|
|
### High-Risk Tasks
|
|
- **API-001/002**: Critical path, affects all video playback
|
|
- **FORMAT-001**: Core logic change, widespread impact
|
|
- **LAUNCH-001**: Platform compatibility complexity
|
|
|
|
### Mitigation Strategies
|
|
- Feature flags for gradual rollout
|
|
- Comprehensive testing before deployment
|
|
- Rollback plan documented
|
|
- Stakeholder communication plan
|
|
|
|
## Success Metrics
|
|
|
|
### Quantitative
|
|
- Zero server CPU usage for video playback
|
|
- Player launch time < 2 seconds
|
|
- 100% format support via local players
|
|
- 90%+ user satisfaction with new approach
|
|
|
|
### Qualitative
|
|
- Seamless user experience
|
|
- Clear error messages and guidance
|
|
- Intuitive settings interface
|
|
- Comprehensive documentation |