nextav/docs/TS_FILE_HANDLING_GUIDE.md

281 lines
7.9 KiB
Markdown

# MPEG Transport Stream (.ts) File Handling Guide
## Overview
MPEG Transport Stream (.ts) files are a common video container format that present unique opportunities for efficient web streaming. This guide explains the characteristics of .ts files and optimal handling strategies.
## Understanding .ts Files
### What are .ts files?
**.ts files are MPEG Transport Stream containers** that:
1. **Contain already-encoded video and audio streams** - typically H.264 video and AAC audio
2. **Are designed for streaming and broadcast** - specifically created for reliable transmission over networks
3. **Are the native format used by HLS (HTTP Live Streaming)** - HLS breaks videos into .ts segments
4. **Can be "converted" instantly** using container remuxing (no re-encoding needed)
### Why .ts files from streaming sites work well
Downloaded .ts files from video streaming sites (like the ones you mentioned) are particularly suitable because:
- They already contain **web-compatible codecs** (H.264/AAC)
- They're **optimized for streaming** (proper keyframe intervals, constant bitrates)
- They're **single-segment streams** (entire video in one .ts file)
- They have **proper metadata** for duration and seeking
## Technical Characteristics
### Container vs. Codec
```
┌─────────────────┐ ┌──────────────────┐
│ .ts Container │ │ .mp4 Container │
├─────────────────┤ ├──────────────────┤
│ H.264 Video ────┼────┼──► H.264 Video │
│ AAC Audio ────┼────┼──► AAC Audio │
└─────────────────┘ └──────────────────┘
Same codecs, different container
```
### Browser Compatibility
| Format | Chrome | Firefox | Safari | Edge | Notes |
|--------|--------|---------|---------|------|-------|
| .ts direct | ❌ | ❌ | ❌ | ❌ | Browsers don't support .ts containers |
| .ts via HLS | ✅ | ✅ | ✅ | ✅ | With hls.js library |
| .mp4 (converted) | ✅ | ✅ | ✅ | ✅ | Native browser support |
## Implementation Strategies
### Strategy 1: HLS Streaming (Recommended)
**Best for**: Downloaded .ts files from streaming sites
```typescript
// Current implementation in video-format-detector.ts
if (TS_STREAM_FORMATS.includes(extension)) {
return createTSHLSFormat(video, extension);
}
```
**Advantages**:
- ✅ Works with all browsers (via hls.js)
- ✅ No conversion needed
- ✅ Proper seeking and buffering
- ✅ Leverages existing HLS infrastructure
**How it works**:
1. Generate M3U8 playlist pointing to the .ts file as a single segment
2. Serve the entire .ts file when segment 0 is requested
3. Browser uses hls.js to handle the stream
### Strategy 2: Container Conversion
**Best for**: Maximum browser compatibility
```bash
# Fast container remuxing (seconds, not minutes)
ffmpeg -i input.ts -c copy -movflags +faststart output.mp4
```
**Advantages**:
- ✅ Native browser support (no JavaScript libraries needed)
- ✅ Maximum compatibility
- ✅ Optimized for web (faststart flag)
- ✅ Very fast (container remuxing only)
**API Usage**:
```javascript
// Convert .ts to .mp4
POST /api/videos/{id}/convert-ts
{
"fastStart": true,
"deleteOriginal": false
}
```
### Strategy 3: Direct Streaming
**Best for**: External players
```typescript
// Serve .ts file directly with proper MIME type
headers: {
'Content-Type': 'video/mp2t',
'Accept-Ranges': 'bytes'
}
```
**Advantages**:
- ✅ No processing needed
- ✅ Works with VLC, MPV, etc.
- ✅ Full range request support
## Current Implementation
### Format Detection
```typescript
// src/lib/video-format-detector.ts
const TS_STREAM_FORMATS = ['ts', 'm2ts', 'mts'];
if (TS_STREAM_FORMATS.includes(extension)) {
return createTSHLSFormat(video, extension); // Default to HLS
}
```
### HLS Playlist Generation
```typescript
// src/app/api/stream/hls/[id]/playlist.m3u8/route.ts
function generateTSFilePlaylist(video: any, videoId: number): Response {
const playlist = [
'#EXTM3U',
'#EXT-X-VERSION:3',
`#EXT-X-TARGETDURATION:${Math.ceil(duration)}`,
'#EXT-X-MEDIA-SEQUENCE:0',
`#EXTINF:${duration.toFixed(3)},`,
'../segment/0.ts',
'#EXT-X-ENDLIST'
].join('\n');
}
```
### Segment Serving
```typescript
// src/app/api/stream/hls/[id]/segment/[segment]/route.ts
if (fileExtension === '.ts' && segmentIndex === 0) {
// Serve entire .ts file as segment 0
const file = fs.createReadStream(videoPath);
return new Response(file, {
headers: {
'Content-Type': 'video/mp2t',
'Accept-Ranges': 'bytes'
}
});
}
```
## Testing and Validation
### Test Suite
Run the comprehensive test suite:
```bash
node test-ts-streaming.mjs
```
**Tests include**:
1. Format detection
2. HLS playlist generation
3. Segment serving
4. Direct streaming
5. External streaming
6. Conversion status
7. Media access information
### Manual Testing
1. **Browser HLS Test**:
```javascript
// In browser console with hls.js loaded
const hls = new Hls();
hls.loadSource('/api/stream/hls/109/playlist.m3u8');
hls.attachMedia(video);
```
2. **VLC Direct Test**:
```bash
vlc http://localhost:3000/api/external-stream/109
```
3. **Container Conversion Test**:
```bash
curl -X POST http://localhost:3000/api/videos/109/convert-ts
```
## Performance Comparison
| Method | Conversion Time | Browser Support | Quality | Seeking |
|--------|----------------|-----------------|---------|---------|
| HLS Streaming | 0s (instant) | ✅ (with hls.js) | Original | ✅ |
| Container Conversion | ~5-10s | ✅ (native) | Original | ✅ |
| Direct Streaming | 0s (instant) | ❌ (browsers) | Original | ✅ (VLC) |
## Troubleshooting
### Common Issues
1. **"Video cannot be played"**
- Check if hls.js is loaded
- Verify M3U8 playlist is valid
- Test segment URLs directly
2. **"Seeking not working"**
- Ensure Accept-Ranges header is set
- Check if duration metadata is available
- Verify keyframe intervals in source
3. **"Slow loading"**
- Check if faststart flag is used for MP4
- Verify server supports range requests
- Monitor network requests in dev tools
### Debug Commands
```bash
# Check .ts file codec information
ffprobe -v quiet -print_format json -show_streams input.ts
# Verify HLS playlist
curl http://localhost:3000/api/stream/hls/109/playlist.m3u8
# Test segment serving
curl -I http://localhost:3000/api/stream/hls/109/segment/0.ts
```
## Recommendations
### For Downloaded .ts Files
1. **Primary**: Use HLS streaming (current implementation)
2. **Fallback**: Container conversion to .mp4
3. **External**: Direct streaming for VLC/MPV
### For Production
1. **Batch convert** popular .ts files to .mp4 during off-peak hours
2. **Serve via CDN** for better performance
3. **Monitor** conversion success rates and user preferences
4. **Cache** M3U8 playlists for better response times
### Browser Integration
```javascript
// Recommended ArtPlayer setup for .ts files
if (format.type === 'hls') {
if (Hls.isSupported()) {
const hls = new Hls({
enableWorker: false,
lowLatencyMode: false,
backBufferLength: 90
});
hls.loadSource(format.url);
hls.attachMedia(art.video);
}
}
```
## Conclusion
Your observation about VLC's instant "conversion" is spot-on - it's **container remuxing, not re-encoding**. The .ts files you have likely contain web-compatible H.264/AAC streams that just need the right serving strategy.
**The optimal approach is**:
1. **HLS streaming** for immediate playback (already implemented)
2. **Container conversion** for maximum compatibility (API available)
3. **Direct streaming** for external players (already working)
This gives users the best of all worlds while leveraging the fact that .ts files from streaming sites are already optimized for web delivery.