下面分三块说清楚:HLS(m3u8)、本地 MP4、FMP4 分别是什么,以及它们之间的区别。
一、HLS 源(m3u8)
是什么
- HLS(HTTP Live Streaming) 是苹果提出的一套流媒体传输方案(协议 + 约定),不是某一种”文件格式”。
- 对外暴露的是一个 m3u8 地址(播放列表),例如:
https://xxx/live/stream.m3u8。 - 浏览器或播放器先请求这个 m3u8,再根据里面的信息去拉取真正的媒体切片(TS 或 fMP4)。
怎么工作
m3u8 文件
- 纯文本,里面是一份”清单”:
- 各切片的 URL(相对或绝对)
- 可选:多码率列表(主列表 + 子列表)
- 直播时:m3u8 会不断更新,追加新切片、去掉旧切片。
- 纯文本,里面是一份”清单”:
切片
- 常见两种:
- TS(.ts):MPEG-TS 封装,HLS 最传统的形式。
- fMP4(Fragmented MP4):HLS 也支持用 fMP4 做切片(和下面说的 FMP4 是同一类格式)。
- 常见两种:
播放流程
- 请求 m3u8 → 解析出切片 URL → 按顺序请求切片 → 解封装、解码 → 通过 MSE 喂给
<video>或直接给 Safari 播放。 - 在非 Safari 浏览器里,通常用 hls.js 做”请求 m3u8 + 拉切片 + MSE”这件事。
- 请求 m3u8 → 解析出切片 URL → 按顺序请求切片 → 解封装、解码 → 通过 MSE 喂给
特点
- 协议/方案:定义了”怎么列清单(m3u8)+ 怎么拉切片(HTTP)”。
- 传输:走 HTTP/HTTPS,用普通 GET 请求即可,适合 CDN、缓存。
- 直播/点播:都支持;直播靠不断更新 m3u8、追加新切片。
- 前端:Safari 可原生播 m3u8;其它浏览器一般用 hls.js 等库。
二、本地 MP4(普通 MP4)
是什么
- 就是大家平时说的 MP4 文件(如
video.mp4),标准叫法接近 ISO Base Media(MP4 容器)。 - 一个完整文件里包含:元数据(moov) + 一整段媒体数据(mdat),通常是”整片编码好再封装”的形态。
怎么工作
结构
- moov:时长、码率、关键帧、索引等,告诉播放器”怎么解码、怎么 seek”。
- mdat:音视频帧数据。
- 很多 MP4 会把 moov 放在文件末尾(方便边下边生成),也有放在开头的。
播放
- 浏览器直接:
<video src="/video/360_vr.mp4">。 - 由浏览器自己请求文件、解析 moov、按需读 mdat、解码播放;不需要 m3u8、不需要 MSE,也不需要 hls.js。
- 浏览器直接:
特点
- 格式:一种封装格式(容器),里面一般是 H.264 + AAC。
- 传输:一个 URL 对应一个完整文件,用 HTTP 范围请求(Range)可以拖进度、断点续传。
- 典型用途:本地文件、点播、下载后播放;不做直播(没有”不断追加新切片”的概念)。
- 前端:所有主流浏览器原生支持,无需额外库。
三、FMP4(Fragmented MP4 / fMP4)
是什么
- FMP4 是 MP4 的一种”切片化”用法,还是 MP4 容器,但按片段组织,而不是”一个 moov + 一大块 mdat”。
- 每个”片段”可以独立解码、按顺序拼接播放,适合流式、直播。
怎么工作
结构
- Init segment(初始化段):相当于 moov,只发一次,描述编码、分辨率、轨道等。
- Media segments(媒体段):一段段的小块数据(几秒到十几秒),按时间顺序追加。
- 没有”一个巨大的 mdat”,而是很多小段,所以可以边生成边推、边收边播。
谁在用 FMP4
- HLS:可以用 fMP4 做切片(m3u8 里列的是 fMP4 的 URL),替代 TS。
- DASH:常用 fMP4 作为媒体格式。
- WebSocket / 自定义推流:服务端直接推送 fMP4 二进制(如你们用的 BorunFmp4Player),不经过 m3u8,用 MSE 接进
<video>。
特点
- 格式:还是 MP4 容器,但是”分片版”的用法。
- 传输:不绑定协议——可以用 HTTP(HLS/DASH)、也可以用 WebSocket、甚至内存/文件。
- 典型用途:直播、低延迟流、自适应码率;点播也可以。
- 前端:不能直接
video.src = fMP4 文件,需要 MSE(Media Source Extensions) 把 init segment + 多个 media segment 喂给<video>,所以需要脚本(hls.js、BorunFmp4Player 等)配合。
四、三者对比(简要)
| 维度 | HLS 源(m3u8) | 本地 MP4 | FMP4 |
|---|---|---|---|
| 是什么 | 一套传输方案(协议 + 播放列表 + 切片约定) | 一种封装格式(完整文件) | 同是 MP4 封装,但分片形态 |
| 你看到的是什么 | 一个 m3u8 的 URL,背后是多个 TS 或 fMP4 切片 | 一个 .mp4 文件 URL | 一段段二进制数据(或对应 URL),没有”一个 m3u8”也可以 |
| 传输方式 | HTTP:先下 m3u8,再按列表下切片 | HTTP:一个 URL,可 Range 请求 | HTTP(HLS/DASH)或 WebSocket 等 |
| 能否直播 | 能(m3u8 不断更新、追加切片) | 一般不做直播 | 能(持续推送新片段) |
| 前端怎么播 | Safari 原生;其它用 hls.js 等 | 直接 video.src = url |
必须用 MSE + 脚本(hls.js / BorunFmp4Player 等) |
| 典型场景 | 直播、点播、CDN 分发 | 本地/点播、下载 | 直播、低延迟、WebSocket 推流 |
五、和你们项目的关系(一句话对应)
- HLS(m3u8):后台给一个 m3u8 地址,前端用 hls.js 去拉 m3u8 和切片(TS 或 fMP4),再通过 MSE 播。——你们现在用的就是这种。
- 本地 MP4:后台或静态服务给一个
.mp4地址,前端直接src="/video/360_vr.mp4",不接流、不切片。 - FMP4:
- 要么作为 HLS 的切片格式(m3u8 里列的是 fMP4),仍由 hls.js 拉;
- 要么由后台通过 WebSocket 直接推 fMP4 片段,前端用 BorunFmp4Player + MP4Box 接 MSE 播放,不走 m3u8。
如果你愿意,我也可以按”协议/格式/前端代码”画一张更简的对比图(或只针对 HLS vs 本地 MP4 vs FMP4 三种”源”的差异再精简成一页说明)。