目录
- 不想装软件?直接用在线工具
- [前置准备:安装 FFmpeg](#前置准备:安装 FFmpeg)
- 方法一:concat协议(无损、最快)
- 方法二:批处理脚本一键合并
- 方法三:Python批量合并多文件夹
- 常见报错与解决
- 小结
零、不想装软件?在线工具直接搞定
如果你现在就有 TS 文件要合并,不想折腾安装配置,可以先试试这个方案。
市面上大多数在线 TS 合并工具都是"上传到服务器→合并→下载",这就带来了两个问题:一是你的视频文件会经过别人的服务器(隐私隐患),二是大文件上传下载慢得让人抓狂。
这里推荐一个不走寻常路的在线工具 ------ ezwebtools TS文件合并 。它用的是 FFmpeg.wasm,把 FFmpeg 编译成 WebAssembly 直接在浏览器里跑,意味着你的文件根本不用上传到服务器,全程在本地浏览器完成。几个核心功能点:
| 功能 | 说明 |
|---|---|
| 本地处理,隐私安全 | 基于 FFmpeg.wasm,文件不上传服务器,所有操作在浏览器本地完成 |
| 加密 TS 解密 | 支持 AES-128 加密的 TS 文件,上传 .key 密钥文件即可自动解密合并 |
| 智能排序 | 自动识别文件名中的数字序列,不会出现 1.ts → 10.ts → 2.ts 的顺序错误 |
| 流复制无损 | 底层走 concat 协议 + -c copy,不重新编码,画质零损失 |
| 手动拖拽调整 | 页面上可以拖拽文件调整顺序,所见即所得 |

局限性也得说清楚:因为跑的是 WebAssembly 而非原生 FFmpeg,处理几个 GB 的大文件时速度不如本地安装版。另外建议用 Chrome / Edge 最新版,老浏览器可能兼容性不好。
结论:几百 MB 的 TS 文件、偶尔用一次、或者遇到加密文件,直接用 ezwebtools 最省心。需要频繁处理大文件的话,接着往下看,把 FFmpeg 装好更划算。
一、前置准备:安装 FFmpeg
TS 文件合并这件事,说到底就是 FFmpeg 的活。不管你用什么 GUI 工具,背后大概率还是调它。所以第一步先装上。
Windows 安装步骤:
- 打开 FFmpeg 官网下载页
- 找到 Windows 区域,选
gyan.dev或者BtbN的链接 - 下载
ffmpeg-release-full.7z,用 7-Zip 解压到C:\ffmpeg - 把
C:\ffmpeg\bin加到系统环境变量 Path 里:

- 打开终端(Win+R →
powershell),输入ffmpeg -version,看到版本信息就说明装好了。
bash
PS C:\Users\Admin> ffmpeg -version
ffmpeg version 6.1.1-full_build-www.gyan.dev Copyright (c) 2000-2023 ...
二、方法一:concat协议合并(无损、最快)
这是最推荐的方法。-c copy 表示流复制,不会重新编码,所以速度极快、画质无损。
步骤1:生成文件列表
先把目录下所有 .ts 文件的文件名写到一个文本文件里:
bash
# Windows PowerShell
Get-ChildItem *.ts | ForEach-Object { "file '$($_.Name)'" } | Out-File -Encoding utf8 filelist.txt -NoNewline
执行完后,当前目录会生成一个 filelist.txt,内容大概长这样:
bash
file 'segment_000.ts'
file 'segment_001.ts'
file 'segment_002.ts'
file 'segment_003.ts'
...
注意 :PowerShell 生成的文件列表默认是按文件名字典序排列的。如果 TS 文件名是
1.ts, 2.ts, ..., 10.ts,字典序会把10.ts排在2.ts前面。如果你是用工具从 M3U8 下载的,建议直接用 M3U8 文件里的顺序来生成列表。这个坑后面会专门讲。
步骤2:执行合并
bash
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mp4
参数解释:
| 参数 | 含义 |
|---|---|
-f concat |
使用 concat demuxer(拼接解复用器) |
-safe 0 |
允许使用绝对路径和特殊字符 |
-i filelist.txt |
指定输入文件列表 |
-c copy |
流复制,不重新编码 |
output.mp4 |
输出文件名 |

什么情况下这个方法会失败?
如果你的 TS 文件编码参数不一致(比如分辨率不同、编码格式不同),concat demuxer 会报错。这种情况改用 concat 滤镜,后面会讲。
三、方法二:批处理脚本一键合并
每次都要手动敲命令太麻烦了。我写了一个现成的 bat 脚本,保存后双击就能用:
bat
@echo off
chcp 65001 >nul
title TS文件合并工具
setlocal enabledelayedexpansion
echo ========================================
echo TS 文件合并工具 v1.0
echo ========================================
echo.
:: 检查 FFmpeg
where ffmpeg >nul 2>&1
if %errorlevel% neq 0 (
echo [错误] 未检测到 FFmpeg,请先安装并配置环境变量!
echo 下载地址: https://ffmpeg.org/download.html
pause
exit /b 1
)
:: 扫描 TS 文件
set count=0
for %%i in (*.ts) do set /a count+=1
if %count%==0 (
echo [提示] 当前目录没有找到 .ts 文件,请把脚本放到 TS 文件目录下运行。
pause
exit /b 1
)
echo [信息] 发现 %count% 个 TS 文件,开始生成列表...
:: 生成文件列表
set listfile=%TEMP%\ts_merge_list_%RANDOM%.txt
(for %%i in (*.ts) do (
echo file '%%~nxi'
)) > "%listfile%"
:: 让用户输入输出文件名
set /p outname="请输入输出文件名(默认 merged.mp4):"
if "!outname!"=="" set outname=merged.mp4
echo.
echo [执行] 开始合并,请勿关闭窗口...
ffmpeg -f concat -safe 0 -i "%listfile%" -c copy "!outname!"
:: 清理临时文件
del "%listfile%" 2>nul
if exist "!outname!" (
echo.
echo ========================================
echo 合并完成!输出文件:!outname!
echo ========================================
) else (
echo.
echo [失败] 合并未成功,请检查上面的错误信息。
)
pause
使用方法:
- 把上面代码复制到记事本,另存为
merge_ts.bat(编码选 ANSI 或 UTF-8 with BOM) - 把
merge_ts.bat丢到你的 TS 文件所在的文件夹 - 双击运行,按提示输入输出文件名(直接回车默认
merged.mp4) - 等待完成
四、方法三:Python 批量合并多文件夹
如果你下载了很多视频,每个都在单独的文件夹里,一个文件夹一个文件夹地跑脚本就太慢了。下面这个 Python 脚本可以一键遍历所有子文件夹,自动合并每个文件夹里的 TS 文件:
python
"""
TS文件批量合并工具
功能:遍历指定目录下的所有子文件夹,自动合并每个文件夹内的 TS 文件
依赖:Python 3.7+, FFmpeg
"""
import os
import re
import subprocess
from pathlib import Path
def natural_sort_key(name: str) -> list:
"""
自然排序:让 1.ts, 2.ts, ..., 10.ts 按数字大小而非字典序排列
"""
return [int(s) if s.isdigit() else s.lower() for s in re.split(r'(\d+)', name)]
def merge_ts_in_folder(folder: str, output_name: str = "merged.mp4") -> bool:
"""
合并单个文件夹内的所有 TS 文件
"""
folder = Path(folder)
ts_files = sorted(
[f.name for f in folder.glob("*.ts")],
key=natural_sort_key
)
if not ts_files:
return False
total = len(ts_files)
print(f"\n[{folder.name}] 发现 {total} 个 TS 文件,开始合并...")
# 写入文件列表
list_file = folder / "_ffmpeg_list.txt"
with open(list_file, "w", encoding="utf-8") as f:
for name in ts_files:
f.write(f"file '{name}'\n")
# 执行 FFmpeg
output_path = folder / output_name
cmd = [
"ffmpeg", "-y",
"-f", "concat", "-safe", "0",
"-i", str(list_file),
"-c", "copy",
str(output_path)
]
result = subprocess.run(cmd, capture_output=True, text=True)
# 清理临时文件
list_file.unlink(missing_ok=True)
if result.returncode != 0:
# 取出最后几行错误信息
err = result.stderr.strip().split("\n")[-3:]
print(f" [失败] {' | '.join(err)}")
return False
size_mb = output_path.stat().st_size / (1024 * 1024)
print(f" [完成] {output_name} ({size_mb:.1f} MB)")
return True
def batch_merge(base_dir: str, recursive: bool = True):
"""
批量合并 base_dir 下所有子文件夹的 TS 文件
"""
base = Path(base_dir)
if not base.exists():
print(f"错误:目录不存在 -> {base_dir}")
return
if recursive:
subdirs = [str(d) for d in base.iterdir() if d.is_dir()]
else:
subdirs = [str(base)]
if not subdirs:
print("未找到子文件夹。")
return
success = 0
fail = 0
skip = 0
for sub in subdirs:
has_ts = any(Path(sub).glob("*.ts"))
if not has_ts:
skip += 1
continue
ok = merge_ts_in_folder(sub)
if ok:
success += 1
else:
fail += 1
print(f"\n{'='*50}")
print(f"处理完毕:成功 {success} / 失败 {fail} / 跳过 {skip}")
print(f"{'='*50}")
if __name__ == "__main__":
# 把这里改成你自己的目录
TARGET_DIR = r"D:\Downloads\videos"
batch_merge(TARGET_DIR, recursive=True)
使用说明:
- 把脚本最后一行
TARGET_DIR改成你的视频下载目录 - 运行前确保 FFmpeg 在 PATH 中
- 默认会递归处理所有子文件夹,不想递归的话把
recursive=True改成False
如果你的 TS 文件是跟着 M3U8 一起下载的,可以直接解析 M3U8 获取文件名和顺序,比用
glob更靠谱。代码就不展开了,需求多的话评论区说一下,我再补一版。
五、常见报错与解决
报错1:Unsafe file name
bash
[concat @ 000001a2b3c4d5e0] Unsafe file name 'C:\videos\segment_000.ts'
filelist.txt: Operation not permitted
原因 :-safe 0 参数没加,或者路径里有特殊字符。
解决 :确保命令里有 -safe 0。如果还不行,把 filelist.txt 里的路径改成相对路径。
报错2:Stream mapping 后直接退出
bash
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Press [q] to stop, [?] for help
[mp4 @ 000001...] Could not find tag for codec none in stream #0
原因:TS 文件的某一路流(通常是数据流或字幕流)无法写入 MP4。
解决:只复制视频和音频流,忽略其他流:
bash
ffmpeg -f concat -safe 0 -i filelist.txt -c copy -map 0:v -map 0:a output.mp4
报错3:合并后视频正常但没声音
原因:MP4 容器不支持源文件的音频编码格式(常见于 AC3、DTS、PCM_bluray)。
解决A(推荐):改用 MKV 容器,兼容性更好:
bash
ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mkv
解决B:音频转码为 AAC,视频保持原样:
bash
ffmpeg -f concat -safe 0 -i filelist.txt -c:v copy -c:a aac -b:a 192k output.mp4
报错4:Packet loss 或 Invalid data found
原因:某个 TS 片段在下载/录制时损坏了。
解决:
- 先找到是哪个文件有问题------打开 filelist.txt,一个一个注释掉,看合并到哪个报错。
- 或者用 FFmpeg 单独测试每个文件:
bash
for %i in (*.ts) do @(ffmpeg -v error -i "%i" -f null - 2>&1 | findstr /i error && echo [损坏] %i)
找到损坏文件后,看体积------如果特别小(几百字节),大概率是空文件,直接删掉;如果体积正常但损坏,用下面命令试着修复:
bash
ffmpeg -i broken.ts -c copy fixed.ts
报错5:文件顺序乱了
现象:合并出来的视频播放到中间跳到别的画面,然后又跳回来。
原因 :PowerShell 的 Sort-Object 或文件系统的默认排序是字典序,1.ts → 10.ts → 100.ts → 2.ts。
解决 :用自然排序重新生成列表。要么用上面 Python 脚本里的 natural_sort_key,要么手动在 filelist.txt 里调整顺序。如果你有 M3U8 索引文件,可以直接从 M3U8 里提取文件顺序。
报错6:音画不同步
现象:合并完后口型和声音对不上,而且越到后面越明显。
原因:源 TS 文件的时间戳(PTS/DTS)有问题,concat 时没有重新生成。
解决 :加 -fflags +genpts 强制正时视频时间戳:
bash
ffmpeg -fflags +genpts -f concat -safe 0 -i filelist.txt -c copy output.mp4
如果还不行,只能走重新编码路线了:
bash
ffmpeg -f concat -safe 0 -i filelist.txt -c:v libx264 -crf 18 -c:a aac -b:a 192k output.mp4
六、什么时候必须重新编码?
以下场景不建议用 -c copy,老老实实走编码路线:
- TS 片段来自不同相机/设备(编码参数不一致)
- 需要剪辑/裁剪/加水印
- 输出格式与源编码不兼容(比如源是 HEVC 但播放器只支持 H.264)
- concat demuxer 死活报错且找不到原因
bash
# 重新编码合并(画质优先)
ffmpeg -f concat -safe 0 -i filelist.txt -c:v libx264 -crf 18 -preset medium -c:a aac -b:a 192k output.mp4
-crf 18:画质优先,数字越小画质越好(0=无损,18=视觉无损,28=平衡)-preset medium:编码速度,fast 快但文件大,slow 文件小但慢
七、小结
| 场景 | 推荐方案 |
|---|---|
| 临时合并几个 TS,文件参数一致 | 方法一(concat 协议 + -c copy) |
| 不想装任何软件,文件不大 | ezwebtools 在线工具(浏览器本地处理,隐私安全) |
| 经常需要合并,想省事 | 方法二(bat 脚本,双击即用) |
| 批量处理几十个文件夹 | 方法三(Python 脚本) |
| 合并后有问题(没声音/不同步) | 查第五章对应报错 |
| 源文件参数不一致 | 重新编码(第六章) |
个人建议:如果你只是偶尔合并几个 TS 文件,文件也不大(几百 MB),直接打开 ezwebtools 的 TS 合并工具,拖进去点合并就完事了,浏览器本地跑 FFmpeg,不经过服务器,画质无损还不用担心隐私问题。
如果需要频繁处理、或者文件太大(几个 GB),花 10 分钟把 FFmpeg 装好,把 -c copy 这条命令记住。看起来是命令行,但比你在网上到处找所谓"合并软件"省的时间多得多------关键是画质一点不丢。
有问题欢迎在评论区留言,我看到都会回。
原创文章,转载请注明出处。欢迎关注,不定期更新实用工具教程。