208 lines
6.6 KiB
Markdown
208 lines
6.6 KiB
Markdown
# Transcoding Fixes Documentation
|
|
|
|
This document describes the fixes implemented to address two critical issues with the video transcoding functionality in NextAV.
|
|
|
|
## Issues Addressed
|
|
|
|
### 1. FFmpeg Process Not Stopped When Video Viewer Closes
|
|
|
|
**Problem**: When users closed the video viewer, FFmpeg transcoding processes continued running in the background, consuming system resources.
|
|
|
|
**Root Cause**:
|
|
- Inadequate cleanup mechanisms in the transcoding API
|
|
- No global process tracking
|
|
- Unreliable client disconnect detection
|
|
|
|
**Solution**:
|
|
- Implemented a **heartbeat mechanism** for reliable player tracking
|
|
- Created a global `ProcessManager` class to track all FFmpeg processes
|
|
- Added automatic cleanup when heartbeat stops for more than 10 seconds
|
|
- Created a DELETE endpoint for manual process termination
|
|
- Added automatic cleanup of stale processes (older than 10 minutes)
|
|
|
|
### 2. Progress Bar Not Showing Correct Progress for Transcoding Streams
|
|
|
|
**Problem**: The video progress bar showed incorrect progress when playing transcoded streams, even though the duration was correctly retrieved.
|
|
|
|
**Root Cause**:
|
|
- Video player components weren't properly reading the `X-Content-Duration` header
|
|
- Duration wasn't being set correctly for transcoded streams
|
|
- Missing duration display in the UI
|
|
|
|
**Solution**:
|
|
- Enhanced video player components to read duration from response headers
|
|
- Added proper duration handling for both direct and transcoded streams
|
|
- Improved duration display in the UI
|
|
- Added transcoding indicator to show when transcoding is active
|
|
|
|
## Implementation Details
|
|
|
|
### Heartbeat Mechanism (`src/app/api/heartbeat/route.ts`)
|
|
|
|
A reliable system for tracking active video players:
|
|
|
|
```typescript
|
|
// Player sends heartbeat every 5 seconds
|
|
POST /api/heartbeat
|
|
{
|
|
"playerId": "player_1234567890_abc123",
|
|
"videoId": 53
|
|
}
|
|
|
|
// Player notifies disconnect
|
|
DELETE /api/heartbeat
|
|
{
|
|
"playerId": "player_1234567890_abc123"
|
|
}
|
|
|
|
// Check active players
|
|
GET /api/heartbeat
|
|
```
|
|
|
|
**Key Features**:
|
|
- **10-second timeout**: If no heartbeat for 10 seconds, FFmpeg processes are cleaned up
|
|
- **Automatic cleanup**: Background process checks every 5 seconds for stale heartbeats
|
|
- **Player tracking**: Each player has a unique ID for reliable tracking
|
|
- **Video association**: Heartbeats are linked to specific video IDs for targeted cleanup
|
|
|
|
### Process Manager (`src/lib/process-manager.ts`)
|
|
|
|
A global singleton class that manages all FFmpeg processes:
|
|
|
|
```typescript
|
|
class ProcessManager {
|
|
// Register a new FFmpeg process
|
|
register(processId: string, process: any, videoId: string, cleanup: () => void)
|
|
|
|
// Remove a specific process
|
|
remove(processId: string)
|
|
|
|
// Remove all processes for a specific video
|
|
removeByVideoId(videoId: string)
|
|
|
|
// Get all active processes
|
|
getAllProcesses()
|
|
}
|
|
```
|
|
|
|
### Enhanced Transcoding API (`src/app/api/stream/[id]/transcode/route.ts`)
|
|
|
|
Key improvements:
|
|
- Uses `ProcessManager` for process tracking
|
|
- Simplified cleanup (now handled by heartbeat)
|
|
- Proper duration header handling
|
|
- DELETE endpoint for manual cleanup
|
|
|
|
### Updated Video Player Components
|
|
|
|
Both `InlineVideoPlayer` and `VideoViewer` components now:
|
|
- **Send heartbeats**: Every 5 seconds while player is open
|
|
- **Notify disconnect**: When player closes or component unmounts
|
|
- **Track transcoding state**: Show transcoding indicators
|
|
- **Read duration from headers**: Proper progress bar support
|
|
- **Display duration information**: Show video duration in UI
|
|
|
|
## API Endpoints
|
|
|
|
### Heartbeat Management
|
|
- `POST /api/heartbeat` - Send player heartbeat
|
|
- `DELETE /api/heartbeat` - Notify player disconnect
|
|
- `GET /api/heartbeat` - Get status of all active players
|
|
|
|
### Process Management
|
|
- `GET /api/processes` - Get status of all active processes
|
|
- `DELETE /api/processes` - Cleanup all processes
|
|
- `DELETE /api/processes?videoId=123` - Cleanup processes for specific video
|
|
|
|
### Transcoding
|
|
- `GET /api/stream/{id}/transcode` - Start transcoding stream
|
|
- `DELETE /api/stream/{id}/transcode` - Stop transcoding for video
|
|
|
|
## Testing
|
|
|
|
### Test Heartbeat Mechanism
|
|
```bash
|
|
node test-heartbeat.mjs
|
|
```
|
|
|
|
### Test Transcoding Fixes
|
|
```bash
|
|
node test-transcoding-fixes.mjs
|
|
```
|
|
|
|
## Monitoring
|
|
|
|
### Check Active Players
|
|
```bash
|
|
curl http://localhost:3000/api/heartbeat
|
|
```
|
|
|
|
### Check Active Processes
|
|
```bash
|
|
curl http://localhost:3000/api/processes
|
|
```
|
|
|
|
### Cleanup Specific Video
|
|
```bash
|
|
curl -X DELETE "http://localhost:3000/api/processes?videoId=53"
|
|
```
|
|
|
|
### Cleanup All Processes
|
|
```bash
|
|
curl -X DELETE http://localhost:3000/api/processes
|
|
```
|
|
|
|
## Logs
|
|
|
|
The system now provides detailed logging:
|
|
|
|
```
|
|
[HEARTBEAT] Player player_1234567890_abc123 for video 53 pinged
|
|
[PROCESS_MANAGER] Registered process: transcode_53_1234567890 for video: 53
|
|
[HEARTBEAT] Player player_1234567890_abc123 for video 53 timed out, cleaning up FFmpeg processes
|
|
[PROCESS_MANAGER] Removed process: transcode_53_1234567890
|
|
```
|
|
|
|
## How It Works
|
|
|
|
### 1. Player Opens
|
|
1. Video player generates unique `playerId`
|
|
2. Starts sending heartbeats every 5 seconds to `/api/heartbeat`
|
|
3. Backend tracks the player and associates it with the video ID
|
|
|
|
### 2. Transcoding Starts
|
|
1. When transcoding is needed, FFmpeg process is started
|
|
2. Process is registered with `ProcessManager` using the video ID
|
|
3. Player continues sending heartbeats while transcoding
|
|
|
|
### 3. Player Closes
|
|
1. Player stops sending heartbeats
|
|
2. After 10 seconds without heartbeat, backend automatically:
|
|
- Removes player from active list
|
|
- Cleans up all FFmpeg processes for that video ID
|
|
3. Alternatively, player can explicitly notify disconnect via DELETE request
|
|
|
|
### 4. Automatic Cleanup
|
|
- Background process runs every 5 seconds
|
|
- Checks for heartbeats older than 10 seconds
|
|
- Automatically cleans up associated FFmpeg processes
|
|
- Prevents resource leaks from crashed or closed players
|
|
|
|
## Benefits
|
|
|
|
1. **Reliable Cleanup**: Heartbeat mechanism ensures FFmpeg processes are always cleaned up
|
|
2. **Resource Efficiency**: No more orphaned processes consuming system resources
|
|
3. **Better UX**: Accurate progress bars and visual feedback
|
|
4. **Monitoring**: Admin tools to track active players and processes
|
|
5. **Transparency**: Users can see when transcoding is active
|
|
6. **Fault Tolerance**: Handles browser crashes, network issues, and unexpected closures
|
|
|
|
## Future Improvements
|
|
|
|
1. **Progress Tracking**: Real-time transcoding progress updates via heartbeat
|
|
2. **Quality Selection**: User-selectable transcoding quality
|
|
3. **Caching**: Cache transcoded videos to avoid re-transcoding
|
|
4. **Queue Management**: Handle multiple concurrent transcoding requests
|
|
5. **Error Recovery**: Automatic retry mechanisms for failed transcoding
|
|
6. **Heartbeat Optimization**: Reduce heartbeat frequency for better performance
|