ARTICLE DETAIL

资讯详情

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

OpenDisplay协议总览:pv3线规中的角色分工、传输绑定与帧结构

OpenDisplay协议总览:pv3线规中的角色分工、传输绑定与帧结构 OpenDisplay协议总览pv3线规中的角色分工、传输绑定与帧结构【免费下载链接】opendisplayFree, open-source Sidecar/Duet alternative — use your iPhone, iPad or Mac as a true second monitor for your primary Mac over USB or WiFi. Low latency H.264, Retina HiDPI, touch input.项目地址: https://gitcode.com/GitHub_Trending/op/opendisplayOpenDisplay 是一个免费、开源的第二显示器方案——它让你的 iPhone、iPad 或备用 Mac 通过 USB 或 WiFi 成为 Mac 的真正扩展屏支持低延迟 H.264 传输、Retina 高清与触摸输入。要理解它如何工作只需读懂它的线规wire protocol协议版本 pv3。本文将带你快速掌握 pv3 中的三件大事——角色分工谁监听、谁拨号、传输绑定WiFi 与 USB 如何统一成同一条 TCP 流、帧结构4 字节长度前缀如何区分视频与控制消息即使你是新手也能看懂整条数据通路。一、角色分工接收方监听 9000 端口发送方拨号这是整个协议中承重最大的架构决策也是 pv3 线规的第一条规则接收方Receiver永远在 TCP 端口 9000 上监听并广播自己的存在发送方Sender永远是主动连接的一端。为什么这样设计因为接收方固定为监听端发送方无论是走 WiFi拨号到发现的地址还是走 USB拨号到隧穿端口一条代码路径就能同时服务两种传输无需任何分支逻辑。此外还有三条配套规则规则说明单 TCP 连接视频、控制消息、遥测全部共用一条连接双向流动一次只服务一个发送方新连接到来时接收方会接管新连接、丢弃旧连接无 TLS、无鉴权设计目标是可信局域网与直连线缆建议开启 TCP_NODELAY 避免输入延迟代码中接收侧核心逻辑集中在 Shared/StreamReceiver.swift它同时被 iOS App 和 Mac 接收模式复用——这也是备用 Mac 当显示器功能的实现基础发送侧则见 Mac/MacSender.swift。二、传输绑定WiFi 与 USB 如何统一核心协议只关心接收方 9000 端口上的一条 TCP 字节流至于怎么找到这个端口就是所谓的绑定binding。pv3 目前定义了两种绑定2.1 WiFi / 局域网Bonjour 服务发现 接收方广播一个 BonjourmDNS/DNS-SD服务服务类型_opensidecar._tcp沿用项目最初的名字改名会让所有存量客户端失效设备名仅用于界面展示不能作为身份标识用户会改名名字可重复TXT 记录携带两个键id每次安装唯一的 UUID让发送方认出换了一条路还是同一台设备和pv协议版本缺失则视为 pv 1。2.2 USB 有线通过 usbmuxd 隧穿 对于插线的 iPhone/iPad发送方通过 macOS 自带的usbmuxd设备多路守护进程发起Connect直接打到设备上的 TCP 9000 端口。收到OK之后这条 socket 变成一条透明字节管道后续协议与 WiFi 路径完全一致。Bonjour 在这条路径上完全不参与——这就是接收方监听设计最直接的收益。2.3 加分项Mac 到 Mac 的线缆升级两台 Mac 用雷雳或 USB-C 直连时会形成主机间网络。pv3 通过hello.addrs字段让接收方上报所有可达 IP发送方会定期探测这些地址一旦发现线缆路径就把会话从 WiFi 迁移过去。这个升级是单向的拔出线缆即视为用户主动结束会话不会回落到 WiFi。三、帧结构4 字节长度前缀两种帧所有消息双向都采用统一的长度前缀封装[4字节 无符号大端长度][载荷]长度只统计载荷本身不含 4 字节头部。由于 TCP 不保留消息边界两端都必须自行缓冲、重组帧——一帧可能跨多次读取也可能和别的帧挤在同一次读取里。一个帧要么是视频帧要么是控制消息。接收方如何区分pv3 使用一条启发式规则发送方到接收方方向载荷同时满足以下三条即为 JSON 控制消息否则就是视频帧——长度小于 32768 字节首字节是{0x7B不含任何 NUL 字节0x00。它能成立是因为 H.264 Annex B 起始码00 00 00 01保证了每个视频帧都含 NUL 字节。官方最大的控制消息base64 光标图cursorImg刻意把 PNG 压到 24000 字节以内正是为了在 base64 膨胀后仍留在这条线之下。⚠️ 注意这条启发式是设计债务而非特性文档明确标注将在pv4 中被带类型字段的帧头取代两阶段迁移。实现方应当把解复用决策封装在独立位置方便将来无痛切换。完整规则见 PROTOCOL.md 第 3、4 节。四、视频帧H.264 Annex B一帧一画面视频流是H.264 Annex B格式每个线帧恰好装一个编码画面access unit结构为[可选遥测前缀JSON无起始码][00 00 00 01][NALU]× N关键约定遥测前缀第一个起始码之前的内容是一个 JSON 对象{cap:…,snd:…}捕获/发送时间戳Unix 毫秒专用于端到端延迟测量接收方必须容忍其缺失起始码固定 4 字节发送方禁止发出 3 字节起始码关键帧自带参数集每个 IDR 帧前必须带上当前 SPS 和 PPS NALU非关键帧只携带片数据同一画面的所有片必须在同一线帧内接收方按一到就显示的顺序播放——线上不传显示时间戳因为官方发送方不编码 B 帧本身就是低延迟流。分辨率以 SPS 为准永远不要信 hello。发送方可能按画质预设降分辨率编码当屏幕旋转或切换画质时发送方直接开始发送带新 SPS/PPS 的帧接收方检测到参数集变化就重建解码器、丢弃旧格式缓冲。丢帧怎么恢复接收方解码失步中途加入、解码器崩溃、从后台恢复时用kf控制消息请求关键帧发送方必须让下一帧成为带 SPS/PPS 的 IDR。代码中这个请求逻辑见 Shared/StreamReceiver.swift。五、控制消息带 type 字段的 JSON控制消息是 UTF-8 编码的 JSON 对象每条独占一帧靠type字符串区分类型。两条让协议可持续演化的规则均为规范性要求未知type必须忽略新对端发的旧实现不认识的消息是常态已知类型的未知字段必须忽略可选字段缺失必须容忍——新字段可以不加版本号直接加。5.1 接收方 → 发送方type用途hello每条新连接的第一条消息上报物理像素尺寸、UI 缩放、设备标识、协议版本屏幕旋转时重发ping/touch/scroll心跳时钟同步 / 手指触摸 / 双指滚动pencil/proximitypv3 新增Apple Pencil 压感、方位角与悬停进出对 pv 低于 3 的发送方必须降级为 touchkf请求 IDR 关键帧stats接收方遥测约每 5 秒一次仅被发送方记录日志sleeping/closing设备锁屏稍后重连/ 应用退出会话彻底结束尽力而为的礼貌消息hello的实现可以直接对照 Shared/StreamReceiver.swift除了必选字段还会按需附加cursorPortUDP 光标侧通道端口、maxEncodeWide/High解码上限、addrs线缆升级用地址这些增量字段——全部不触发版本号提升。5.2 发送方 → 接收方type用途pong回显ping的t并附带发送方时钟mt用于 NTP 式时钟偏移估算ping发送方心跳顺带捎上编码丢帧、队列深度、输入延迟百分位等健康指标cursor/cursorImg光标位置以输入速率 120 次/秒推送不烧进视频里与光标贴图base64 PNGwelcomepv2 版本握手的发送方一侧声明自己的pv与最低支持版本minupdateRequired对端版本过低提示用户更新后才能继续心跳与时钟同步是隐形的骨架两端各自每 2 秒发一次ping超过 5 秒无任何字节即判定链路死亡并重建连接静态屏幕不会产生视频帧全靠心跳保活。接收方用最低 RTT 的 ping/pong 样本估算时钟偏移从而把视频遥测前缀映射到本地时钟算出真实的端到端延迟。六、版本演化pv3 与增量优先策略协议版本pv是单个整数只在线上格式变化时才递增与产品发版解耦——这个约定固化在 Shared/Protocol.swift 中。当前状态一览pv引入内容1帧封装、解复用启发式、视频格式、hello、ping/pong、touch、scroll、kf、stats、光标消息2版本握手welcome、updateRequired、sleeping、closing3pencil、proximity笔输入增量加入 UDP 光标侧通道4预留类型化帧头取代第 4 节解复用启发式两阶段迁移演化规则非常克制增量变更免费新类型、新可选字段不需要 bump破坏性变更必须走两阶段流程先双支持、普及后再抬高底线绝不悄悄改。完整政策见 COMPATIBILITY.md。七、快速上手最小实现清单如果你想动手实现一个第三方客户端PROTOCOL.md 附录 A 给出了提炼版清单最小接收方把设备变成一块只显示的屏幕监听 9000 端口 → 连接后先发hello→ 每 2 秒ping→ 按长度前缀拆帧并套用第 4 节的解复用规则 → 视频帧喂给 H.264 解码器留意 SPS/PPS 变化→ 解码失步就发kf→ 其余控制消息一概忽略。仓库里 74 行的 tools/fake-receiver.swift 就是这个骨架的可运行示例。最小发送方拨号 9000 端口 → 等待hello→ 回welcome→ 按第 5 节约定编码 H.2644 字节起始码、每个 IDR 带 SPS/PPS、一图一帧→ 连接建立与收到kf时发 IDR → 每 2 秒ping→ 忽略未知控制类型。输入注入、光标转发、性能遥测都是可选的上层积木按需叠加即可。小结OpenDisplay 的 pv3 线规看似简单——一条 TCP 连接、一个 4 字节长度前缀、两种帧——但每个细节都指向同一个目标WiFi 与 USB 走同一条代码路径、增量演化不打断存量客户端、低延迟优先于一切。理解了角色分工、传输绑定与帧结构这三块你也就拿到了与官方 App 互操作的完整地图。【免费下载链接】opendisplayFree, open-source Sidecar/Duet alternative — use your iPhone, iPad or Mac as a true second monitor for your primary Mac over USB or WiFi. Low latency H.264, Retina HiDPI, touch input.项目地址: https://gitcode.com/GitHub_Trending/op/opendisplay创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表