前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS设备有线投屏的方案

iOS设备有线投屏的方案

原创
作者头像
windseeker
发布2023-11-09 18:54:55
7870
发布2023-11-09 18:54:55
举报

关于 iPhone 如何使用 USB 投屏的方案能找到的资料非常有限,很多开源的代码也很难一次跑起来,所以我把最近的一些调研做一个简单的总结和分享

业务中刚好需要用到使用 USB 数据线投屏到电脑的场景,在安卓上可以使用 scrcpy,在 iOS 中,没有跟 scrcpy 类似功能的开源解决方案,所以最近调研了很多方向,本文就浅谈一下 iPhone 音视频投屏的实现。

要自定义开发 iOS 设备的投屏,一般而言,有下面这几种方式:

使用苹果自带的 AVFoundation 库

使用苹果AVFoundation库获取 iOS设备上的视频内容,这个方法是可行的,但是大部分的开源库都是获取 iPhone 的摄像头上的视频流,而非手机上的视频流,而且 chatgpt4 给的答案也很果断的说不可以:

gpt
gpt

所以我不确定是不是一个 Hack 的方式,ios-minicap就是这样实现的,厉害的是,这个7年前的项目现在也能跑起来,核心原理是利用 [AVCaptureDevice devicesWithMediaType: AVMediaTypeMuxed] 获取设备,然后使用 libjpeg-turboCMSampleBufferRef 编码成 jpeg。

本地开发的时候,需要修改下 CMakeLists.txt 文件,替换 jpeg-turbo 的文件路径,比如我使用 brew 安装的,替换成下面这样:

代码语言:shell
复制
include_directories(
        - /usr/local/opt/jpeg-turbo/include
        + /opt/homebrew/Cellar/jpeg-turbo/2.1.5.1/include
)

target_link_libraries (ios_minicap
        "-framework Foundation"
        "-framework CoreFoundation"
        "-framework CoreMedia"
        "-framework CoreVideo"
        "-framework CoreMediaIO"
        "-framework AVFoundation"
        -/usr/local/opt/jpeg-turbo/lib/libturbojpeg.a)
        +/opt/homebrew/Cellar/jpeg-turbo/2.1.5.1/lib/libturbojpeg.a)

ios-minicap 是不支持音频的,如果需要接收音频,需要自己处理音频流。

利用 AVFoundation 本身底层使用的 usbmuxd 通信

usbmuxd 的主要作用是在计算机和苹果设备之间建立一个 TCP/IP 连接,这样就可以通过 USB 端口与设备进行通信。它监听并管理设备的连接和断开,同时协调多个客户端之间的通信。这使得像 iTunes 这样的应用程序可以与设备同步,或者开发者可以使用 Xcode 等工具进行调试,usbmuxd 也是大部分主流投屏 sdk 使用的方式。

有个叫 Daniel Paulus 的老哥逆向工程后使用 golang 开发了一个 quicktime_video_hack的项目,底层主要依赖 libusb 库,基于 GStreamer 框架做编解码,这个项目本地运行 activate 命令启用视频流配置的时候,一直报错 Assertion failed: (list_empty(&darwin_cached_devices)), function darwin_init, file darwin_usb.c, line 603,主要是 gousb 版本的问题,手动更新 go get -u github.com/google/gousb@latest,或者手动调用 C.libusb_init(&ctx)可以解决。

使用 ReplayKit 或 ReplayKit2

录屏功能是 iOS 10 新推出的特性,苹果在 iOS 9 的 ReplayKit 保存录屏视频的基础上,增加了视频流实时直播功能,iOS 11 增强为 ReplayKit2,进一步提升了 Replaykit 的易用性和通用性,并且可以对整个手机实现屏幕录制,而非某些做了支持ReplayKit功能的App。

系统录屏采用的是扩展方式,有单独的进程,但是 iOS 系统为了保证系统流畅,给扩展程序的资源相对较少,扩展程序内存占用过大也会被 Kill 掉。有大部分直播软件使用的就是这种实现方式,但它的实时性不如前面2种。

使用采集卡

让 iOS 设备通过 Lightning AV 转换器将画面与声音输出到采集卡,再由采集卡的软件传输数据。这个方案不推荐,一是要硬件的支持有一定成本,二是实时性更差,多了一条链路,维护成本也更大。

总结

最终,我们采取的方案是 AVFoundation,但没有使用 libjpeg-turbo,而是用 macOS 内置的 CoreGraphics 编码,从视频采集 -> socket传输 -> nodejs接收并通过 websocket 发送 -> web渲染 ,整体的耗时在 80ms 左右。值的注意的是,使用 macOS10.10 以上的sdk,需要加上这段代码才能允许访问 iPhone 设备:

代码语言:objective-c
复制
#ifdef __MAC_10_10
    // Enable iOS device to show up as AVCapture devices
    // From WWDC video 2014 #508 at 5:34
    // https://developer.apple.com/videos/wwdc/2014/#508
    CMIOObjectPropertyAddress prop = {
        kCMIOHardwarePropertyAllowScreenCaptureDevices,
        kCMIOObjectPropertyScopeGlobal,
        kCMIOObjectPropertyElementMain};
    UInt32 allow = 1;
    CMIOObjectSetPropertyData(kCMIOObjectSystemObject, &prop, 0, NULL, sizeof(allow), &allow);
#endif

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用苹果自带的 AVFoundation 库
  • 利用 AVFoundation 本身底层使用的 usbmuxd 通信
  • 使用 ReplayKit 或 ReplayKit2
  • 使用采集卡
  • 总结
相关产品与服务
云直播
云直播(Cloud Streaming Services,CSS)为您提供极速、稳定、专业的云端直播处理服务,根据业务的不同直播场景需求,云直播提供了标准直播、快直播、云导播台三种服务,分别针对大规模实时观看、超低延时直播、便捷云端导播的场景,配合腾讯云视立方·直播 SDK,为您提供一站式的音视频直播解决方案。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com