有线镜像投屏简介
手机投屏到电脑分为无线和有线两种方式
无线通过WiFi投屏,基本能实现高清,但是受限于网络速度, 延迟会比较高, 不适合玩游戏这种使用场景.
有线投屏 通过usb数据线能实现设备间稳定的连接, 可以高速传输数据, 延迟低, 画面清晰, 适合游戏, 直播等场景
iOS 有线镜像投屏原理
MAC系统自带的 QuickTime Player 在插入Lighting 数据线时, 能实现iOS 屏幕镜像和录制, 如图所示:
可以此为基础研究有线投屏的协议, 根据抓包并分析, 可以初步得到协议实现, 分成3个步骤:
1. 启动投屏
- 启用隐藏设备配置
- 声明结束端点
- 等待接收 PING 数据包
- 使用 PING 数据包进行响应
- 等待 SYNC CWPA 数据包接收设备音频时钟的时钟
- 创建本地时钟,将时钟ref作为回复SYNC CWPA并发送
- 发送ASYN_HPD1
- 发送ASYN_HPA1与步骤 6 中收到的设备音频时钟
- 接收 SYNC AFMT,并回复零错误代码
- 使用设备视频时钟Ref接收 SYNC CVRP
- 使用本地视频时钟Ref进行回复
- 使用设备的视频时钟Ref开始发送 ASYN 需求
- 接收两个 ASYN 集属性
- 接收同步 Clok,并回复新创建的时钟
- 接收两个 SYNC 时间,并回复两个 CMTimes
2. 接收数据
视频和音频的数据包将由设备发送。我们需要定期发送视频的 NEED 数据包
3. 关闭投屏
- 从 cwpa 同步数据包发送带有设备时钟ref 的 asyn hpa0,告诉设备停止发送音频
- 发送 hpd0 与空时钟Ref 停止视频
- 接收同步停止包,我们创建的视频时钟时,cvrp发送给我们,这是在每个馈送数据包
- 回复以 8 个零字节同步停止
- 接收本地视频时钟Ref的 ASYN RELS(在 FEED 数据包中找到的 ASYN RELS)
- 接收 SYNC CLOCK 后创建的本地时钟的 ASYN RELS
- 释放 usb 终结点
- 将设备活动配置设置为仅 usbmux
具体的镜像协议细节点击访问 quicktime_video_hack , 包括一个go 语言的协议实现, 可以运行在Ubuntu 和 MacOS 平台.
Android 有线镜像投屏原理
Android系统的有线投屏有2种实现方式, 使用ADB 和 USBAccessory 方式. 缺点是, 不管哪种方式, 目前都不能投屏系统声音.
使用 ADB 镜像投屏
这种方式有个优秀代表 - scrcpy, 是genymobile开源的利用ADB工具实现画面投屏的项目:
- 打开手机的usb 调试即可投屏
- 可达到60fps 的镜像帧率
- 35-70ms 的低延时
- 可在电脑反向控制手机
使用 USBAccessory 镜像投屏
此方式的技术实现和adb 完全不一样, 主要基于 Android USBAccessory , 在两个设备间建立usb 传输通道, 手机端运行app 录屏传输数据至电脑
展望
投屏技术极大改进了设备互联互通, 华为和苹果都在此领域发力, 未来肯定会有更长远的发展.
我们团队深耕投屏领域, 不仅实现了miracast 和airplay 无线投屏, 目前也完美实现了 iOS和android 的有线投屏.
分享本文的技术资料, 只为了让有兴趣的人深入研究 , 实现低延时, 高可用, 秒级设备发现的投屏技术, 提升每个人的数字生活体验.