视频流媒体格式对比

下面分三块说清楚:HLS(m3u8)本地 MP4FMP4 分别是什么,以及它们之间的区别。


一、HLS 源(m3u8)

是什么

  • HLS(HTTP Live Streaming) 是苹果提出的一套流媒体传输方案(协议 + 约定),不是某一种”文件格式”。
  • 对外暴露的是一个 m3u8 地址(播放列表),例如:https://xxx/live/stream.m3u8
  • 浏览器或播放器先请求这个 m3u8,再根据里面的信息去拉取真正的媒体切片(TS 或 fMP4)。

怎么工作

  1. m3u8 文件

    • 纯文本,里面是一份”清单”:
      • 各切片的 URL(相对或绝对)
      • 可选:多码率列表(主列表 + 子列表)
    • 直播时:m3u8 会不断更新,追加新切片、去掉旧切片。
  2. 切片

    • 常见两种:
      • TS(.ts):MPEG-TS 封装,HLS 最传统的形式。
      • fMP4(Fragmented MP4):HLS 也支持用 fMP4 做切片(和下面说的 FMP4 是同一类格式)。
  3. 播放流程

    • 请求 m3u8 → 解析出切片 URL → 按顺序请求切片 → 解封装、解码 → 通过 MSE 喂给 <video> 或直接给 Safari 播放。
    • 在非 Safari 浏览器里,通常用 hls.js 做”请求 m3u8 + 拉切片 + MSE”这件事。

特点

  • 协议/方案:定义了”怎么列清单(m3u8)+ 怎么拉切片(HTTP)”。
  • 传输:走 HTTP/HTTPS,用普通 GET 请求即可,适合 CDN、缓存。
  • 直播/点播:都支持;直播靠不断更新 m3u8、追加新切片。
  • 前端:Safari 可原生播 m3u8;其它浏览器一般用 hls.js 等库。

二、本地 MP4(普通 MP4)

是什么

  • 就是大家平时说的 MP4 文件(如 video.mp4),标准叫法接近 ISO Base Media(MP4 容器)
  • 一个完整文件里包含:元数据(moov) + 一整段媒体数据(mdat),通常是”整片编码好再封装”的形态。

怎么工作

  1. 结构

    • moov:时长、码率、关键帧、索引等,告诉播放器”怎么解码、怎么 seek”。
    • mdat:音视频帧数据。
    • 很多 MP4 会把 moov 放在文件末尾(方便边下边生成),也有放在开头的。
  2. 播放

    • 浏览器直接:<video src="/video/360_vr.mp4">
    • 由浏览器自己请求文件、解析 moov、按需读 mdat、解码播放;不需要 m3u8、不需要 MSE,也不需要 hls.js。

特点

  • 格式:一种封装格式(容器),里面一般是 H.264 + AAC。
  • 传输:一个 URL 对应一个完整文件,用 HTTP 范围请求(Range)可以拖进度、断点续传。
  • 典型用途:本地文件、点播、下载后播放;不做直播(没有”不断追加新切片”的概念)。
  • 前端:所有主流浏览器原生支持,无需额外库。

三、FMP4(Fragmented MP4 / fMP4)

是什么

  • FMP4MP4 的一种”切片化”用法,还是 MP4 容器,但按片段组织,而不是”一个 moov + 一大块 mdat”。
  • 每个”片段”可以独立解码、按顺序拼接播放,适合流式、直播

怎么工作

  1. 结构

    • Init segment(初始化段):相当于 moov,只发一次,描述编码、分辨率、轨道等。
    • Media segments(媒体段):一段段的小块数据(几秒到十几秒),按时间顺序追加。
    • 没有”一个巨大的 mdat”,而是很多小段,所以可以边生成边推、边收边播
  2. 谁在用 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 三种”源”的差异再精简成一页说明)。