安卓Android/苹果iOS USB有线投屏原理和实现

时间:2024-02-25 20:03:59

有线镜像投屏简介

手机投屏到电脑分为无线和有线两种方式
无线通过WiFi投屏,基本能实现高清,但是受限于网络速度, 延迟会比较高, 不适合玩游戏这种使用场景.
有线投屏 通过usb数据线能实现设备间稳定的连接, 可以高速传输数据, 延迟低, 画面清晰, 适合游戏, 直播等场景

iOS 有线镜像投屏原理

MAC系统自带的 QuickTime Player 在插入Lighting 数据线时, 能实现iOS 屏幕镜像和录制, 如图所示:

可以此为基础研究有线投屏的协议, 根据抓包并分析, 可以初步得到协议实现, 分成3个步骤:

1. 启动投屏
  1. 启用隐藏设备配置
  2. 声明结束端点
  3. 等待接收 PING 数据包
  4. 使用 PING 数据包进行响应
  5. 等待 SYNC CWPA 数据包接收设备音频时钟的时钟
  6. 创建本地时钟,将时钟ref作为回复SYNC CWPA并发送
  7. 发送ASYN_HPD1
  8. 发送ASYN_HPA1与步骤 6 中收到的设备音频时钟
  9. 接收 SYNC AFMT,并回复零错误代码
  10. 使用设备视频时钟Ref接收 SYNC CVRP
  11. 使用本地视频时钟Ref进行回复
  12. 使用设备的视频时钟Ref开始发送 ASYN 需求
  13. 接收两个 ASYN 集属性
  14. 接收同步 Clok,并回复新创建的时钟
  15. 接收两个 SYNC 时间,并回复两个 CMTimes
2. 接收数据

视频和音频的数据包将由设备发送。我们需要定期发送视频的 NEED 数据包

3. 关闭投屏
  1. 从 cwpa 同步数据包发送带有设备时钟ref 的 asyn hpa0,告诉设备停止发送音频
  2. 发送 hpd0 与空时钟Ref 停止视频
  3. 接收同步停止包,我们创建的视频时钟时,cvrp发送给我们,这是在每个馈送数据包
  4. 回复以 8 个零字节同步停止
  5. 接收本地视频时钟Ref的 ASYN RELS(在 FEED 数据包中找到的 ASYN RELS)
  6. 接收 SYNC CLOCK 后创建的本地时钟的 ASYN RELS
  7. 释放 usb 终结点
  8. 将设备活动配置设置为仅 usbmux

具体的镜像协议细节点击访问 quicktime_video_hack , 包括一个go 语言的协议实现, 可以运行在Ubuntu 和 MacOS 平台.

Android 有线镜像投屏原理

Android系统的有线投屏有2种实现方式, 使用ADB 和 USBAccessory 方式. 缺点是, 不管哪种方式, 目前都不能投屏系统声音.

使用 ADB 镜像投屏

这种方式有个优秀代表 - scrcpy, 是genymobile开源的利用ADB工具实现画面投屏的项目:

  1. 打开手机的usb 调试即可投屏
  2. 可达到60fps 的镜像帧率
  3. 35-70ms 的低延时
  4. 可在电脑反向控制手机
使用 USBAccessory 镜像投屏

此方式的技术实现和adb 完全不一样, 主要基于 Android USBAccessory , 在两个设备间建立usb 传输通道, 手机端运行app 录屏传输数据至电脑

展望

投屏技术极大改进了设备互联互通, 华为和苹果都在此领域发力, 未来肯定会有更长远的发展.
我们团队深耕投屏领域, 不仅实现了miracast 和airplay 无线投屏, 目前也完美实现了 iOS和android 的有线投屏.
分享本文的技术资料, 只为了让有兴趣的人深入研究 , 实现低延时, 高可用, 秒级设备发现的投屏技术, 提升每个人的数字生活体验.