#2505·go2rtc

GET /api/streams 使用 `microphone` 参数重新连接每个正在播放的 RTSP 生产者,其 SDP 中包含单向音频(AddTrack 不会匹配已匹配的去重,与 GetTrack 不同)

作者: emacboros创建于 2026年9月17日更新于 2026年9月17日
  • go2rtc 与一个 RTSP 生产者,其中既有 recvonly 音频(摄像头流),也有 sendonly 音频(扬声器/背景通道)媒体 — — 这通常发生在支持双向音频的摄像头上(我们在 thingino 摄像头上看到这种情况:SDP 传输 audio, recvonly, MPEG4-GENERIC/16000 以及 audio, sendonly, MPEG4-GENERIC/16000|PCMU|PCMA)。
  • 该流上的一个正在播放的消费者(go2rtc 重新传输的 frigate ffmpeg)。
  • 然后:
bash
curl "http://go2rtc:1984/api/streams?src=<cam>&video=all&audio=all&microphone="

观察到:生产者的 RTSP 会话被重新创建(在摄像头上创建新会话,RTSP 重连 事件,现有消费者的流中断并重新启动)。重复 GET 重新创建重连 — — 没有状态使第二个探测器具有等效性。 没有 microphone 参数的同一 GET 不会重新连接:视频/音频探测器媒体与 GetTrack 指针相等的重复检测(在 streams.Producer Wrapper 级别和 conn.GetTrack 中均如此)。

机制(源代码分析,v1.9.10 == v1.9.14 == master 为以下所有文件)

  1. internal/streams/api.go GET 分支:probe.Create("probe", query) — — microphone 参数创建了一个 recvonly 音频媒体(使用 CodecAnypkg/probe/consumer.go),然后 stream.AddConsumer(cons)
  2. internal/streams/add_consumer.go:对于每个消费者媒体,匹配与生产者媒体。麦克风媒体(recvonly)与生产者的 sendonly 音频媒体匹配(CodecAny 与任何内容匹配,pkg/core/codec.go Codec.Match)。
  3. 生产者媒体是 sendonly -> 第 4/5 步:cons.GetTrack,然后 prod.AddTrack(prodMedia, prodCodec, track)
  4. internal/streams/producer.go Producer.AddTrack:没有重复检测 -> p.conn.(core.Consumer).AddTrack(...)
  5. pkg/rtsp/consumer.go Conn.AddTrack,ModeActiveProducer 分支:if c.state == StatePlay { c.Reconnect() } — — 无条件,不检查是否存在等效发送者…