Monibuca HLS 直播与点播实战:从TS分片到fMP4无缝播放
【免费下载链接】monibucaMonibuca(简称 m7s)是一款纯 Go 开发的开源流媒体服务器开发框架。项目地址: https://gitcode.com/langhuihui/monibuca
Monibuca(简称 m7s)是一款纯 Go 开发的开源流媒体服务器,其内置的HLS 插件能让任何进入服务器的流瞬间获得 HTTP Live Streaming 播放能力:实时 TS 分片、内存滚动缓存、录像存储、按时间段点播,还支持将录像导出为 fMP4 实现低首屏延迟的无缝播放。本文将带你从零理解 TS 分片原理,到配置直播、拉流、录像,再到时间范围点播与 fMP4 点播的完整实战路径。
一、3 分钟看懂 HLS 直播原理
HLS(HTTP Live Streaming)的核心思想非常直观:把连续的音视频流切成一个个几秒长的 TS 文件(Media Segment),再用一个.m3u8播放列表文件记录这些分片的顺序和时长。播放器周期性拉取最新的 m3u8,发现新分片就下载播放——这就是"直播"的由来。
Monibuca 的实现完全遵循这套思路:
- 实时切片:plugin/hls/pkg/writer.go 中的
HLSWriter订阅流的音视频帧,按配置的时长(如 5s)在关键帧处切开,封装成标准 MPEG-TS; - 内存缓存:完成的分片放入滚动窗口(默认保留 3 个已完成 + 1 个进行中分片),请求 m3u8 时直接从内存返回,零磁盘 IO;
- 播放列表:plugin/hls/pkg/m3u8.go 按 RFC 8216 规范生成
#EXTM3U、#EXT-X-VERSION、#EXTINF等标签; - 无观众自动回收:15 秒无人读取分片后,切片任务自动停止,释放内存。
📌 Monibuca 采用"核心 + 插件"架构:HLS 作为协议插件与 RTMP、RTSP、WebRTC 等并列,任何协议的流进入服务器后,都可以被任意协议的插件转封装输出。
二、快速启动:一条正则开启 HLS 直播
HLS 插件的核心配置只有一个onpub.transform正则映射,格式为{分片时长} x {窗口大小}:
hls: onpub: transform: ^live/.+: 5s x 3 # live/ 开头的所有流:5秒分片,保留3个分片窗口这行配置生效后的效果:
| 配置项 | 含义 | 建议值 |
|---|---|---|
5s | TS 分片时长 | 2~6s,越短延迟越低 |
3 | 播放列表窗口(已完成的分片数) | 2~6,越大越抗弱网 |
配置完成后,任何发布到live/xxx的流,立即可通过以下地址播放:
http://{host}:8080/hls/live/xxx.m3u8(直播列表)http://{host}:8080/hls/live/xxx/{segment}.ts(TS 分片)
内置播放器,开箱即验
Monibuca 在 plugin/hls/index.go 中把 hls.js 演示页面打包进了二进制,无需任何额外部署:
http://{host}:8080/hls/index.html—— 全功能 Demohttp://{host}:8080/hls/basic-usage.html—— 入门示例http://{host}:8080/hls/metrics.html—— 延迟、缓冲等指标可视化
浏览器打开即播,是新手验证配置最快的方式 ✅
流还没推上来?用 timeout 等它上线
请求 m3u8 时可附加?timeout=30s参数:插件会先内部订阅等待流上线(最长 30 秒)再返回播放列表,避免"流还没到、列表却是空的"。处理逻辑见 plugin/hls/index.go 的ServeHTTP。
三、拉取远端 HLS 流:把别人家的直播变成自己的
如果你要转推第三方平台的 HLS 流(比如央视、地方电视台),只需配置pull或在管理界面创建拉流任务:
hls: pull: live/apple-demo: url: https://example.com/stream.m3u8 relaymode: mix # remux(默认重封装)/ relay(原样转发)/ mix(两者都要)一个典型示例见 example/8080/pull_hls.yaml。拉流器会自动解析主播放列表、跟进多码率分支、下载最新 TS 分片,并在 Monibuca 内重新发布为内部流——之后再走 RTMP、WebRTC 分发都畅通无阻。
四、录像与点播:按时间段"回看"直播
4.1 启动录像(两种姿势)
方式一:配置式,复用record配置:
hls: onpub: record: ^live/.+: filepath: record/$0 # $0 自动替换为流路径 fragment: 1m # 每 1 分钟一个 TS 文件方式二:REST API 动态启停,适合业务系统按需录制:
# 启动录像(30s 分片),返回任务 ID curl -X POST "http://localhost:8080/hls/api/record/start/live/demo?fragment=30s" # 停止录像 curl -X POST http://localhost:8080/hls/api/record/stop/{id}实现位于 plugin/hls/index.go 的API_record_start/API_record_stop。
4.2 时间范围点播:m3u8 里的"时光机"
启用数据库后,所有录像都会登记到RecordStream元数据表。此时点播接口就变成了时间查询接口:
GET /vod/live/demo.m3u8?start=2026-10-01T08:00:00&end=2026-10-01T09:00:00 GET /vod/live/demo.m3u8?range=1759286400-1759290000插件会从数据库查出该时间段内的录像记录,动态拼出一份带#EXT-X-ENDLIST(点播结束标记)的 m3u8。核心逻辑在 plugin/hls/index.go 的vod处理函数。
4.3 TS 时间段下载
浏览器下载整个时间段的历史 TS,一个请求搞定:
GET /hls/download/live/demo.ts?start=1759286400&end=1759290000插件会把该时间段内多个 TS 文件拼接下发(并智能跳过分片间的重复 PAT/PMT 头);如果库里只有 MP4 录像,还会自动调用 MP4 解复用器实时转封装成 TS 输出。
五、fMP4 无缝播放:把首屏延迟打下来
传统 HLS 有个经典痛点:TS 封装笨重、必须等整个分片下载完才能播,首屏慢。fMP4(fragmented MP4,分片 MP4)则是现代答案——分片更小、无需等待、支持 Range 请求。
Monibuca 的 MP4 插件(plugin/mp4/pkg/)内置了完整的 fMP4 封装器,moof/mfra等动态 box 的实现在 plugin/mp4/pkg/box/moof.go 与 plugin/mp4/pkg/box/mfro.go,封装原理可延伸阅读 doc/fmp4.md。
fMP4 点播接口长这样:
GET /vod/fmp4.m3u8?start=...&end=...注意路径中的fmp4.m3u8这个"魔法文件名"——插件据此把recordType切到fmp4,生成的播放列表不再指向 TS,而是指向数据库中的 fMP4 录像记录:
#EXTINF:90.000,2026-10-01T08:00:00+08:00 /mp4/download/live/demo.fmp4?id=42每个条目直接落到单条录像记录的下载接口,播放器(hls.js 原生支持 fMP4)边下边播,首屏延迟和内存占用都显著优于 TS 方案。
💡 一句话总结:TS 分片 = 直播标配,fMP4 = 点播利器,Monibuca 用一套 m3u8 路由同时兼容两种封装。
六、进阶:LL-HLS 把延迟压到 2 秒以内
普通 HLS 的延迟下限受分片时长约束(5s 分片 ≈ 10~15s 延迟)。Monibuca 另注册了LL-HLS 插件(plugin/hls/llhls.go),基于 gohlslib 直接输出低延迟分片:
llhls: onpub: transform: ^live/.+: 1s x 7 # 1秒最小分片,保留7个- 访问地址:
http://{host}:8080/llhls/live/demo/index.m3u8 - 打开
http://{host}:8080/llhls/live/demo/index.html甚至能用原生<video>标签直接播(Safari 内置 LL-HLS 支持) - 默认总时移 < 2 秒,接近 RTMP 的延迟体验
对比一览:
| 方案 | 访问前缀 | 典型延迟 | 适用场景 |
|---|---|---|---|
| 标准 HLS | /hls/{stream}.m3u8 | 10~15s | 弱网友好、CDN 分发 |
| LL-HLS | /llhls/{stream}/index.m3u8 | <2s | 互动直播、监控回看 |
| 点播 | /vod/{stream}.m3u8?start=&end= | 即点即播 | 历史录像回放 |
七、常见问题速查
🔍 m3u8 返回空?确认发布者在线,且onpub.transform正则匹配流路径;加?timeout=30s给自动订阅留时间。
🔍 分片刚生成就被清理?窗口太小。把5s x 3调大到5s x 6,或拉流任务改用relaymode: mix。
🔍 点播下载 404?点播依赖数据库定位录像文件——先确认数据库已启用且RecordStream表有对应记录。
🔍 跨域播放失败?/hls是标准 HTTP 接口,跨域需自行在反向代理配置 CORS。
八、总结
| 能力 | 接口 / 配置 | 源码位置 |
|---|---|---|
| 直播输出 | /hls/{stream}.m3u8 | plugin/hls/pkg/writer.go |
| 远端拉流 | hls.pull | plugin/hls/pkg/pull.go |
| 录像启停 | /hls/api/record/start|stop | plugin/hls/index.go |
| 时间范围点播 | /vod/{stream}.m3u8?start=&end= | plugin/hls/index.go |
| fMP4 点播 | /vod/fmp4.m3u8 | plugin/mp4/pkg/muxer.go |
| 低延迟 LL-HLS | /llhls/{stream}/index.m3u8 | plugin/hls/llhls.go |
Monibuca 把 HLS 直播、TS 分片、录像点播、fMP4 无缝播放、LL-HLS 低延迟全部装进一个轻量 Go 二进制里,配置几行 YAML 即可上线。更多细节欢迎翻阅 plugin/hls/README_CN.md 完整插件文档。🚀
【免费下载链接】monibucaMonibuca(简称 m7s)是一款纯 Go 开发的开源流媒体服务器开发框架。项目地址: https://gitcode.com/langhuihui/monibuca
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考