TS File Merge Tutorial: 4 FFmpeg concat Methods Compared
Merging TS (MPEG Transport Stream) files is a common task when working with HLS streams, recorded TV broadcasts, or video fragments from download tools. FFmpeg offers multiple ways to merge them, each with different trade-offs. This guide compares 4 methods and explains when to use each.
What are TS files?
TS (Transport Stream) is a container format designed for transmitting video over unreliable networks (broadcast, streaming). It's used in:
- HLS streaming: M3U8 playlists reference TS segments
- DVB broadcast: Digital TV uses TS format
- Blu-ray discs: M2TS is a variant of TS
- Video recording: Some cameras record in TS
TS files are robust against packet loss but inefficient for storage. Converting to MP4 is common for archival and playback.
Method 1: FFmpeg concat demuxer (recommended for same parameters)
This is the fastest method when all TS files have identical codec, resolution, frame rate, and sample rate.
Step 1: Create file list
Create a text file filelist.txt:
file 'segment1.ts'
file 'segment2.ts'
file 'segment3.ts'
file 'segment4.ts'Important: Use single quotes around filenames and forward slashes for paths (even on Windows).
Step 2: Merge with stream copy
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4-f concat: Use concat demuxer-safe 0: Allow absolute paths in file list-i filelist.txt: Input file list-c copy: Stream copy (no re-encoding, lossless, fast)output.mp4: Output file
This method runs in seconds even for large files because it just copies and concatenates streams.
Generate file list automatically
# Linux/macOS
for f in *.ts; do echo "file '$f'" >> filelist.txt; done
# Windows PowerShell
Get-ChildItem *.ts | ForEach-Object { "file '$_'" } | Out-File filelist.txt -Encoding ASCIIMethod 2: FFmpeg concat protocol
The concat protocol works at the byte level, suitable for formats that support concatenation (like TS):
# Linux/macOS
ffmpeg -i "concat:segment1.ts|segment2.ts|segment3.ts" -c copy output.mp4
# Windows (different syntax)
ffmpeg -i "concat:segment1.ts|segment2.ts|segment3.ts" -c copy output.mp4Limitations:
- Only works with formats that natively support concatenation (TS, MPG)
- Doesn't work with MP4 (needs special handling)
- Less reliable than concat demuxer for complex cases
Method 3: FFmpeg concat filter (for different parameters)
When TS files have different codecs, resolutions, or frame rates, use the concat filter with re-encoding:
ffmpeg -i segment1.ts -i segment2.ts -i segment3.ts \
-filter_complex "[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" \
-c:v libx264 -crf 23 -c:a aac \
output.mp4-i segment1.ts -i segment2.ts -i segment3.ts: Multiple inputs[0:v][0:a][1:v][1:a][2:v][2:a]: Input streams (video and audio from each input)concat=n=3:v=1:a=1: Concatenate 3 inputs, with video and audio[v][a]: Output labels-c:v libx264 -crf 23 -c:a aac: Re-encode to H.264/AAC
Normalize resolution before concat
If segments have different resolutions, scale them first:
ffmpeg -i segment1.ts -i segment2.ts \
-filter_complex "[0:v]scale=1920:1080[v0];[1:v]scale=1920:1080[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[v][a]" \
-map "[v]" -map "[a]" \
-c:v libx264 -crf 23 -c:a aac \
output.mp4Method 4: Online tools
For users who don't want to install FFmpeg, online tools offer browser-based merging:
Pros:
- No installation
- Easy to use
- Works on any device
Cons:
- File size limits
- Upload/download time
- Privacy concerns
Our TS Merge tool uses FFmpeg.wasm to merge TS files entirely in your browser — no uploads, complete privacy.
Comparison of methods
| Method | Speed | Quality | Same parameters required | Re-encodes | Use case |
|---|---|---|---|---|---|
| Concat demuxer | Fastest | Lossless | Yes | No | Same-parameter files |
| Concat protocol | Fast | Lossless | Yes | No | Simple TS merging |
| Concat filter | Slow | Re-encoded | No | Yes | Different parameters |
| Online tools | Medium | Varies | Varies | Varies | No FFmpeg install |
Merge TS from M3U8 playlist
If you have an M3U8 playlist URL, FFmpeg can download and merge automatically:
# Download and merge M3U8 to MP4
ffmpeg -i "https://example.com/stream.m3u8" -c copy output.mp4
# With custom headers (for sites with Referer protection)
ffmpeg -headers "Referer: https://example.com/" -i "https://example.com/stream.m3u8" -c copy output.mp4For details, see our M3U8 to MP4 merge tutorial.
Handle encrypted TS (AES-128)
HLS streams may use AES-128 encryption. If your TS files are encrypted, you need the decryption key:
# FFmpeg can automatically decrypt if key URL is accessible
ffmpeg -i "https://example.com/stream.m3u8" -c copy output.mp4
# Manual decryption of a single segment
openssl aes-128-cbc -d -in segment.ts -out segment_decrypted.ts -K <hex_key> -iv <hex_iv>See our MP4 to M3U8 slicing tutorial for AES-128 encryption details.
Common issues
| Issue | Cause | Solution |
|---|---|---|
| Audio sync drift | Different sample rates | Re-encode with -c:a aac -ar 48000 |
| Timestamp discontinuity | Missing/duplicate timestamps | Add -fflags +genpts |
| Black frames between segments | Different codecs or keyframe issues | Use concat filter with re-encoding |
| Concat demuxer fails | Different parameters | Use concat filter instead |
| Output file won't play | Codec compatibility | Re-encode to H.264/AAC in MP4 |
| Missing audio in one segment | Different audio channel layout | Add -ac 2 to normalize to stereo |
Verify merged output
After merging, verify the output file:
# Check duration
ffprobe -v error -show_entries format=duration -of csv=p=0 output.mp4
# Check streams
ffprobe -v error -show_streams output.mp4
# Play to verify (using ffplay)
ffplay output.mp4Summary
For merging TS files:
- Same parameters: Use concat demuxer with
-c copy(fastest, lossless) - Different parameters: Use concat filter with re-encoding
- M3U8 source: Let FFmpeg download and merge automatically
- No FFmpeg install: Use our browser-based TS Merge tool
Quick reference:
- Lossless merge:
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4 - Re-encode merge:
ffmpeg -i seg1.ts -i seg2.ts -filter_complex "[0:v][0:a][1:v][1:a]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" -c:v libx264 -crf 23 -c:a aac output.mp4 - M3U8 download:
ffmpeg -i "https://example.com/stream.m3u8" -c copy output.mp4
For more FFmpeg commands, see our FFmpeg Getting Started Tutorial.