go2rtc 媒体格式 / 协议 / 编解码器全览:Producers、Consumers 与 Snapshots 支持矩阵
【免费下载链接】go2rtcUltimate camera streaming application项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc
go2rtc(Ultimate camera streaming application)是一个以 Go 编写的流媒体应用,其pkg/目录承载着全部媒体格式与协议的编解码实现。本文基于 pkg/README.md 的核心命名约定与三张支持矩阵(输入 Producers、输出 Consumers、快照 Snapshots),结合main.go、internal/README.md、pkg/core/core.go等源码,系统梳理 go2rtc 对音视频格式、传输协议与编解码器的完整支持面,帮助你快速判断某一路流应该用什么格式接入、用哪个 API 输出,以及如何在 go2rtc 中新增一种自定义格式。
命名约定:向 FFmpeg 看齐,兼容其术语体系
go2rtc 在设计上刻意让格式(format)、协议(protocol)与编解码器(codec)的命名方式与 FFmpeg 保持一致:
go2rtc tries to name formats, protocols and codecs the same way they are named in FFmpeg. Some formats and protocols go2rtc supports exclusively. They have no equivalent in FFmpeg.
这一约定带来的直接收益是:熟悉 FFmpeg 的用户几乎不需要学习成本就能读懂 go2rtc 的配置与 API。例如rtsp:、rtmp:、hls、adts、mpegts、pcm_alaw、pcm_mulaw等术语,在 FFmpeg 生态中含义相同。同时 go2rtc 也有一些 FFmpeg 没有的独占格式与协议(如bubble:、doorbird:、eseecloud:等私有云/私有设备协议),它们会在下文各矩阵中体现。
Producers(输入):四大角色与全量支持矩阵
在 go2rtc 的输入侧,连接发起方与数据流向决定了模块的角色:
- Source protocols(源协议):连接由 go2rtc 主动发起,即 go2rtc 作为客户端去拉取远端流;
- Ingress protocols(入站协议):连接由外部程序发起,go2rtc 作为服务端接收外部推流(对应内部架构中的 ingest 能力);
- Receiver codecs(接收编解码器):编解码器是"进来"的,即 go2rtc 接收并解码该编码的媒体;
- Sender codecs(发送编解码器):编解码器是"出去"的,即 go2rtc 向外发送该编码的媒体,用于双向音频(two-way audio)等场景。
Producers 完整矩阵
| Group | Format | Protocols | Ingress | Receiver codecs | Sender codecs | Example |
|---|---|---|---|---|---|---|
| Devices | alsa | pipe | pcm | alsa: | ||
| Devices | v4l2 | pipe | v4l2: | |||
| Files | adts | http, tcp, pipe | http | aac | http: | |
| Files | flv | http, tcp, pipe | http | h264, aac | http: | |
| Files | h264 | http, tcp, pipe | http | h264 | http: | |
| Files | hevc | http, tcp, pipe | http | hevc | http: | |
| Files | hls | http | h264, h265, aac, opus | http: | ||
| Files | mjpeg | http, tcp, pipe | http | mjpeg | http: | |
| Files | mpegts | http, tcp, pipe | http | h264, hevc, aac, opus | http: | |
| Files | wav | http, tcp, pipe | http | pcm_alaw, pcm_mulaw | http: | |
| Net (pub) | mpjpeg | http, tcp, pipe | http | mjpeg | http: | |
| Net (pub) | onvif | rtsp | onvif: | |||
| Net (pub) | rtmp | rtmp | rtmp | h264, aac | rtmp: | |
| Net (pub) | rtsp | rtsp, ws | rtsp | h264, hevc, aac, pcm*, opus | pcm*, opus | rtsp: |
| Net (pub) | webrtc* | webrtc | webrtc | h264, pcm_alaw, pcm_mulaw, opus | pcm_alaw, pcm_mulaw | webrtc: |
| Net (pub) | yuv4mpegpipe | http, tcp, pipe | http | rawvideo | http: | |
| Net (priv) | bubble | http | h264, hevc, pcm_alaw | bubble: | ||
| Net (priv) | doorbird | http | doorbird: | |||
| Net (priv) | dvrip | tcp | h264, hevc, pcm_alaw, pcm_mulaw | pcm_alaw | dvrip: | |
| Net (priv) | eseecloud | http | eseecloud: | |||
| Net (priv) | gopro | udp | TODO | gopro: | ||
| Net (priv) | hass | webrtc | TODO | hass: | ||
| Net (priv) | homekit | hap | h264, eld* | homekit: | ||
| Net (priv) | isapi | http | pcm_alaw, pcm_mulaw | isapi: | ||
| Net (priv) | kasa | http | h264, pcm_mulaw | kasa: | ||
| Net (priv) | nest | rtsp, webrtc | TODO | nest: | ||
| Net (priv) | ring | webrtc | ring: | |||
| Net (priv) | roborock | webrtc | h264, opus | opus | roborock: | |
| Net (priv) | tapo | http | h264, pcma | pcm_alaw | tapo: | |
| Net (priv) | tuya | webrtc | tuya: | |||
| Net (priv) | vigi | http | vigi: | |||
| Net (priv) | webtorrent | webrtc | TODO | TODO | TODO | webtorrent: |
| Net (priv) | xiaomi* | cs2, tutk | xiaomi: | |||
| Services | flussonic | ws | flussonic: | |||
| Services | ivideon | ws | h264 | ivideon: | ||
| Services | yandex | webrtc | yandex: | |||
| Other | echo | * | echo: | |||
| Other | exec | pipe, rtsp | exec: | |||
| Other | expr | * | expr: | |||
| Other | ffmpeg | pipe, rtsp | ffmpeg: | |||
| Other | stdin | pipe | pcm_alaw, pcm_mulaw | stdin: |
矩阵注释(Codec 组定义)
- eld:aac 编解码器的罕见变体(AAC-ELD,常见于 HomeKit 视频门铃/对讲场景),见 pkg/core/core.go 中的
CodecELD = "ELD"定义; - pcm:指
pcm_alaw、pcm_mulaw、pcm_s16be、pcm_s16le四种 PCM 变体; - webrtc:指 WebRTC 在 go2rtc 中的一系列专有客户端变体:
webrtc/kinesis、webrtc/openipc、webrtc/milestone、webrtc/wyze、webrtc/whep。
从源码看 Producers 的角色划分
矩阵中四类角色的划分并非文档发明,而是直接体现在核心接口上。pkg/core/core.go 定义了Producer接口:
type Producer interface { // GetMedias - return Media(s) with local Media.Direction: // - recvonly for Producer Video/Audio // - sendonly for Producer backchannel GetMedias() []*Media // GetTrack - return Receiver, that can only produce rtp.Packet(s) GetTrack(media *Media, codec *Codec) (*Receiver, error) // Deprecated: rename to Run() Start() error // Deprecated: rename to Close() Stop() error }注释清楚地说明了"双向音频"(backchannel)在实现上的落点:普通 Producer 的 Media 方向是recvonly(接收远端视频/音频),而回传通道(Sender codecs)的 Media 方向是sendonly。以 RTSP 为例,pkg/rtsp/producer.go 中的GetTrack在core.ModeActiveProducer(go2rtc 主动拉流)与core.ModePassiveConsumer(backchannel 回传)两种模式下分别分配 RTP 通道,正是矩阵中rtsp同时具备 Receiver codecs(h264、hevc、aac、pcm*、opus)与 Sender codecs(pcm*、opus)的实现依据。
另外注意 Devices 分组:alsa与v4l2都使用pipe协议(本地设备走管道),其中alsa同时具备pcm的 Sender codecs,说明 go2rtc 支持通过 ALSA 设备进行音频采集与回放(双向音频),对应实现位于 pkg/alsa 与 internal/alsa。
Consumers(输出):格式、协议与 API 端点
输出侧(Consumers)矩阵列出了 go2rtc 对外提供流服务的所有方式,其中 "Send codecs" 是 go2rtc 向客户端发送的编码,"Recv codecs" 是 go2rtc 从客户端接收的编码(同样服务于双向音频等场景):
| Format | Protocol | Send codecs | Recv codecs | Example |
|---|---|---|---|---|
| adts | http | aac | GET /api/stream.adts | |
| ascii | http | mjpeg | GET /api/stream.ascii | |
| flv | http | h264, aac | GET /api/stream.flv | |
| hls/mpegts | http | h264, hevc, aac | GET /api/stream.m3u8 | |
| hls/fmp4 | http | h264, hevc, aac, pcm*, opus | GET /api/stream.m3u8?mp4 | |
| homekit | hap | h264, opus | Apple HomeKit app | |
| mjpeg | ws | mjpeg | {"type":"mjpeg"}->/api/ws | |
| mpjpeg | http | mjpeg | GET /api/stream.mjpeg | |
| mp4 | http | h264, hevc, aac, pcm*, opus | GET /api/stream.mp4 | |
| mse/fmp4 | ws | h264, hevc, aac, pcm*, opus | {"type":"mse"}->/api/ws | |
| mpegts | http | h264, hevc, aac | GET /api/stream.ts | |
| rtmp | rtmp | h264, aac | rtmp://localhost:1935/{stream_name} | |
| rtsp | rtsp | h264, hevc, aac, pcm*, opus | rtsp://localhost:8554/{stream_name} | |
| webrtc | webrtc | h264, pcm_alaw, pcm_mulaw, opus | pcm_alaw, pcm_mulaw, opus | {"type":"webrtc"}->/api/ws |
| yuv4mpegpipe | http | rawvideo | GET /api/stream.y4m |
其中pcm同样指pcm_alaw、pcm_mulaw、pcm_s16be、pcm_s16le。
输出侧的三个观察点
- HTTP API 是主输出通道:绝大多数输出格式通过 HTTP REST 端点暴露,形式统一为
GET /api/stream.{format},由 internal/api/api.go 与各输出模块(internal/hls、internal/mp4、internal/mjpeg、internal/mpeg 等)共同实现;前端 Web UI 中的播放器(www 目录)正是通过这些端点拉流。 - WebSocket 通道承载交互式协议:
mjpeg、mse/fmp4、webrtc三种输出都通过{"type":"..."}的 JSON 消息路由到/api/ws,由 internal/api/ws/ws.go 统一处理;其中webrtc是唯一同时具备 Recv codecs 的输出格式(支持pcm_alaw、pcm_mulaw、opus回传),即浏览器端经 WebRTC 实现双向音频。 - RTSP/RTMP 同时是输入与输出:
rtsp://localhost:8554/{stream_name}与rtmp://localhost:1935/{stream_name}既可被 go2rtc 拉取(Source),也可由 go2rtc 对外分发(输出),对应 internal/rtsp 与 internal/rtmp 中 server 与 client 的双重实现。
Snapshots(快照):单帧抓取接口
go2rtc 还提供两种轻量级快照端点,适合门禁联动、缩略图、定时抓帧等场景:
| Format | Protocol | Send codecs | Example |
|---|---|---|---|
| jpeg | http | mjpeg | GET /api/frame.jpeg |
| mp4 | http | h264,hevc | GET /api/frame.mp4 |
GET /api/frame.jpeg:以 MJPEG 编码输出一帧 JPEG 图片;GET /api/frame.mp4:输出一小段 MP4 视频(h264/hevc 编码),通常作为"几秒短视频快照"使用。
两者均由 internal/mjpeg / internal/mp4 模块承载,与 Web UI 的实时预览共用同一套流媒体管线。
Developers:如何新增一种格式(源码结构约定)
对于想在 go2rtc 中接入新设备/新格式的开发者,pkg/README.md给出了清晰的文件命名规范(File naming):
pkg/{format}/producer.go—— 该格式的 producer 实现(若支持 backchannel,backchannel 能力也在此文件内);pkg/{format}/consumer.go—— 该格式的 consumer 实现;pkg/{format}/backchannel.go—— 仅含 backchannel 功能的 producer。
这与实际仓库结构完全吻合,例如 RTSP 模块 pkg/rtsp 下同时存在producer.go、consumer.go、helpers.go;而仅做回传通道的模块如 pkg/doorbird/backchannel.go、pkg/tapo/backchannel.go、pkg/xiaomi/miss/backchannel.go 则遵循backchannel.go的独立命名约定。
新增模块时需要同步"提及"的位置(Mentioning modules)
文档明确列出,新增/修改一个模块时,需要同步更新以下文件中与该模块相关的注册或引用信息:
- main.go —— 模块的
Init注册列表(源码中以modules := []module{...}的形式按分组顺序执行初始化,例如 HTTP/RTSP/WebRTC 作为 Main sources 最先注册,硬件源与私有云源随后注册); - README.md —— 项目主文档中的功能说明;
- internal/README.md —— 模块-格式-协议对照总表(该表进一步把模块细分为 "Modules 实现通信 API"、"Formats 描述数据结构"、"Protocols 实现传输",并在 internal/README.md 中列出每个模块的 formats、protocols、input/output/ingest/two-way 能力);
- website/.vitepress/config.js —— 文档站点的侧边栏导航(注意该配置中
srcDir: '..'且srcExclude: ['examples/', 'pkg/'],即文档站点从仓库根目录构建,但pkg/目录被排除在站点之外,属于内部实现层); - website/api/openapi.yaml —— API 的 OpenAPI 描述文件;
- www/schema.json —— 前端 Web UI 的配置 schema。
其中 main.go 的模块注册顺序值得一提:它先初始化app(配置与日志)、api与ws(API 端点)、streams(流管理核心),然后是 "Main sources and servers"(http、rtsp、webrtc),再是 "Main API"(mp4、hls、mjpeg),最后是各类脚本源、硬件源与私有云源。新增格式若需要服务端能力(如监听端口),必须参考这一顺序在合适的位置注册Init。
总结
pkg/README.md本质上是一张 go2rtc 的"能力全景图":输入侧按 Devices / Files / Net (pub) / Net (priv) / Services / Other 六个分组,输出侧按 Format-Protocol-API 三元组,加上 JPEG/MP4 快照端点,共同构成了完整的媒体接入与分发体系。搭配 pkg/core/core.go 的Producer/Consumer接口、main.go 的模块注册顺序以及 internal/README.md 的模块能力总表,你可以快速判断:
- 某路摄像头(RTSP/ONVIF/私有云)该用哪个
xxx:前缀接入; - 浏览器、播放器、Home Assistant 等下游分别该走哪个
/api/stream.*端点; - 双向往来(双向音频、语音回传)依赖哪些 Sender/Recv codecs;
- 新协议接入时该在
pkg/下如何组织producer.go/consumer.go/backchannel.go文件,以及需要同步修改哪些注册与文档文件。
【免费下载链接】go2rtcUltimate camera streaming application项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考