16 KiB
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:
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:
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:
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:
// 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:
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:
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:
{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:
// 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:
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>orvlc://<url> - Windows:
start vlc.exe <url>orvlc://<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:
- Protocol handler testing (vlc://, potplayer://)
- Common installation path checking
- User preference storage
- Browser extension integration (future)
Implementation:
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:
<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:
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.tslocal-player-launcher.test.tsplayer-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