# 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.