欢迎光临
我们一直在努力

ffmpeg 合并 TS 文件完整教程(附批量脚本+常见报错解决)


目录

  • 不想装软件?直接用在线工具
  • 前置准备:安装 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,不重新编码,画质零损失
    手动拖拽调整 页面上可以拖拽文件调整顺序,所见即所得

    TS文件合并

    局限性也得说清楚:因为跑的是 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 里:
  • ffmpeg环境变量添加

  • 打开终端(Win+R → powershell),输入 ffmpeg -version,看到版本信息就说明装好了。
  • 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 文件的文件名写到一个文本文件里:

    # Windows PowerShell
    Get-ChildItem *.ts | ForEach-Object { "file '$($_.Name)'" } | Out-File -Encoding utf8 filelist.txt -NoNewline

    执行完后,当前目录会生成一个 filelist.txt,内容大概长这样:

    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:执行合并

    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 输出文件名

    FFmpeg运行截图

    什么情况下这个方法会失败?

    如果你的 TS 文件编码参数不一致(比如分辨率不同、编码格式不同),concat demuxer 会报错。这种情况改用 concat 滤镜,后面会讲。


    三、方法二:批处理脚本一键合并

    每次都要手动敲命令太麻烦了。我写了一个现成的 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 文件:

    """
    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

    [concat @ 000001a2b3c4d5e0] Unsafe file name 'C:\\videos\\segment_000.ts'
    filelist.txt: Operation not permitted

    原因:-safe 0 参数没加,或者路径里有特殊字符。

    解决:确保命令里有 -safe 0。如果还不行,把 filelist.txt 里的路径改成相对路径。


    报错2:Stream mapping 后直接退出

    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。

    解决:只复制视频和音频流,忽略其他流:

    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 容器,兼容性更好:

    ffmpeg -f concat -safe 0 -i filelist.txt -c copy output.mkv

    解决B:音频转码为 AAC,视频保持原样:

    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 单独测试每个文件:
  • for %i in (*.ts) do @(ffmpeg -v error -i "%i" -f null – 2>&1 | findstr /i error && echo [损坏] %i)

    找到损坏文件后,看体积——如果特别小(几百字节),大概率是空文件,直接删掉;如果体积正常但损坏,用下面命令试着修复:

    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 强制正时视频时间戳:

    ffmpeg -fflags +genpts -f concat -safe 0 -i filelist.txt -c copy output.mp4

    如果还不行,只能走重新编码路线了:

    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 死活报错且找不到原因

    # 重新编码合并(画质优先)
    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 这条命令记住。看起来是命令行,但比你在网上到处找所谓"合并软件"省的时间多得多——关键是画质一点不丢。

    有问题欢迎在评论区留言,我看到都会回。


    原创文章,转载请注明出处。欢迎关注,不定期更新实用工具教程。

    赞(0)
    未经允许不得转载:171主机测评 » ffmpeg 合并 TS 文件完整教程(附批量脚本+常见报错解决)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址