TS 檔案合併教學:4 種 FFmpeg concat 方法比較
下載 HLS 串流得到的 TS 片段,需要合併成一個檔案。多個影片片段要連接成一個檔案。FFmpeg 提供 4 種 concat 方法,各有適用場景。這篇詳細比較這 4 種方法,幫你選擇適合的。
為什麼要合併 TS 檔案
- HLS 下載後合併: M3U8 串流由多個 TS 片段組成,需要合併成單一 MP4
- 攝影機片段整合: 長時間錄影分成多個檔案儲存
- 剪輯片段連接: 多段素材要連接成一個完整影片
- 直播錄製整合: 直播分段錄製要合併
4 種 FFmpeg concat 方法
方法 1:concat demuxer(推薦)
適用場景: 相同編碼器和參數的檔案
優點: 無損、最快、低資源使用
缺點: 所有檔案需要相同參數
使用方式
- 建立檔案清單
list.txt:
file 'segment1.ts'
file 'segment2.ts'
file 'segment3.ts'- 執行 FFmpeg:
bash
# 輸出 TS
ffmpeg -f concat -safe 0 -i list.txt -c copy output.ts
# 輸出 MP4
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4參數說明
-f concat:使用 concat demuxer-safe 0:允許絕對路徑-i list.txt:檔案清單-c copy:串流複製(無損)
自動生成清單
bash
# Linux/macOS
for f in *.ts; do echo "file '$f'" >> list.txt; done
# Windows PowerShell
Get-ChildItem *.ts | ForEach-Object { Add-Content list.txt "file '$($_.Name)'" }方法 2:concat protocol
適用場景: MPEG-TS 檔案直接合併
優點: 簡單
缺點: 只適用於 MPEG-TS,可能有相容性問題
使用方式
bash
# TS 檔案合併
ffmpeg -i "concat:segment1.ts|segment2.ts|segment3.ts" -c copy output.ts
# 輸出 MP4
ffmpeg -i "concat:segment1.ts|segment2.ts|segment3.ts" -c copy -bsf:a aac_adtstoasc output.mp4注意: 只有 MPEG-TS 容器支援 concat protocol。MP4、MKV 等不支援。
方法 3:concat filter
適用場景: 不同編碼器或參數的檔案
優點: 支援不同參數
缺點: 重新編碼(有損)、慢
使用方式
bash
# 2 個檔案合併
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4
# 3 個檔案合併
ffmpeg -i input1.mp4 -i input2.mp4 -i input3.mp4 -filter_complex \
"[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4參數說明
n=2:合併檔案數v=1:輸出視訊串流a=1:輸出音訊串流[0:v:0][0:a:0]:第一個輸入的視訊和音訊
不同解析度合併
bash
# 統一解析度後合併
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v]scale=1280:720[v0];[1:v]scale=1280:720[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4方法 4:中間檔案方法
適用場景: 不同容器但相同編碼器
優點: 支援不同容器
缺點: 需要額外儲存空間
使用方式
bash
# 步驟 1:MP4 轉 TS
ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb temp1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb temp2.ts
# 步驟 2:用 concat protocol 合併
ffmpeg -i "concat:temp1.ts|temp2.ts" -c copy -bsf:a aac_adtstoasc output.mp4
# 步驟 3:刪除中間檔案
rm temp1.ts temp2.ts方法比較
| 方法 | 速度 | 無損 | 支援不同參數 | 使用場景 |
|---|---|---|---|---|
| concat demuxer | 最快 | ✓ | ✗ | 相同參數 |
| concat protocol | 快 | ✓ | ✗ | TS 檔案 |
| concat filter | 慢 | ✗(重新編碼) | ✓ | 不同參數 |
| 中間檔案 | 中 | ✓ | ✗ | 不同容器 |
HLS 下載後 TS 合併
從 HLS 串流下載的 TS 片段合併:
bash
# 1. 下載 M3U8 列出的所有 TS 片段
ffmpeg -i "https://example.com/stream.m3u8" -c copy -bsf:a aac_adtstoasc output.mp4
# 2. 已經有 TS 檔案時用 concat demuxer 合併
for f in segment*.ts; do echo "file '$f'" >> list.txt; done
ffmpeg -f concat -safe 0 -i list.txt -c copy -bsf:a aac_adtstoasc output.mp4-bsf:a aac_adtstoasc 把 AAC 從 ADTS 格式轉成 MP4 容器格式。
詳見 MP4 轉 M3U8 教學。
常見問題
1. 合併後播放卡頓
原因: 時間戳衝突
解決方案:
bash
# 重新生成時間戳
ffmpeg -f concat -safe 0 -i list.txt -c copy -fflags +genpts output.mp42. 音訊不同步
原因: 音訊串流起始時間不同
解決方案:
bash
# 重置時間戳
ffmpeg -f concat -safe 0 -i list.txt -c copy -copyts -output_ts_offset 0 output.mp43. 部分檔案無法合併
原因: 編碼器或參數不同
解決方案: 用 concat filter 重新編碼
4. 合併後檔案巨大
原因: 串流複製保留原始位元率
解決方案: 合併後重新壓縮
bash
ffmpeg -f concat -safe 0 -i list.txt -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4進階技巧
1. 跳過損壞片段
bash
# 跳過損壞部分繼續處理
ffmpeg -f concat -safe 0 -i list.txt -c copy -err_detect ignore_err output.mp42. 部分合併
bash
# 只合併前 5 個檔案
head -5 list.txt > list-short.txt
ffmpeg -f concat -safe 0 -i list-short.txt -c copy output.mp43. 同時合併和轉換
bash
# 合併並轉成 H.265
ffmpeg -f concat -safe 0 -i list.txt -c:v libx265 -crf 28 -c:a aac -b:a 128k output.mp44. 加上過場效果
bash
# 場景間加 1 秒黑畫面
ffmpeg -i input1.mp4 -i input2.mp4 -filter_complex \
"[0:v]format=yuv420p[v0];[1:v]format=yuv420p[v1];[v0][0:a][v1][1:a]concat=n=2:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4各場景範本
HLS 下載 TS 合併
bash
# 直接下載並合併
ffmpeg -i "https://example.com/stream.m3u8" -c copy -bsf:a aac_adtstoasc output.mp4攝影機片段合併
bash
# 生成清單
for f in CAM*.ts; do echo "file '$f'" >> list.txt; done
# 無損合併
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4不同解析度片段合併
bash
# 統一解析度後合併
ffmpeg -i input1.mp4 -i input2.mp4 -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[outv][outa]" \
-map "[outv]" -map "[outa]" -c:v libx264 -crf 23 -c:a aac output.mp4總結
TS 檔案合併方法選擇:
- 相同參數: concat demuxer(推薦)
- TS 檔案: concat protocol
- 不同參數: concat filter
- 不同容器: 中間檔案方法
快速參考:
- 推薦方法:
ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4 - 不同參數: 用 concat filter
- HLS 下載:
ffmpeg -i stream.m3u8 -c copy output.mp4 - TS→MP4: 加
-bsf:a aac_adtstoasc