资讯动态

TS文件怎么合并成MP4?一条FFmpeg命令搞定分片视频转换

发布时间:2026/10/13 8:53:33 来源:尧图企业网站定制
直接跟你说结论这堆.ts文件完全不用怕它们不是损坏的视频碎片只是一段完整视频被按时间切成了若干个小块。你只要按顺序把它们接起来再换个封装格式就能得到流畅播放的 MP4。我前前后后用这个方法处理过几十个从浏览器缓存里扒下来的视频折腾多了发现核心就一个工具、一条命令的事。这篇就给你把原理、命令、坑一次性讲明白。1. 先从根上搞清楚TS 文件是什么为什么会有一大堆1.1 TS 文件不是残缺文件而是视频流的原始分片很多朋友第一次看到几百个.ts文件时的第一反应是这视频被切碎了是不是没救。其实TS的全称是 Transport Stream也就是传输流。它本身就是一种音视频封装格式最早是用在数字电视广播里的讲究的是哪怕网络抖一抖、丢几个包也能尽量把画面继续播下去。所以每个.ts文件实际上都是一个可以独立解码的视频小片段自带音频和视频数据只看单个文件也能播放出那几秒钟的内容。你在浏览器里下载到的这一堆 TS 文件本质上就是播放器从服务器拉取下来的一段 CDN 加速后的流媒体缓存。视频网站为了让你拖动进度条不卡顿、边下边播会把整部影片切成 5 到 10 秒一小段然后用一个播放列表去索引这些片段。你看到的这些.ts文件就是这些已经被下载到本地缓存的原材料。1.2 浏览器下载视频时到底发生了什么正常情况下你在网页里看视频地址栏里是看不到.mp4的。因为页面里嵌入的播放器通常不是直接请求一个完整的大文件而是先请求一个m3u8或mpd格式的索引文件。以m3u8为例它里面写的不是视频内容本身而是一张地图从哪个地址下载第 1 个文件从哪个地址下载第 2 个文件每个文件播放多久视频的分辨率、码率是多少。当页面加载完成播放器会根据这个地图把 TS 分片一个个下载到浏览器缓存目录里。你如果在文件资源管理器里看浏览器的缓存文件夹自然就会看到xxx_00001.ts、xxx_00002.ts这种按序号排好的文件。这根本不是视频下载到了某个文件夹而是浏览器把已经播放过的分片留在本地了。1.3 播放列表文件 M3U8 的作用我建议你先找到那个m3u8文件。如果它还在后面的合并工作会简单很多。.m3u8本质上是一个 UTF-8 编码的文本文件里面每一行都指向一个 TS 分片的路径有的还标注了EXTINFDuration时长信息。举个例子#EXTM3U #EXT-X-VERSION:3 #EXT-X-TARGETDURATION:10 #EXT-X-MEDIA-SEQUENCE:0 #EXTINF:10.000000, index_00001.ts #EXTINF:10.000000, index_00002.ts ... #EXT-X-ENDLIST这个东西就是分片之间的锁链。只要有了它FFmpeg 就能自动按列表顺序读取所有分片无缝拼成一个完整的视频流。后面我会教你怎么从浏览器缓存里把 m3u8 一起捞出来或者干脆手动生成一个等价清单。1.4 合并前先把工具备齐不需要安装一堆花里胡哨的软件。我实测下来最省心的组合是工具用途获取方式FFmpeg合并、转换、修复音画同步官网下载对应系统的可执行文件一个能看十六进制或文本的编辑器检查 m3u8 内容、修改文件清单Notepad / VS Code / 系统自带记事本文件管理器排序、重命名、清点分片数量Windows/macOS/Linux 自带如果你不想下载额外软件Windows 系统下用 PowerShell、macOS 或 Linux 下用终端加 FFmpeg 就能完成 80% 的工作。接下来我会把核心操作拆开讲保证你在十分钟内能把第一段视频合并出来。2. 合并转换的核心思路一条 FFmpeg 命令为什么能搞定2.1 先看 FFmpeg 的合并命令长什么样假设你已经把某个视频所有的 TS 分片放在同一个文件夹里并且找到了对应的 m3u8 文件那么合并命令非常简单ffmpeg -allowed_extensions ALL -i input.m3u8 -c copy -bsf:a aac_adtstoasc output.mp4我知道新手看到这一串字母会慌我来拆给你看-allowed_extensions ALL允许 FFmpeg 读取本地文件时跨目录访问相关分片。如果m3u8里写的是相对路径不加这个参数可能报错。-i input.m3u8指定输入文件注意这里把m3u8当输入FFmpeg 会自动读取列表并逐个加载 TS 分片。-c copy这是最关键的参数意思是流复制。它告诉 FFmpeg不要重新编码视频和音频直接把原始数据拷进新的封装容器里。相当于把一盒积木按原样搬到另一个盒子里不改变每一块的形状。-bsf:a aac_adtstoasc把音频从 ADTS 格式转换成 ASC 格式。TS 流里的 AAC 音频通常带一个 ADTS 头MP4 需要的则是 ASC 配置信息。不写这个参数输出文件播放时经常只有画面没有声音或者音画不同步。output.mp4输出的文件名。你可以自己指定路径。就这么一条命令它做了三件事读取播放列表、按顺序拼接所有分片、把最终结果封装成 MP4。2.2 为什么优先推荐流复制而不是重新编码很多教程会让你写ffmpeg -i input.m3u8 -c:v libx264 -c:a aac output.mp4我强烈不建议你直接用这个。因为-c:v libx264意味着 FFmpeg 会把视频重新解码再用 x264 编码器重新压一遍。这个过程有两个明显毛病第一极其耗时。一个 1 小时的 1080p 视频重新编码可能需要 20 分钟甚至更久而-c copy通常几十秒就完成了。第二画质损失。哪怕你把码率参数调得很高二次编码总会引入额外的压缩误差。特别是原本码率比较低的在线视频重压之后会出现明显的色块和模糊。你可以把 TS 分片理解成一张张已经裁剪好的照片。复制拼接是直接把照片按序号订成册画面原封不动重新编码则相当于把每张照片拿扫描仪扫一遍、修图、再打印出来怎么能不糊所以除非遇到下面两个场景否则永远优先用-c copy。原视频编码格式过于古老比如 MPEG-2 编码的 TSMP4 容器虽然能装它但兼容性很差手机可能播不了。这种情况下可以只转视频编码。你确实需要压缩体积比如原视频码率非常高你想转一个小文件发出去。这时候可以接受画质损失。如果你不确定原视频是什么编码先用这个命令看一眼ffprobe -i input.m3u8输出结果里会写明Video: h264还是Video: hevc或Video: mpeg2video。如果是 h264 或 hevc放心用-c copy。2.3 m3u8 文件丢了还能不能合并这是最常见的情况。浏览器缓存里只有一堆xxx_0.ts、xxx_1.ts翻遍了都找不到 m3u8。别慌我们可以自己生成一个。在 Linux 或 macOS 的终端里先进入分片所在目录然后执行for f in *.ts; do echo file $f; done list.txtWindows 下的 PowerShell 用Get-ChildItem -Name *.ts | ForEach-Object { file $_ } | Out-File -Encoding ascii list.txt然后使用 FFmpeg 的 concat 格式直接合并ffmpeg -f concat -safe 0 -i list.txt -c copy -bsf:a aac_adtstoasc output.mp4这里的-f concat告诉 FFmpeg 按文本清单拼接文件。注意每一行必须写成file 文件名的格式如果是中文文件名最好先把文件重命名成简单的数字序列防止编码问题。2.4 没装 FFmpeg 的备选方案用播放器或网站在线转换如果电脑上暂时没有 FFmpeg又急着合并可以考虑这类办法用支持本地 M3U8 播放的播放器打开对应的 m3u8 文件确认能完整播放后再用它的录制/导出功能。不过我不太推荐这条路线因为播放器导出要么是录屏画质受损要么依赖特殊插件成功率低。另一个方案是把 m3u8 文件上传到某个在线转换网站但视频隐私和文件大小都是问题。所以我的建议很明确花几分钟装个 FFmpeg 才是最省事、最可靠的路。3. 完整实操从一堆 TS 文件到流畅播放的 MP43.1 第一步把分片文件归拢到同一个文件夹先把浏览器缓存目录里的相关文件复制到一个新文件夹。不要直接在原目录操作一是避免文件被浏览器自动清理二是保持操作环境干净防止混入别的视频碎片。具体操作方式Windows 的 Edge/Chrome 等浏览器在地址栏输入edge://version或chrome://version可以看到个人资料路径缓存目录通常在这个路径下的Cache或Code Cache里。实际文件往往没有扩展名你需要按文件大小排序来找体积较大的那一批。Safari、Firefox 也有类似的缓存目录。实在找不到就搜索m3u8一般能定位到最近播放的视频的索引文件。如果你是从某些第三方工具或网页下载按钮直接保存的视频文件夹里可能已经是一个个.ts文件那更好办。把所有这些文件放进同一个目录并且确保播放列表里的路径与真实文件名一致。3.2 第二步确认分片的顺序和完整性合并最怕的是顺序错乱和缺片。先按名称排序检查一下。如果是类似index_0.ts、index_1.ts、index_2.ts这种序号开头的通常没问题。但如果文件名是带时间戳的哈希值比如a1b2c3.ts、d4e5f6.ts这种毫无规律的名字顺序就完全依赖 m3u8 列表了这时一定要找到 m3u8 作为索引。完整性怎么查最快速的方法是用 FFmpeg 直接尝试合并过程中会提示403、404或Invalid data等字眼。不过更稳妥的是写个小脚本统计每个文件的大小。以我经验同一个视频分片除了开头和结尾的文件可能明显小一些中间的分片大小应该都在一个相近的范围内。如果发现某个文件特别小比如只有几百字节那很可能下载不完整。3.3 第三步用 M3U8 清单合并并保持原画质现在假设你已经拷贝好文件、找到了 m3u8执行ffmpeg -allowed_extensions ALL -i playlist.m3u8 -c copy -bsf:a aac_adtstoasc merged.mp4如果成功会出现一长串进度记录最后显示muxing overhead之类的信息。此时用播放器打开merged.mp4拖动进度条确认无异常即可。这里有个小细节如果 m3u8 里的路径是完整 URLhttp://.../xxx.tsFFmpeg 会直接去网络拉流。你本地已经有缓存的情况下应该把 m3u8 里的 URL 改成相对路径或本地路径否则要么下载不了要么速度很慢。推荐用文本编辑器打开 m3u8把每一行的http....../前缀去掉只保留文件名。如果分片和 m3u8 在同一个目录这一步是必须的。3.4 第四步没有 M3U8 时的手动清单合并没有 m3u8 文件就按 2.3 节的方法生成list.txt。这里有一个提升成功率的技巧生成前先把文件名批量重命名成四位数的序号比如0001.ts、0002.ts避免因为序号位数不齐导致排序错误。Windows 下可以使用 PowerShell$i1; Get-ChildItem *.ts | Sort-Object Name | ForEach-Object { Rename-Item -Path $_.FullName -NewName ({0:D4}.ts -f $i) ; $i }这样之后生成的list.txt内容就非常干净了。然后执行 2.3 的合并命令。3.5 第五步检查输出文件清理中间文件合并完成后先用ffprobe看一眼输出文件的基本信息ffprobe merged.mp4主要确认三样时长是否和原视频一致、音频流是否存在、视频编码是否为 h264/hevc。如果时长和你记忆中差不多那就基本成功了。我习惯把最终 MP4 挪到安全目录然后删除原文件夹里的分片和临时 list.txt避免它们占用大量空间。这也是经验之谈一个 2 小时的视频分片加起来的体积可能比你想象的还大合并不代表分片消失两者会同时占磁盘。确认无误后及时清理。4. 常见问题与排查技巧实录4.1 合并出来的视频有画面没声音十次有八次是这个原因没有用-bsf:a aac_adtstoasc。前面我已经说过TS 里的 AAC 音频和 MP4 里的组织方式不同需要转换 bitstream filter。补上参数重新跑一次就正常了。但还有另一种情况原视频本身是 AC3 或 EAC3 音轨MP4 容器对这两种音频格式支持得不太好。这时你可以只把音频转成 AACffmpeg -allowed_extensions ALL -i input.m3u8 -c:v copy -c:a aac -bsf:a aac_adtstoasc output.mp4注意这里-c:v copy保留视频-c:a aac单独转音频速度也很快。4.2 播放器提示文件损坏或中途跳帧排查分几步用 FFmpeg 的日志看有没有报错。如果某一行提示Packet corrupt说明对应的 TS 分片可能下载不完整。找到那个序号的分片看它的大小是否明显偏小尝试重新从浏览器缓存里捞一次或者重新拉取。如果只是个别文件问题可以编辑 m3u8 或 list.txt 跳过那个文件但这样可能造成画面跳动几十秒属于下策。我遇到这种情况通常直接临时换一条合并策略不按清单而是把所有文件按顺序用 concat 协议硬拼ffmpeg -f concat -safe 0 -i list.txt -c copy -bsf:a aac_adtstoasc output.mp4concat 协议在遇到个别损坏分片时的容忍度比 m3u8 读取模式高一点。如果还是失败那就别硬撑重新下载原视频更省时间。4.3 合并成功了但画质明显比在线播放差这个问题九成不是合并造成的而是你下载的分片本身码率就不高。很多网站在播放时会根据你的带宽自动选择清晰度如果当时网络一般浏览器缓存的可能是 480p 甚至 360p 的分片。合并只是搬运不会把低清变高清。解决办法是主动把浏览器播放器的清晰度调到最高然后重新完整播放一遍哪怕倍速播放让所有高码率分片下载到本地再重复合并操作。另外有些网站的 m3u8 里包含多组不同清晰度的流开头会有RESOLUTION1920x1080这样的标签你可以手动指定最高分辨率的那一组索引。不要被伪 4K 骗了很多电视端的 4K 在线流码率比普通 1080p 高不了多少。4.4 分片带有加密合并后内容花屏或直接黑屏现在很多正规视频平台都对 HLS 分片做了 AES-128 加密。m3u8 文件里会多一行#EXT-X-KEY:METHODAES-128,URIkey.key分片的内容不是纯视频流而是加密后的密文。这时你如果硬合并得到的 MP4 是花的或黑的。处理思路有两条找到解密的 key 文件并在 m3u8 中保留正确的 URIFFmpeg 会自动解密。前提是 key 文件路径可访问。你需要把 key 同步到本地并将 m3u8 里的 URI 改成本地路径。如果 key 是通过网络请求动态获取的且已失效那你基本无法离线解密除非在播放时实时获取。这个属于版权边界问题我不建议折腾也没必要。一句话总结带加密的 HLS 流能不能离线合并取决于你是否有合法的解密密钥。这不是工具能硬解的。4.5 分片数量太多Windows 路径长度报错当分片文件名很长或者文件目录层级很深Windows 会报文件名太长的错误。解决办法很简单把临时目录放在盘符根目录下比如D:\merge\并且把分片重命名为0001.ts这样的短名字。这个问题我在处理长视频时经常遇到提前做好重命名可以省掉很多麻烦。4.6 合并过程中内存或磁盘爆满用-c copy合并时FFmpeg 并不会把全部内容载入内存内存占用一般很低。但输出文件也是完整大小所以磁盘空间至少要剩视频体积的两倍分片 输出。如果空间不足可以分两次先合并前面一半再合并后面一半最后用 concat 把两个半段 MP4 接起来。当然这属于应急方案正常情况下不建议分多次。我个人现在处理这种多 TS 文件转 MP4 的需求第一反应永远是先找 m3u8第二反应才是手动生成 list.txt。前一种方法能自动确保顺序、处理加密和变体流后一种需要自己确认的信息更多。你要是只偶尔处理一次用上面的命令足够要是频繁处理这类视频建议把 2.3 的生成清单脚本和合并命令写成一个批处理文件丢到右键菜单里能省下不少重复劳动。最后再提醒一个很多人忽略的点合并后的 MP4 一定要自己完整拉一遍进度条别只看开头几十秒没问题就以为大功告成中途某个分片缺失往往要等播放到那里才露馅。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑