281 lines
7.9 KiB
Markdown
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. |