TS视频合并工具:HTML生成bat脚本一键无损合并MP4
简介面向需要合并数字序号型 ts 视频的用户一份零门槛的本地合并工具包。针对 0.ts、1.ts、2.ts 这类非加密分段文件只需用浏览器打开 HTML 工具输入最大序号例如 88生成批处理脚本后放入视频文件夹双击即可输出合并后的 MP4免去手动敲命令的麻烦。压缩包共 5 个文件包含 HTML 主工具、bat 默认合并脚本、两个 WMV 视频操作教程和一个 txt 使用手册整体仅 1.54MB适配普通电脑环境。已有 2631 人学习/下载适合下载了分段视频却不懂 ffmpeg 命令的普通用户以及希望批量处理此类 ts 合并任务的轻度技术爱好者。资源自带录屏讲解和文字说明照着操作即可完成合并工具脚本也可作为简易视频批处理参考。1. TS 视频合并工具从 HTML 生成器到 bat 的一键链路做音视频的人手里多少都攒过一堆 0.ts、1.ts、2.ts 这种分段文件浏览器缓存、录屏工具、课程平台切片都会吐出这种按编号排列的 TS 小视频。单个能播想整段保存、上传就麻烦。这个 ts 视频合并工具解决的就是这个具体问题用浏览器打开工具里的 HTML 页面输入最后一个文件的编号——比如文件夹里最大的是 88.ts就填 88——点生成得到 mergFileDefault.bat把它复制进视频文件夹双击几十秒后同目录就多出一个 output.mp4。它本质上是把 ffmpeg 合并命令封装成填数字→出脚本的轻量源码软件适合不想装全家桶、只想本地快速收拾分段视频的从业者和爱折腾的人。2. 合并原理为什么 0.ts 到 88.ts 能无损拼成一个 MP42.1 TS 是流MP4 是容器选型理由先说清楚要理解这个工具为什么敢让一个 bat 去拼几十个文件得先分清 TS 和 MP4 的底子。MPEG-TSTransport Stream是传输流诞生目的是广播电视和流媒体推送数据被切成 188 字节的小包每段 .ts 文件里都自带 PAT/PMT 节目表和时间戳信息可以独立解码播放。这意味着多个编号连续的 .ts 本质上是可以按顺序排着队喂给解码器的拼接本身不需要重新压缩。MP4 是另一回事它是典型的文件容器靠 ftyp、moov、mdat 这些 box 组织内容索引表在文件头或文件尾播放器先读索引再定位数据。所以把两个 MP4 的二进制直接拼在一起这种操作在 MP4 上行不通这也是市面上很多视频合并工具要重新编码一遍、慢且损耗画质的原因。这个工具选 TS 做输入、MP4 做输出方向是对的输入是多段可直拼的传输流输出是通用性最好的播放容器。合并过程本质是解封装 TS → 重新封装 MP4视频和音频的数据帧原样搬运也就是常说的流复制stream copy。速度接近磁盘拷贝一段几百 MB 的课程分片几十秒就能完成画质无损。这里补一句正因为是流复制所以对源文件要求苛刻——所有 .ts 的编码参数必须一致。分辨率、帧率、音频采样率里只要有一个不齐流复制出来的 MP4 就可能时长错位或者播放到一半断电。工具文件名里非加密三个字也是同一个道理后面第 4 章专门说这块。2.2 两种 concat 方式协议concat protocol与 demuxerconcat demuxerffmpeg 合并 TS 有两条主流路线先分清再动手不然抄命令都会翻车。第一条是 concat 协议命令长这样ffmpeg -i concat:0.ts|1.ts|2.ts|...|88.ts -c copy output.mp4思路是把所有文件名用竖线串成一个伪输入。好处是不用生成中间清单文件段数少的时候随手就能写缺点也明显文件名里一旦有空格、单引号或者中文竖线拼接的解析就会出乱子Windows 下路径带着盘符和反斜杠时这套字符串解析更容易踩坑我一般只在临时测试三四段的时候用它。第二条是 concat demuxer也就是工具最可能走的路线ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4它要求先有一个 list.txt每一行写一个输入文件格式是file 文件名。ffmpeg 按清单顺序逐个读取支持相对路径、支持不同目录、支持带空格的文件名容错能力比协议强不少。对 0.ts 到 88.ts 这种几十段的场景这条路是正解。两种方式的差异用一张表记一下方便以后直接查方式命令形态适用场景主要坑concat 协议-i concat:0.ts|1.ts段数少、文件名干净空格/中文/盘符解析易错concat demuxer-f concat -safe 0 -i list.txt段数多、路径复杂需要先维护 list.txt2.3 最小合并命令逐参数拆解工具生成的 bat 把两步做进了同一个脚本先生成 list.txt再调 ffmpeg 合并。最简形态是这样的(for /L %%i in (0,1,88) do echo file %%i.ts) list.txt ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4逐行拆开看。for /L %%i in (0,1,88)是 cmd 的步进循环三个数字分别表示起始值、步长、终止值这里是 0 到 88 逐个取注意在 .bat 文件里循环变量必须写成双百分号%%i如果直接在 cmd 窗口手敲则要用单百分号%i这是新手最容易抄错的地方。echo file %%i.ts负责输出类似file 0.ts的清单行前后单引号是 concat demuxer 的语法要求不能省。整个括号块的输出通过重定向写入 list.txt注意是覆盖写重复执行不会残留旧内容。第二行是真正的合并命令。-f concat强制让 ffmpeg 用 concat demuxer 去解析输入-safe 0放开安全限制允许清单里出现相对路径和某些特殊路径写法不写这个参数时相对路径没问题但路径稍微复杂就容易被拦-i list.txt指定清单文件是输入-c copy告诉 ffmpeg 所有流直接复制、不要重新编码这是速度和无损的关键最后的 output.mp4 是输出文件名实际输出名以你手上那个 bat 为准工具包不同版本可能会有差异。实操层面的两个前提。第一这段命令假设 ffmpeg 已经在系统 PATH 里否则要把ffmpeg换成完整路径比如C:\tools\ffmpeg\bin\ffmpeg.exe工具手册里一般会写清楚它默认调用的是哪个 ffmpeg。第二list.txt 是中间产物合完就可以删工具的 bat 结尾通常有del list.txt自动清理。真正到双击执行的细节下一章接上。3. 完整操作流程输入尾号、生成 bat、双击合并的三步实操3.1 HTML 生成端为什么只让你填一个数字工具的使用入口是视频合并工具.html打开后界面极简一个输入框、一个生成按钮旁边的手册和教程视频把操作讲得很细。页面只让你填一个数字——最后一个文件的编号而不是文件名列表背后是有逻辑的工具的适用域就是 0.ts、1.ts、2.ts 这种从 0 开始的连续编号序列知道了终点起点和步长就都定死了一个数字就能唯一确定整个清单。填 88生成的就是覆盖 0.ts 到 88.ts 的 bat 脚本。这个 HTML 本质上是最轻量的一类源码软件逻辑全在浏览器本地 JS 里不联网、不上传、不依赖任何服务端。常见实现是这样拿到输入数字做合法性校验然后把 bat 文本按行拼好再通过 Blob 触发下载文件名就叫 mergFileDefault.bat。核心代码逻辑大概是function generateBat(){ const last document.getElementById(lastNum).value.trim(); if (!/^\d$/.test(last)) { alert(只需输入最后一个文件的数字编号例如 88); return; } const lines [ echo off, chcp 65001 nul, (for /L %%i in (0,1,${last}) do echo file %%i.ts) list.txt, ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4, del list.txt, pause ]; const blob new Blob([lines.join(\r\n)], {type: application/x-bat}); const a document.createElement(a); a.href URL.createObjectURL(blob); a.download mergFileDefault.bat; a.click(); }逐个说关键点。第一行lastNum的取值做了正则校验^\d$能挡住负数、小数和字母避免把乱值拼进 bat 里这是从源头防呆。模板字符串(for /L %%i in (0,1,${last})把用户输入的数字直接注入循环终止值所以填 88 和填 999 会生成两个不同终点的 bat。lines.join(\r\n)用了 Windows 标准的 CRLF 换行而不是 Unix 的 LF批处理对换行符敏感这里错一点都可能让命令解析出问题。Blob 指定application/x-bat类型再通过URL.createObjectURL触发下载是浏览器端生成并下载文件的通用套路。实际工具页面的写法可能有细节出入但骨架就是这个校验输入、拼脚本字符串、触发下载。3.2 把 bat 放进视频文件夹工作目录决定一切生成 bat 只是第一步双击之前有一个容易被忽略的动作——把 bat 复制到 ts 文件所在的文件夹里。批处理里的 list.txt、output.mp4 全是相对路径相对的是当前工作目录而双击 bat 时工作目录就是 bat 自己所在目录。把 bat 扔在桌面双击ffmpeg 就会在桌面找 0.ts结果可想而知。所以流程必须是先确认视频文件夹把 bat 复制进去再双击。ffmpeg 的依赖也要先验证。bat 里写的是裸命令ffmpeg意味着系统 PATH 必须能找到它。验证方式是在 cmd 里执行where ffmpeg ffmpeg -versionwhere ffmpeg能找到就说明 PATH 没问题如果提示找不到把解压版 ffmpeg 的 bin 目录加进 PATH或者更省事——直接把 ffmpeg.exe 拷到 bat 同目录bat 里写ffmpeg.exe或保留ffmpeg都能优先命中当前目录。很多工具包会自带 ffmpeg.exe手册里一般也会注明。这一步不做后面双击大概率就是闪退连报错都看不到具体排法在第 4 章。3.3 双击执行后看什么、验什么双击 bat 后窗口里会滚动 ffmpeg 的输出日志最后停在pause上等按键。这个暂停不是多余的它给了你检查日志的空间。需要确认三件事同目录出现合并好的 mp4输出文件名以实际生成的 bat 为准文件大小和各 ts 体积之和基本相当流复制不会大幅压缩体积对不上就说明丢了段播放器能正常拖动进度条。提示第一次合并时不要把源 ts 文件删掉。output.mp4 验证通过前源文件就是后悔药删了再想重来就只能重新下载。如果窗口里出现红字 error先别按任意键把报错信息拍照或者手动抄下来。最省事的做法是把日志重定向到文件下一章 4.5 会给出具体命令。合完以后list.txt 会被 bat 自动清掉视频文件夹里只多一个合并好的 mp4这也是工具设计上比较省心的一点。4. 避坑排查TS 合并最常见的五个翻车现场工具虽然只有三道步骤但实际用起来翻车点都藏在细节里。这一章按 现象 → 原因 → 解决 的格式记录五条高频问题遇到直接对照不用从头猜。4.1 双击后报 No such file or directory编号位数对不上现象双击 bat 后 ffmpeg 报88.ts: No such file or directory或者更早一步list.txt 里生成的文件名和文件夹里的文件对不上。原因文件夹里的真实文件名是 088.ts、089.ts 这种三位补零或者最后一个根本不是 88 而是 89你没有核对就填了数字。工具的设计前提是0 到 N 连续、无前导零一旦文件名带前导零填什么都对不上。解决先在视频文件夹执行dir /b /on *.ts看真实文件名和最大编号。如果是三位补零不要把精力花在改 bat 上——cmd 里补零要额外写 set 拼接麻烦且容易错最快的办法是把文件统一改成 0.ts、1.ts 这种干净命名或者换用第 5 章的按实际文件名生成清单方案绕开编号假设。4.2 合并出来的 mp4 只有第一段或时长明显不足现象output.mp4 能生成但总时长只有几秒或者播放到一半就没了。原因清单里的文件顺序不对。编号连续时for /L生成的顺序是可靠的但如果你把工具用在带前缀的文件上或者中间有文件缺席——比如 0.ts 到 88.ts 里缺了 37.ts——ffmpeg 会在缺号处停止输出就只有缺号之前那部分。还有一个隐蔽原因数字和字母混排时系统默认排序不一定是你以为的顺序。解决查两处。一处是 list.txt 是否覆盖全部文件另一处是 ffmpeg 日志末尾有没有 Impossible to open 之类的行。对工具的标准场景0..N 连续来说缺号是唯一可能的坑补上缺失文件或者调整终止编号即可对带前缀的命名直接跳到第 5 章的 dir 方案。4.3 合并后能播但拖动卡顿时间戳断裂现象output.mp4 播放正常但拖进度条就转圈VLC 里尤其明显进度条一顿一顿。原因各分段的起始 PTS 不是从 0 开始的拼起来之后时间戳有跳变部分 ts 的封装时间基不一致mux 成 MP4 之后索引表不好定位。这类问题最玄学因为源文件参数看起来都一样就是拼出来的文件拖不动。解决先试流复制加时间戳修复命令是ffmpeg -fflags genpts -f concat -safe 0 -i list.txt -c copy -movflags faststart output.mp4-fflags genpts让 ffmpeg 在输入阶段重新生成缺失或异常的 PTS-movflags faststart把 MP4 的索引 moov 挪到文件头播放器打开时不用先扫全片拖动体验会好很多。如果这样还卡说明源 ts 的编码参数确实不一致得用ffprobe -v error -show_entries streamcodec_name,width,height,avg_frame_rate 0.ts 1.ts逐个对比参数不齐就只能重编码合并-c:v libx264 -c:a aac速度慢但能根治。4.4 合并后花屏、只有第一帧正常加密 TS 的典型排雷现象按同一套流程合并从 m3u8 下载的分片产物播放出来只有第一帧清晰往后全是雪花或者马赛克。原因这些分片是 AES-128 加密过的文件内容不是明文 TS 流直接 copy 等于把密文一段段拼起来解码器自然只认得出开头。这就是工具文件名里非加密三个字的含义——它只处理明文 TS加密流是它的明确边界。解决判断是否加密有个快速办法用十六进制编辑器看分片首字节明文 TS 分片的同步字节是 0x47ASCII 的 G加密分片首字节是随机的。确认加密之后别再走 concat 这条路线如果在本地已经有完整的 m3u8 和分片可以交给 ffmpeg 直接处理播放列表让它自己解密合并命令是ffmpeg -i playlist.m3u8 -c copy output.mp4但这依赖播放列表里的 key 配置正确属于另一套玩法不在这个工具的覆盖范围内。务实建议非加密场景随便用加密场景找专门的解密合并方案别硬拿这个工具顶。4.5 bat 一闪而过什么都没留下缺 pause 和日志现象双击 bat窗口闪一下就消失list.txt、output.mp4 全都没有像什么也没发生过。原因脚本里没有pauseffmpeg 的报错在窗口关闭前来不及看更常见的是 ffmpeg 根本没在 PATH 里命令直接失败窗口一闪而过。这类问题我把它列为血泪经验——你根本不知道是拼写错了、路径错了还是文件错了全是黑匣子。解决bat 最后一行加pause是排查期保命手段窗口会停住等你按键想留下现场把 ffmpeg 的报错重定向到文件ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4 2err.txt pause2err.txt把标准错误写进 err.txt之后用记事本打开看具体是哪一步失败。另外用where ffmpeg先验证依赖我第一次用这类工具时就因为 PATH 没配好白白折腾了半小时。5. 边界场景改造非 0 开头、乱序命名和子目录 TS 的合并方案工具默认只认 0.ts、1.ts 这种干净序列但实际拿到的素材往往不干净。这一章的三个场景都基于同一个思路把工具生成的 bat 当模板按文件名真实情况改造。下面按需取用。5.1 起始编号不是 0改 for /L 的起点场景文件是 5.ts 到 42.ts最小号不是 0。直接在输入框填 42生成的 bat 会从 0.ts 开始找立刻报错。原因HTML 生成器写死了循环起点是 0它只服务标准序列。解决记事本打开 bat把循环起点改成实际最小编号保存后再双击(for /L %%i in (5,1,42) do echo file %%i.ts) list.txt ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4(5,1,42)里的 5 就是新的起点42 是终点中间那个 1 是步长。这里有个容易用错的点只有编号规律递增时才省事如果编号是 5、8、11 这种等差序列把步长改成 3 即可如果是 5、9、12 这种无规律分布编号法就别用了直接看 5.2。5.2 带前缀、乱序、有中文名用 dir 生成清单更稳场景文件叫 dkfagyk93ksfyl32dakgd_0.ts 这种带长前缀的或者文件名是中文、带空格输入框根本没法填填了也对不齐。解决绕开 HTML 生成器直接用一份通用 bat。这也是老手把这类工具当模板用的常规操作——生成的 bat 只是个起点真正干活的是里面的清单生成逻辑(for /f delims %%f in (dir /b /on *.ts) do echo file %%f) list.txt ffmpeg -f concat -safe 0 -i list.txt -c copy output.mp4第一行拆开看dir /b /on *.ts列出当前目录所有 ts 文件/on按名称排序for /f逐行读取结果delims把默认的分隔符清掉防止文件名带空格时被拆成多列%%f依次取到完整文件名包成file dkfagyk93ksfyl32dakgd_0.ts这样的清单行。这套方案对任意命名都成立前提依旧是明文未加密。注意一个踩坑点bat 文件的保存编码要和 chcp 设置匹配。文件名里有中文时如果 bat 存成 UTF-8前面就要有chcp 65001如果存成 ANSI就删掉 chcp 那行。两者混用中文路径会在运行时报乱码错这个我栽过一次。5.3 多目录、多集批量循环里套循环场景一个课程十几个文件夹每个文件夹里都是一套 0..N 的 ts想一键把每集合成一个 mp4而不是手动跑十几遍。解决外层遍历文件夹内层做清单生成和合并。每轮先cd进子目录合并完输出到上级目录避免产物和源文件混在一起echo off set /p last请输入最大编号: for /d %%d in (*) do ( cd %%d (for /L %%i in (0,1,%last%) do echo file %%i.ts) list.txt ffmpeg -f concat -safe 0 -i list.txt -c copy ..\%%d.mp4 del /q list.txt cd .. ) pauseset /p last让脚本停下来问你最大编号一次输入、全部套用for /d %%d in (*)遍历所有子目录%%d拿到目录名内层for /L的%%i和外层%%d用了不同的变量字母cmd 里嵌套循环变量不能同名这是个容易报错的细节输出文件名写成..\%%d.mp4就是放到上一级目录、以目录名命名这样每集产物互不覆盖。跑之前先选一个只有两三段的小目录试一轮确认格式没问题再放整批别一上来就全量执行。这套脚本是我把同类工具实际用在多集课程素材时改出来的稳定性比手动逐个跑高得多。6. 进阶校验合并后用 ffprobe 验证时长、流信息和关键帧合并完成不等于交付完成。TS 拼接最大的风险是文件在、内容错我现在养成了固定习惯合并完顺手跑一遍 ffprobe三个检查项两分钟搞定。第一项是时长。产物总时长应约等于各 ts 时长之和误差超一两秒就要警惕丢段命令分两步来看ffprobe -v error -show_entries formatduration -of defaultnoprint_wrappers1:nokey1 output.mp4for %%f in (*.ts) do ffprobe -v error -show_entries formatduration -of csvp0 %%f-show_entries formatduration只取封装层时长nokey1让输出干净到只剩一个数字两边的数加一加、比一比对不上就回到第 4 章查缺号和时间戳问题。第二项是流信息。素材带多音轨时拼接后可能出两条音轨播放器默认选错轨就会有画面没声音ffprobe -v error -show_entries streamindex,codec_name,codec_type,width,height -of compact output.mp4stream...逐流列出索引、编码、类型和分辨率一眼就能看出视频流是否只有一路、音频流是否还在。第三项产物要上传或发人就再补一次 faststart——ffmpeg -i output.mp4 -c copy -movflags faststart done.mp4把 moov 索引挪到文件头避免对方在网页播放器里打开时白屏转圈。这套流程配合工具包里的手册和教程视频完整跑通一次基本不会再翻车。从那以后我每次用这类 ts 合并工具都强制走一遍 ffprobe 校验时长对不上就回头查 list.txt流信息不对就逐个看源 ts 参数靠这个习惯救回来的素材比想象中多。希望帮到你。本文还有配套的精品资源点击获取
上一篇/下一篇内容由系统自动关联
返回资讯列表 →