live-multi

command
v0.3.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 6, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

live-multi —— 多路直播 + 多路流管理(Hub)+ OTel 指标

一个 RTMP 端口收多路流,按 streamKey 各自成流、各自分发,用 pkg/media.Hub 做注册表/生命周期/路由 + OTel 运维指标。每路 HLS 由 pkg/media/hlsmux(gohlslib)产出 LL-HLS,不转码。

推 /live/roomA ─┐
推 /live/roomB ─┼─▶ rtmp.Server ─▶ Hub.Acquire(key) ─▶ hlsmux.Bridge(→LL-HLS)
                ┘                         │
              播放 /live/roomA/index.m3u8 ◀── Hub 按 key 路由

Hub 现在是泛型 Hub[S media.Stream](Stream = http.Handler + Finish()),这里的 S*hlsmux.Bridge;换成 *hls.Stream 即回到自研 origin。Bridge 同时是 rtmp.Handler(收流) 与 http.Handler(播放),所以一个对象既进 Acquire 收流、又被 Hub 路由分发。

Hub 提供的薄机制:

  • 多路管理:Acquire(key) 抢占一路(重复 key 被拒,防抢流)、Release(key) 回收、Count()Lookup()
  • 路由:Hub 实现 http.Handler,/{key}/index.m3u8/{key}/segN.ts 自动路由到该路 Stream
  • 生命周期:Session.Context()Release 时取消——把 ffmpeg Supervisor 等后台任务绑上去即随流停机。
  • OTel 指标:media.streams.activemedia.publish.totalmedia.publish.rejectedmedia.ingest.bytes 等,走全局 MeterProvider,配了 telemetry 才导出,否则 no-op。

运行

go run ./examples/live-multi
# 推两路(不同 key):
ffmpeg -re -stream_loop -1 -i a.mp4 -c:v libx264 -c:a aac -f flv rtmp://localhost:1935/live/roomA
ffmpeg -re -stream_loop -1 -i b.mp4 -c:v libx264 -c:a aac -f flv rtmp://localhost:1935/live/roomB
# 播放 / 看在线流:
ffplay http://localhost:8090/live/roomA/index.m3u8
curl   http://localhost:8090/streams

Supervisor(转码进程崩溃重启)怎么配

pkg/media.Supervisor 是通用的子进程监督(启动/退避重启/优雅停),把它绑到 Session.Context() 即随该路流停机:

sess, _ := hub.Acquire(key)
sup := media.NewSupervisor(
    func() *exec.Cmd { return exec.Command("ffmpeg", args...) }, // 命令构造是 policy
    media.WithSupervisorMetrics(hub.Metrics(), key),             // 重启计入 media.transcode.restarts
)
go sup.Run(sess.Context()) // Release 时自动停

适用边界(重要):Supervisor 的"崩溃重启"适合 ffmpeg 从可重连的源拉流/读稳定输入 (RTMP URL、文件、FIFO)的拓扑——崩了重启能自动重连。而把 FLV 管道喂给 ffmpeg stdin 的方式,进程一旦崩、输入管道即断,正确做法是结束本次推流、等推流端重推(而非原地重启)。 本示例走不转码路径(gohlslib 直接封装)不涉及转码进程;要 stdin 管道转码见 examples/live-transcode,要带重启的转码请用"拉流/读文件"式输入。

边界

  • 转码档位、ffmpeg 参数、导出器(Prometheus/OTLP)、鉴权 token 体系 —— 都是 policy,不在框架内。
  • 存储:gohlslib 分片默认在内存,hlsmux.WithDirectory 可落盘给 CDN 回源(注:LL-HLS variant 不支持落盘)。要可插拔对象存储(hls.WithStore)得用 *hls.Stream 那条路径——把 Hub 的 S 换成 *hls.Stream 并自行喂分片。多副本部署另需按 key 粘连路由。

Documentation

Overview

live-multi demo:多路直播——一个 RTMP 端口收多路流,按 streamKey 各自成流、各自分发, 用 pkg/media.Hub 做多路管理 + OTel 指标,每路 HLS 由 pkg/media/hlsmux(gohlslib)产出 LL-HLS。

OBS/ffmpeg(推 /live/roomA)─┐
OBS/ffmpeg(推 /live/roomB)─┼─▶ rtmp.Server ─▶ Hub.Acquire(key) ─▶ hlsmux.Bridge(→LL-HLS)
                            ┘                        │
                     播放 /live/roomA/index.m3u8 ◀── Hub 按 key 路由分发

运行:

go run ./examples/live-multi

推两路(不同 streamKey → 两路互不干扰):

ffmpeg -re -stream_loop -1 -i a.mp4 -c:v libx264 -c:a aac -f flv rtmp://localhost:1935/live/roomA
ffmpeg -re -stream_loop -1 -i b.mp4 -c:v libx264 -c:a aac -f flv rtmp://localhost:1935/live/roomB

播放:

ffplay http://localhost:8090/live/roomA/index.m3u8
curl   http://localhost:8090/streams          # 当前在线流数

指标:所有 media.* 指标走 OTel 全局 MeterProvider。配好导出器(OTLP/Prometheus)后即可 采集 media.streams.active / media.ingest.bytes 等;未配置时为 no-op。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL