HLS 服务器 - Monibuca 流媒体分发
HLS(HTTP Live Streaming)是 Apple 提出的基于 HTTP 的流媒体协议。通过将直播流切割为 TS 片段并生成 M3U8 播放列表,HLS 具有极佳的 CDN 兼容性和设备覆盖率,是大规模分发的首选协议。
| 属性 | 值 |
|---|---|
| 传输层 | HTTP(共享引擎 HTTP 端口) |
| 推流 | ❌ 不支持 |
| 拉流 | ✅ 支持 |
| 延迟 | 5-30 秒(取决于切片时长) |
| 配置节 | hls |
预编译二进制已内置该插件,在 config.yaml 中配置即可:
hls: enable: true segment_duration: 6 max_segments: 5 output_dir: "./hls" write_to_disk: true| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enable | bool | true | 是否启用 HLS 插件 |
segment_duration | u64 | 6 | TS 切片时长(秒) |
max_segments | usize | 5 | 播放列表保留的最大切片数 |
output_dir | string | "./hls" | 切片文件输出目录 |
write_to_disk | bool | true | 是否将切片写入磁盘 |
dvr_window | u32 | 0 | 按时长保留的 DVR/回看窗口(秒);0 = 关闭。与 max_segments(直播短尾)独立 |
DVR / 直播回看(opt-in)
Section titled “DVR / 直播回看(opt-in)”默认 dvr_window: 0,行为与原先一致:直播播放列表只保留 max_segments 个切片。
设置 dvr_window(秒)后,已完成的切片会按累计时长在本节点额外保留,不改写普通直播播放列表。玩家通过查询参数选择回看视图:
| 查询 | 行为 |
|---|---|
(无)或 _HLS_rewind=NO | 当前直播短尾(与关闭 DVR 时字节级一致) |
_HLS_rewind=YES | EXT-X-PLAYLIST-TYPE:EVENT,覆盖保留窗口内已完成切片(含正确的 MEDIA-SEQUENCE / discontinuity;LL-HLS 时含已完成 PART) |
hls: enable: true write_to_disk: true # DVR 必需;否则打 warning 并视为关闭 max_segments: 5 # 直播短尾(不变) dvr_window: 120 # 额外保留约 2 分钟# 直播GET /hls/live/show/index.m3u8
# 回看(EVENT)GET /hls/live/show/index.m3u8?_HLS_rewind=YESABR:在 master 上带 _HLS_rewind=YES 时,会把该查询传播到各档位媒体 URI;各档位 remuxer 独立按时长保留。
从 DVR 区间导出 VoD 快照
Section titled “从 DVR 区间导出 VoD 快照”已保留的 DVR 切片可以原子导出为稳定的 HLS VoD 资产:
curl -X POST "http://localhost:8180/hls/api/dvr/export" \ -H "Content-Type: application/json" \ -d '{ "stream_path": "live/show", "start": 120, "end": 135, "name": "show-highlight" }'请求字段:
| 字段 | 说明 |
|---|---|
stream_path | 源直播流路径 |
start / end | HLS EXT-X-MEDIA-SEQUENCE 范围,包含两端;必须仍在本节点 dvr_window 保留窗口内 |
name | 可选资产名;省略时自动生成 |
响应会返回 playlist_url,例如:
{ "status": "ok", "playlist_url": "/hls/vod/show-highlight/index.m3u8", "segment_count": 16, "duration": 48.0}导出时会先把选中的 .ts 切片硬链接到录制目录(跨文件系统失败时自动复制),写入临时 index.m3u8.tmp 后原子重命名为 index.m3u8。导出完成后,直播 DVR 清理不会影响该 VoD 资产。播放地址仍走 HLS 鉴权:
ffplay http://localhost:8180/hls/vod/show-highlight/index.m3u8ABR 多码率(opt-in)
Section titled “ABR 多码率(opt-in)”默认 abr: [](或不写 abr)时,行为与单码率一致:每个流路径只提供一份媒体播放列表。配置 hls.abr 后,可为逻辑主路径生成 multivariant master playlist,指向各档位的媒体 index.m3u8。
HLS 插件只组装 master;各档位码流需由 transcode 插件 的 onpub 输出(或其他方式)发布为独立子流后再由 HLS remux。
hls: enable: true abr: - master: live/show renditions: - path: live/show_720p bandwidth: 2500000 resolution: "1280x720" codecs: "avc1.64001f,mp4a.40.2" # 可选 - path: live/show_480p bandwidth: 1200000 resolution: "854x480"| 字段 | 说明 |
|---|---|
master | 逻辑主路径,对应 master URL 中的 {streamPath} |
renditions | 有序档位(建议高码率在前) |
path | 该档位媒体播放列表对应的流路径 |
bandwidth | #EXT-X-STREAM-INF:BANDWIDTH(bps,必填且 > 0) |
resolution | 可选,如 1280x720 |
codecs | 可选,RFC 6381 字符串 |
Master URL
Section titled “Master URL”规范地址:
GET /hls/<master>/master.m3u8示例:http://localhost:8180/hls/live/show/master.m3u8
当该 master 已配置 ABR 时,/hls/<master>/index.m3u8 与 /hls/<master>.m3u8 也会返回同一份 multivariant playlist(便于兼容旧客户端);规范入口仍是 master.m3u8。各档位媒体列表仍为 /hls/<rendition>/index.m3u8。
端到端示例(RTMP → 转码 → ABR)
Section titled “端到端示例(RTMP → 转码 → ABR)”- 推流:
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://localhost:1935/live/show - Transcode
onpub生成live/show_720p/live/show_480p(见 转码插件) - 配置上方
hls.abr - 播放器打开 master:
ffplay http://localhost:8180/hls/live/show/master.m3u8完整 YAML 片段:
transcode: enable: true onpub: "^live/show$": outputs: - target: "rtmp://127.0.0.1/live/show_720p" options: video_codec: "libx264" resolution: "1280x720" video_bitrate: 2500 audio_codec: "aac" audio_bitrate: 128 - target: "rtmp://127.0.0.1/live/show_480p" options: video_codec: "libx264" resolution: "854x480" video_bitrate: 1200 audio_codec: "aac" audio_bitrate: 96
hls: enable: true abr: - master: live/show renditions: - path: live/show_720p bandwidth: 2500000 resolution: "1280x720" codecs: "avc1.64001f,mp4a.40.2" - path: live/show_480p bandwidth: 1200000 resolution: "854x480"URL 格式
Section titled “URL 格式”M3U8 播放列表
Section titled “M3U8 播放列表”http://host:port/hls/{streamPath}/index.m3u8ABR master(已配置时):
http://host:port/hls/{masterPath}/master.m3u8http://host:port/hls/{streamPath}/{sequence}.ts示例:
http://localhost:8180/hls/live/test/index.m3u8http://localhost:8180/hls/live/test/0.ts使用 FFplay
Section titled “使用 FFplay”ffplay http://localhost:8180/hls/live/test/index.m3u8使用 VLC
Section titled “使用 VLC”- 打开 VLC,选择 媒体 → 打开网络串流
- 输入 URL:
http://localhost:8180/hls/live/test/index.m3u8 - 点击 播放
使用 hls.js 在浏览器中播放:
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script><video id="player" controls></video><script> const video = document.getElementById('player'); if (Hls.isSupported()) { const hls = new Hls(); hls.loadSource('http://localhost:8180/hls/live/test/index.m3u8'); hls.attachMedia(video); hls.on(Hls.Events.MANIFEST_PARSED, () => video.play()); } else if (video.canPlayType('application/vnd.apple.mpegurl')) { // Safari 原生支持 video.src = 'http://localhost:8180/hls/live/test/index.m3u8'; video.play(); }</script>HLS 录制
Section titled “HLS 录制”HLS 插件提供录制 API,可以将流录制为 HLS 格式(M3U8 + TS 文件):
录制播放列表在录制期间保持开放,停止时才写入 EXT-X-ENDLIST;所有已完成切片都会保留,不受直播 max_segments 滑动窗口限制。长时间录制前请规划并监控磁盘容量。
# 开始录制curl -X POST http://localhost:8180/hls/record/start/live/test
# 停止录制curl -X POST http://localhost:8180/hls/record/stop/live/test
# 查看录制列表curl http://localhost:8180/hls/record/list
# 查看录制状态curl http://localhost:8180/hls/record/status/live/test
# 查询历史录像curl http://localhost:8180/hls/record/records- 订阅流:当首次请求 HLS 播放列表时,插件自动订阅对应的流
- 切片生成:从流中持续读取帧数据,按
segment_duration切割为 TS 片段 - 播放列表更新:每生成一个新切片,自动更新 M3U8 播放列表
- 滑动窗口:保留最近
max_segments个切片,旧切片自动清理 - 存储策略:切片同时保存在内存和磁盘(取决于
write_to_disk配置)
HLS 的延迟主要由以下因素决定:
总延迟 ≈ segment_duration × (max_segments - 1) + 播放器缓冲优化建议:
# 低延迟配置hls: segment_duration: 2 max_segments: 3此配置下理论最低延迟约 4-6 秒。
# 1. 通过 RTMP 推流ffmpeg -re -i input.mp4 -c copy -f flv rtmp://localhost:1935/live/test
# 2. 通过 HLS 拉流ffplay http://localhost:8180/hls/live/test/index.m3u8
# 3. 也可以同时通过其他协议拉流ffplay http://localhost:8180/flv/live/test.flv联系我们