格式转换
FlowPick 在下载流媒体的同时,能够将分片合并并转换为标准格式。本文档说明支持的转换路径、底层技术原理、输出格式选择以及性能特征。

前置概念:容器 vs 编码
理解格式转换前,需要区分两个容易混淆的概念:
| 概念 | 说明 | 类比 |
|---|---|---|
| 容器(Container) | 文件的"外壳",决定文件扩展名和内部数据的组织方式 | 快递盒——决定包裹的外形 |
| 编码(Codec) | 音视频数据的压缩算法 | 盒子里装的物品 |
FlowPick 的格式转换只改变容器,不改变编码(即"转封装"或 Remux)。这意味着:
- 视频画质和音频音质完全不变
- 转换速度很快(不涉及重新编码)
- 无法改变编码格式(如 H.265 → H.264)
转换路径概览
FlowPick 支持以下转换路径,覆盖 HLS 和 DASH 两种主流流媒体协议:
| 源格式 | 目标格式 | 转换方式 | 速度 | 质量 | 典型场景 |
|---|---|---|---|---|---|
| HLS (TS 分片) | MP4 | FFmpeg WASM 转封装 | 中等 | 无损 | 通用播放、视频编辑 |
| HLS (TS 分片) | TS | 二进制直接拼接 | 极快 | 无损 | 追求速度、后续处理 |
| DASH (MP4 分片) | MP4 | FFmpeg WASM 转封装 | 中等 | 无损 | 通用播放 |
| DASH (FMP4 分片) | MP4 | FFmpeg WASM 重组 | 中等 | 无损 | 需要初始化分片 |
| DASH (分离音视频) | MP4 | FFmpeg WASM 合并 | 较慢 | 无损 | DASH 音视频分离流 |
"无损"指不进行重新编码,仅改变容器格式。视频和音频的编码数据保持不变。
转换技术原理
FlowPick 使用两套转换引擎,根据场景自动选择最优方案:
| 引擎 | 适用场景 | 优势 | 劣势 |
|---|---|---|---|
| FFmpeg WASM | TS→MP4 转封装、DASH 合并、音视频合并 | 功能完整,支持复杂转换 | 需要加载 WASM 文件,内存占用较高 |
| TSToMP4Muxer | TS→MP4 流式转封装 | 纯 JS 实现,无需加载 FFmpeg,内存效率高 | 仅支持 TS→MP4 单一场景 |
TS 分片 → MP4(FFmpeg WASM 转封装)
HLS 流通常使用 MPEG-TS 容器封装。转换为 MP4 时,FlowPick 使用 FFmpeg WASM 执行以下操作:
输入:多个 .ts 分片文件
处理流程:
- 将所有 TS 分片写入 FFmpeg 虚拟文件系统(WASM 内存)
- 生成 concat 文件列表(
filelist.txt) - 执行转封装命令:
ffmpeg -f concat -safe 0 -i filelist.txt \
-c copy \
-movflags +faststart \
-bsf:a aac_adtstoasc \
output.mp4
关键参数说明:
| 参数 | 作用 | 为什么需要 |
|---|---|---|
-f concat | 使用 concat demuxer 拼接分片 | TS 分片无法直接合并,需要 demuxer 处理 |
-safe 0 | 允许任意文件路径 | WASM 虚拟文件系统的路径格式特殊 |
-c copy | 流拷贝模式,不重新编码 | 保证无损转换,速度最快 |
-movflags +faststart | 将 moov atom 移至文件开头 | 支持网络渐进式播放,边下载边看 |
-bsf:a aac_adtstoasc | AAC 音频格式转换 | TS 使用 ADTS 格式,MP4 需要 ASC 格式 |
性能特征:
- 不涉及编解码,CPU 占用低
- 主要耗时在文件 I/O(WASM 虚拟文件系统读写)
- 处理速度约为 50-100 MB/s(取决于 CPU 和分片数量)
TS 分片 → MP4(TSToMP4Muxer 流式转封装)
对于大文件场景,FlowPick 优先使用自研的 TSToMP4Muxer 进行流式转封装,避免 FFmpeg WASM 的内存限制:
处理流程:
- 逐分片解析 TS 包(188 字节/包),提取 PES 数据
- 实时转换为 MP4 格式的媒体数据
- 通过 Streams API 流式写入磁盘(FSA)或内存(Blob)
优势:
- 纯 JavaScript 实现,无需加载 FFmpeg WASM(节省 ~30MB 内存)
- 流式处理,内存占用与文件大小无关
- 支持 File System Access API 直接写入磁盘
劣势:
- 仅支持 TS→MP4 单一转换路径
- 不支持音视频分离合并
TSToMP4Muxer 是 FlowPick 的核心创新之一。它使得在浏览器中处理 GB 级别的视频文件成为可能,而不会触发内存溢出。详见 下载引擎。TS 分片 → TS(直接拼接)
这是最快的"转换"方式——实际上不进行任何转换,仅将 TS 分片按顺序二进制拼接。
处理流程:
- 下载所有 TS 分片到内存
- 按顺序将
ArrayBuffer拼接为单个Uint8Array - 直接写入文件
优势:
- 零 CPU 开销,速度仅受磁盘写入速度限制
- 完全保真,不修改任何字节
- 适合后续使用专业工具处理的场景
劣势:
- 文件体积可能略大于 MP4(TS 容器开销约 5-15%)
- 部分播放器对 TS 文件的支持不如 MP4
DASH 分片 → MP4
DASH 流的分片通常是 MP4 或 FMP4 格式。转换过程:
标准 MP4 分片:
ffmpeg -f concat -safe 0 -i filelist.txt \
-c copy \
-movflags +faststart \
output.mp4
FMP4 分片(需要初始化分片):
ffmpeg -i init.mp4 -i video.mp4 -i audio.mp4 \
-c:v copy -c:a copy \
-movflags +faststart \
output.mp4
音视频分离合并
DASH 流的视频和音频通常在不同的 AdaptationSet 中。合并过程:
ffmpeg -f concat -safe 0 -i video_list.txt \
-f concat -safe 0 -i audio_list.txt \
-c:v copy -c:a copy \
-movflags +faststart \
-bsf:a aac_adtstoasc \
output.mp4
输出格式选择指南
MP4(推荐)
适用场景:
- 需要在各种播放器和设备上播放
- 需要导入视频编辑软件(Premiere、DaVinci Resolve 等)
- 需要上传到视频平台(YouTube、Bilibili 等)
- 需要确保最大兼容性
技术细节:
- 容器:MPEG-4 Part 14
- MIME 类型:
video/mp4 - 支持 H.264/AVC、H.265/HEVC、AAC、MP3 等编码
faststart标志确保网络渐进式播放
TS
适用场景:
- 追求最快下载速度(跳过转封装步骤)
- 后续会用专业工具(如 FFmpeg 命令行)进一步处理
- 源流本身就是 TS 格式且不需要转换
- 临时保存,后续可能删除
技术细节:
- 容器:MPEG Transport Stream
- MIME 类型:
video/mp2t - 每个分片独立可播放
- 文件体积通常比 MP4 大 5-15%
格式选择决策树
需要最大兼容性? ──是──→ 选择 MP4
│
否
│
▼
追求最快速度? ──是──→ 选择 TS
│
否
│
▼
后续会用 FFmpeg 处理? ──是──→ 选择 TS
│
否
│
▼
选择 MP4(推荐)
性能对比
以下是在典型条件下(Chrome 126,Intel i7-13700,16GB RAM)的实测数据:
| 场景 | 分片数 | 总大小 | TS 拼接 | MP4 转封装 (FFmpeg) | MP4 流式 (Muxer) |
|---|---|---|---|---|---|
| 10 分钟 1080p 视频 | ~60 | ~200 MB | <1 秒 | ~3 秒 | ~2 秒 |
| 30 分钟 1080p 视频 | ~180 | ~600 MB | <1 秒 | ~8 秒 | ~5 秒 |
| 60 分钟 4K 视频 | ~360 | ~2.5 GB | ~2 秒 | ~30 秒 | ~18 秒 |
| 120 分钟 4K 视频 | ~720 | ~5 GB | ~4 秒 | ~60 秒 | ~35 秒 |
以上数据为估算值,实际性能取决于 CPU、内存和浏览器状态。流式 Muxer 在处理大文件时优势更明显。
影响转换速度的因素
| 因素 | 影响程度 | 说明 |
|---|---|---|
| 分片数量 | 高 | 分片越多,文件 I/O 次数越多 |
| 文件总大小 | 高 | 直接影响读写时间 |
| CPU 性能 | 中 | FFmpeg WASM 需要 CPU 进行 demux/mux |
| 内存大小 | 中 | WASM 虚拟文件系统需要足够内存 |
| 磁盘写入速度 | 中 | 使用 FSA 直接写入时影响较大 |
| 浏览器版本 | 低 | 新版本浏览器 WASM 性能更好 |
限制与注意事项
编码格式限制
FlowPick 的转换仅改变容器格式,不进行重新编码。这意味着:
| 限制 | 说明 | 影响 |
|---|---|---|
| 无法转换编码 | H.265 源输出仍为 H.265 | 老旧播放器可能不支持 |
| 无法改变码率 | 输出码率与源一致 | 无法压缩文件大小 |
| 无法改变分辨率 | 输出分辨率与源一致 | 无法降级或升级画质 |
| 无法改变帧率 | 输出帧率与源一致 | 无法转换 60fps→30fps |
| 非标准采样率 | 输出保持原样 | 部分播放器可能异常 |
内存限制
FFmpeg WASM 在浏览器中运行,受以下限制:
| 限制项 | 具体数值 | 影响 |
|---|---|---|
| WASM 内存上限 | 4GB(32 位地址空间) | 超大文件可能超出限制 |
| 虚拟文件系统 | 存储在内存中 | 文件大小受可用内存限制 |
| 多线程模式 | 需要 SharedArrayBuffer | 需要正确的 COEP/COOP 头 |
浏览器兼容性
| 功能 | Chrome | Edge | Firefox | Safari |
|---|---|---|---|---|
| FFmpeg WASM 单线程 | 支持 | 支持 | 支持 | 部分支持 |
| FFmpeg WASM 多线程 | 需要 COEP/COOP | 需要 COEP/COOP | 需要 COEP/COOP | 不支持 |
| TSToMP4Muxer 流式 | 支持 | 支持 | 支持 | 支持 |
| TS 直接拼接 | 支持 | 支持 | 支持 | 支持 |
命令行替代方案
如果你熟悉命令行,可以使用原生 FFmpeg 获得更好的性能:
# HLS → MP4
ffmpeg -i "https://example.com/playlist.m3u8" -c copy -bsf:a aac_adtstoasc output.mp4
# DASH → MP4
ffmpeg -i "https://example.com/manifest.mpd" -c copy output.mp4
# TS 分片合并
cat segment_*.ts > output.ts
# TS → MP4 转封装
ffmpeg -i output.ts -c copy -bsf:a aac_adtstoasc output.mp4
原生 FFmpeg 的优势:
| 优势 | 说明 |
|---|---|
| 不受浏览器内存限制 | 可使用全部系统内存 |
| 硬件加速编解码 | 支持 NVENC、QSV、VideoToolbox 等 |
| 更多格式和编码器 | 支持数百种格式和编码器 |
| 处理速度更快 | 原生代码性能远超 WASM |
| 支持重新编码 | 可改变编码格式、码率、分辨率 |
常见问题
为什么转换后的 MP4 文件比 TS 小?
TS 容器每个 188 字节的包都有包头开销,而 MP4 容器的索引结构更紧凑。转封装后文件体积通常减少 5-15%,但音视频数据完全不变。
转换会损失画质吗?
不会。 FlowPick 使用 -c copy(流拷贝)模式,只改变容器格式,不重新编码。视频和音频的每一个字节都原样保留。
为什么有些视频转换后无法播放?
可能的原因:
- 源视频使用了你的播放器不支持的编码(如 H.265)
- 转换过程中分片缺失导致文件不完整
- 源流本身存在问题