feat: implement token-based auto stream pulling

This commit is contained in:
2026-05-09 11:03:27 +08:00
parent 966ef512ab
commit 6ff71fded0
5 changed files with 270 additions and 7 deletions

View File

@@ -29,15 +29,17 @@ type streamProcess struct {
type StreamManager struct {
cfg *config.Config
puller *Puller // 可选的动态拉流客户端
frames chan<- Frame
processes map[string]*streamProcess // url -> {cmd, fps}
mu sync.Mutex
updates <-chan *config.Config
}
func NewStreamManager(cfg *config.Config, frames chan<- Frame, updates <-chan *config.Config) *StreamManager {
func NewStreamManager(cfg *config.Config, puller *Puller, frames chan<- Frame, updates <-chan *config.Config) *StreamManager {
return &StreamManager{
cfg: cfg,
puller: puller,
frames: frames,
processes: make(map[string]*streamProcess),
updates: updates,
@@ -45,7 +47,14 @@ func NewStreamManager(cfg *config.Config, frames chan<- Frame, updates <-chan *c
}
func (sm *StreamManager) Run(ctx context.Context) {
// Initial start
// 1. 动态拉流模式
if sm.puller != nil {
log.Println("stream: running in auto-pull mode")
sm.runAutoPullMode(ctx)
return
}
// 2. 静态配置模式
sm.applyStreams(ctx, sm.cfg.RTSPURLs, sm.cfg.InferFPS)
for {
@@ -60,6 +69,39 @@ func (sm *StreamManager) Run(ctx context.Context) {
}
}
// runAutoPullMode 动态拉流模式主循环
func (sm *StreamManager) runAutoPullMode(ctx context.Context) {
for {
select {
case <-ctx.Done():
sm.stopAll()
return
default:
}
// 从云端获取拉流地址
url, err := sm.puller.Pull()
if err != nil {
log.Printf("stream: pull failed: %v, retry in 10s", err)
time.Sleep(10 * time.Second)
continue
}
log.Printf("stream: got dynamic url=%s, starting ingestion", url)
// 启动该 URL 的拉流
sm.applyStreams(ctx, []string{url}, sm.cfg.InferFPS)
// 等待上下文结束或 URL 被移除(通常意味着需要重新 Pull
// 在 auto-pull 模式下,如果 ffmpeg 断开streamLoop 会自动重试,
// 但我们需要在这里监听 ctx或者等待 puller 心跳失败后重新拉取。
// 简单起见,这里阻塞直到 ctx 取消streamLoop 内部会处理 ffmpeg 重连。
// 如果 streamLoop 发现 URL 失效,会退出并删除 process。
<-ctx.Done()
sm.stopAll()
}
}
func (sm *StreamManager) applyStreams(ctx context.Context, urls []string, fps int) {
sm.mu.Lock()
defer sm.mu.Unlock()