ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

go2rtc Bubble 私有流协议解析:从 dvr163 / eseecloud 摄像头接入到帧级协议实现

go2rtc Bubble 私有流协议解析:从 dvr163 / eseecloud 摄像头接入到帧级协议实现 go2rtc Bubble 私有流协议解析从 dvr163 / eseecloud 摄像头接入到帧级协议实现【免费下载链接】go2rtcUltimate camera streaming application项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc本篇以 go2rtc 仓库中的 internal/bubble/README.md 为主体完整覆盖 Bubble 私有流格式的接入配置URL 语法、参数缺省规则并结合 pkg/bubble/client.go 与 pkg/bubble/producer.go 的源码实现讲清从 TCP 握手、认证包构造、媒体包解包到 RTP 封帧的完整链路。读完后你将能够为 dvr163.com / eseecloud.com 系设备正确配置bubble://源理解该私有协议的报文结构与默认值来源并知道 go2rtc 如何把它转成内部可复用的视频/音频轨。1. Bubble 是什么Bubble 是少数 dvr163.com 与 eseecloud.com 品牌摄像头/NVR 使用的私有流传输格式内部包注释中给出的线索请求 URL 为/bubble/live?ch0stream0响应Content-Type为video/bubble见 client.go 的包注释。它对外的传输载体是普通 TCP HTTP 请求头但其后的数据流是自定义的二进制包头封装既不是标准 RTSP 也不是 MJPEG因此需要专门的 producer 才能被 go2rtc 拉流。go2rtc 在 v1.6.1 版本引入了该格式README 中标注new in v1.6.1。协议支持视频编码为 H.264 或 H.265HEVC音频为 G.711 A-lawPCMA这一点可以从协议实现中交叉印证pkg/README.md 的协议一览表里bubble一行的编码列为h264, hevc, pcm_alaw传输协议列为http。2. 快速开始配置一个 bubble 源按照 internal/bubble/README.md 给出的配置规则username、password、port、ch、stream在取默认值时可以省略不同通道 / 不同码流应配置成不同的 stream 条目。streams: camera1: bubble://username:password192.168.1.123:34567/bubble/live?ch0stream0URL 各部分的含义与默认行为以源码为准字段示例说明schemebubble://触发 bubble 协议的 URL 处理器见 internal/bubble/bubble.gousername / passwordusername:passwordURL userinfo 中的账号密码源码中当 URL 未携带用户时用户名默认填充为adminclient.gohost192.168.1.123设备地址port34567设备私有流端口README 说明其为默认值时可省略path/bubble/live私有 HTTP 请求路径设备端据此返回video/bubblech0通道号对应源码中的c.channel默认 0stream0码流号如主/子码流对应源码中的c.stream默认 0ch与stream的解析逻辑在 Dial() 中先解析stream缺省为0再据此从设备返回的 XML 中匹配对应码流条目最后解析ch。配置完成后该 stream 即可被 go2rtc 的标准消费端复用RTSP、WebRTC、HLS 等这与其它协议源的行为一致协议本身只负责“生产”媒体轨。3. 协议注册从 main.go 到 bubble.DialBubble 的接入遵循 go2rtc “internal 薄壳 pkg 协议实现”的分层程序入口 main.go 中注册了{bubble, bubble.Init}internal/bubble/bubble.go 的Init()调用streams.HandleFunc(bubble, ...)把bubble://这一 scheme 映射到 producer 构造函数构造器直接调用 pkg/bubble 的 Dial() 完成拨号返回的*Client实现了core.Producer接口交由 streams 层管理生命周期。*Client内嵌core.Listener并提供GetMedias()/GetTrack()/Start()/Stop()/Close()等接口client.go源码注释标注其为旧式接口Deprecated: should be rewritten to core.Connection从源码结构看后续版本可能迁移到core.Connection抽象。4. 连接与认证流程Dial 阶段Dial() 实现了整个握手共四步全部超时统一为 5 秒const Timeout time.Second * 5第 1 步TCP 连接 HTTP GET。解析 URL 后net.DialTimeout建立 TCP 连接然后用 go2rtc 自实现的轻量 HTTP 客户端发送GET /bubble/live?ch0stream0 HTTP/1.1请求client.go要求响应状态为 200否则报wrong response。第 2 步读取 1024 字节 XML 描述。响应体先读固定 1024 字节源码注释特别指出部分设备恰好返回 1024 字节但有些设备返回 923 字节因此这里是“尽力读取”而非精确按长度读取client.go。该 XML 描述了设备能力形如bubble version1.0 vin1vin0 stream2 stream0 name720p.264 size2304x1296 x1yes x2yes x4yes / stream1 name360p.265 size640x360 x1yes x2yes x4yes / vin0 /bubble见 client.go 的注释示例。第 3 步发送 48 字节认证包。结构为size uint32(44) 未知 4 字节 username 20 字节 password 20 字节用户名不足 20 字节以零填充未提供用户名时默认写adminclient.go。该包以PacketAuth0x00命令字、固定时间戳0x0E16C271封装发出。第 4 步校验认证响应并解析码流编码。设备回一个 44 字节负载的PacketAuth包源码校验b[4] 3 b[8] 1两个魔数不满足则报wrong auth responseclient.go。随后用正则stream{N} [^]从 XML 中取出所选码流条目按名字是否包含.265决定视频编码为 H.265 还是 H.264client.go。命令字常量定义在 client.go常量值用途SyncByte0xAA每个包的同步头PacketAuth0x00认证包PacketMedia0x01媒体数据包PacketStart0x0A开始播放Play命令5. 报文封装Write / ReadBubble 所有二进制交互共用同一套 10 字节包头封装大端序client.go0xAA | size uint32 | cmd byte | timestamp uint32 | payload (size 5 len(payload))Write(command, timestamp, payload)负责按上述布局打包并写 socketRead()先读满 10 字节头校验首字节必须为0xAA否则wrong start byte再按size - 1 - 4读出 payload返回命令字与负载。包头中size字段统计的是“cmd timestamp payload”的长度即5 len(payload)这是解析该协议时最容易被算错的一处。6. 开始播放与媒体数据处理Play / HandleStart()的调用链是Play()→Handle()producer.go。Play 命令。Play() 发送PacketStart0x0A包16 字节负载为小端序三个 uint32channel、stream、1表示 opened时间戳魔数为0x0E16C2DF。源码注释特别强调“yeah, theres no mistake about the little endian”——认证与包头是大端而 Play 负载是小端属于该私有协议的既定怪异之处。Handle 主循环。Handle() 无限读取包仅处理PacketMedia其余命令字直接丢弃。媒体包 payload 的前 6 字节为公共头size uint32 type 1b channel 1b其中type的语义为1 关键帧、2 普通帧、0 音频。视频b[4] 0b[6:]是 AnnexB 格式的一帧经annexb.EncodeToAVCC转成 AVCC长度前缀格式后封装为 RTP 包90kHz 时间戳写入视频轨音频b[4] 0负载前 36 字节是音频元信息头条目数、大小、PTS、G.711 魔数g711、采样率、采样宽度见 client.go 的注释实际 PCM A-law 数据从b[636:]开始按帧长累加 RTP 时间戳后写入音频轨。只有在对应 receiver 已建立videoTrack/audioTrack非 nil时才写帧未就绪的帧直接丢弃。7. Producer 接口媒体轨声明与 API 输出GetMedias() 向 streams 层声明两条只接收recvonly媒体轨轨编码时钟负载类型视频H.264 或 H.265Dial 阶段由 XML 判定90000 HzPayloadTypeRAWRAW 视频负载音频PCMAG.711 A-law8000 HzPayloadType 8GetTrack()按需创建core.Receiver并回填videoTrack/audioTrack指针供 Handle 主循环写帧producer.go。Stop()则先关闭所有 receiver 再断连。MarshalJSON() 把连接状态序列化进 go2rtc 的/api接口format为bubble、protocol为http并附带远端地址与累计接收字节数Recv便于在 API/Net 页面观察这条私有流的实时状态。bubble也已列入 www/schema.json 的合法 scheme 白名单Web UI 中配置时可获得语法校验。8. 使用限制与注意事项超时拨号、每次读写均使用 5 秒超时Timeout常量弱网环境下认证失败会以超时错误呈现设备兼容性1024 字节 XML 头部存在“923 字节”的变体设备解析依赖设备在头部返回正确的streamN条目若设备固件行为偏离Dial 阶段会报wrong auth response或正则匹配失败编码范围仅支持 H.264/H.265 视频 G.711 A-law 音频GetMedias的声明范围其余编码的 bubble 设备不在当前实现覆盖内同品牌其它协议eseecloud 设备另有标准的 eseecloud:// 接入方式eseecloud://user:passhost:80/livestream/12当设备走标准流时优先使用该协议bubble 面向的是私有video/bubble数据面。9. 相关文件索引文件作用internal/bubble/README.md本文主体bubble 源的配置说明internal/bubble/bubble.go注册bubble://schemepkg/bubble/client.go连接、认证、报文读写、Play/Handle 核心实现pkg/bubble/producer.go媒体轨声明、producer 生命周期与 JSON 状态main.go模块初始化注册点pkg/README.md协议能力一览表bubble 行【免费下载链接】go2rtcUltimate camera streaming application项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表