首页 > 其他分享 >MACOS屏幕录制

MACOS屏幕录制

时间:2022-11-15 11:56:06浏览次数:68  
标签:MACOS 捕获 录制 ReplayKit API 抓屏 屏幕 ScreenCaptureKit

1文章来自:吕大千 字节跳动飞书 2022-07-10 WWDC22 iOS;如有侵权请及时反馈联系;非商用仅记录;支持小专栏正版https://xiaozhuanlan.com/topic/0458326917


 

目前 ScreenCaptureKit 只支持 MacOS 12.3+,Mac Catalyst 15.4+ ,是比较新的操作系统。 这意味着如果应用需要支持更老的操作系统,兼容性还是需要考虑的。此外 ScreenCaptureKit 音频采集还是应用级别的, API 文档中很多音频相关的 API 还被标注为 Beta,这意味着以后还有变化的可能。

导言

屏幕录制一直以来都是一个桌面系统需要提供的基本能力,可以应用到很多场景,例如:视频会议中的桌面共享、电脑游戏直播、远程桌面控制等。 今年的 WWDC 苹果新推出了一个 MacOS 上的高性能屏幕录制框架 ScreenCaptureKit。 ScreenCaptureKit 不仅通过提供更加易于理解的 API 来简化开发成本,还大大提升了屏幕录制的性能,以便 MacOS 用户可以获得更佳的使用体验。

本文主要信息来源于以下两个 WWDC session:

ScreenCaptureKit 前时代

在介绍 ScreenCaptureKit 之前,我们先看看苹果在推出 ScreenCaptureKit 前,MacOS 下有哪些主要的方法可以进行屏幕录制。

AVCaptureScreenInput

与正常采集摄像头视频流数据一样,将 AVCaptureScreenInput 作为 AVCaptureSession 的输入源,就能得到当前的屏幕图像数据。 这种方式的优点是:

  • 可以通过调整scaleFactor来指定分辨率。
  • 可以配置是否包含鼠标光标。
  • 性能很好,可以达到 60fps,CPU 占用不显著。

不过也有显著的缺点,可定制性较差:

  • 只能捕获整个屏幕,不能忽略窗口抓屏,不能只捕获某个窗口

CGDisplayStreamCreate

使用CGDisplayStreamCreate API 可以不通过 AVCaptureSession 直接创建一个屏幕图像数据流。 与 AVCaptureSession + AVCaptureScreenInput 的方式类似。优势:

  • 可以通过来参数指定分辨率。
  • 可以配置是否包含鼠标光标。
  • 实时屏幕流,可以增量,性能很好,CPU 占用不显著。

也有同样的缺点,可定制性较差:

  • 只能捕获整个屏幕,不能忽略窗口抓屏,不能只捕获某个窗口

CGDisplayCreateImage

CGDisplayCreateImage 以及 CGDisplayCreateImageForRect 系统 API 可以直接截取当前屏幕的图像。相对于视频采集 API, 这种方式的优点是:

  • 可以排除特定窗口,抓屏时会自动忽略掉所有 sharingType 为 NSWindowSharingType::NSWindowSharingNone 的 NSWindow

但是缺点也很多:

  • 无法指定分辨率, 只能是显示到屏幕的物理分辨率。
  • 不能只抓去特定的窗口
  • 抓屏时会同时包含鼠标光标,无法去除。
  • 调用开销比较大,CPU 占用显著提高,帧率不可控。
  • 输出数据类型是 CGImageRef,需要应用层转换成原始数据

CGWindowListCreateImageFromArray

CGWindowListCreateImageFromArray 以及 CGWindowListCreateImage 系统 API 可以获得对应窗口的图像。虽然不可以指定任意分辨率抓屏,但是可以通过 CGWindowImageOption 参数选择按照原始物理分辨率抓屏(kCGWindowImageBestResolution),还是坐标分辨率抓屏(kCGWindowImageNominalResolution)。 同时也可以灵活控制捕获或者忽略特定窗口。

相对缺点是:

  • 最小化或者被隐藏的窗口无法捕获图像
  • 无法捕获到鼠标光标的图像,需要额外处理
  • 和 CGDisplayCreateImage 类似,调用开销比较大,CPU 占用显著提高。
  • 输出数据类型是 CGImageRef,需要应用层转换成原始数据

ReplayKit

还有一个取巧的方法,我们都知道在 iOS 平台有一个 ReplayKit 的框架,支持在 iOS 设备上抓屏。 近年来苹果在推动各个平台融合,ReplayKit 也被移植到 Mac 平台上了。 因此也可以通过 ReplayKit 在 Mac 上实现抓屏。参考 WWDC 2020 ReplayKit 相关 session。
Capture and stream apps on the Mac with ReplayKit - WWDC 2020 - Videos - Apple Developer

img

 

相对于其他方案 ReplayKit 的优点是:

  • 能够捕获当前应用输出的音频
  • 性能相对较好

但是 ReplayKit 也有很大的限制:

  • ReplayKit 在 Mac 上仅可以实现当前应用的屏幕录制,因此也限制了应用场景
  • 捕获图像不会包含鼠标光标

总结

在 ScreenCaptureKit 之前, macOS 上捕获特定窗口图像和捕获性能不可兼得。相关 API 使用起来也相对复杂,可配置性也不高。这些都促使了 ScreenCaptureKit 的推出。

ScreenCaptureKit

ScreenCaptureKit 集合了以前所有抓屏方法的优点,提供

  • 提供整个屏幕、应用、窗口等不同级别的捕获能力
  • 支持配置是否包含鼠标光标图像,输出的像素格式、色彩空间,帧率以及分辨率。 帧率和分辨率最高可与实际显示器显示的帧率分辨率一致。
  • 支持以应用级别的声音采集,配置音频采集通道数量和采样率, 最高可达双通道 48khz 采样率
  • 支持动态的选择捕获图像内容,以及动态的配置捕获参数
  • 高性能: 充分利用 GPU 能力,低 CPU 消耗
  • 隐私体验:苹果生态的隐私权限控制

总体架构

ScreenCaptureKit 提供了一套易于理解的 Swift 风格的 API 。结构如下:

img

 

应用层使用 ScreenCaptureKit 的核心对象是 SCStream ,SCStream 可以创建多个实例,每个实例相互独立,可以同时进行多路屏幕图像的捕获。

创建一个SCStream 对象,需要提供内容过滤器(SCContentFilter)和配置参数(SCStreamConfiguration)来控制捕获屏幕图像的内容。 通过配置 SCStream delegate 来处理屏幕捕获过程中的错误,通过配置 SCStreamOutput 对象来获得捕获到的数据。

ShareableContent

ShareableContent 是一个用来枚举当前系统可以被用来屏幕录制的实体的工具。我们能够通过它对应的数组属性得到当前有效的 SCDisplay, SCRunningApplication, SCWindow 对象。可以参考苹果官方文档:SCShareableContent

 

如何控制捕获内容

SCContentFilter 顾名思义这是一个用来控制共享内容的对象。 可以通过一系列的构造方法来创建SCContentFilter 对象。通过SCContentFilter 对象我们可以指定需要显示或者排除哪些应用或者窗口

参考苹果官方文档:SCContentFilter


 

标签:MACOS,捕获,录制,ReplayKit,API,抓屏,屏幕,ScreenCaptureKit
From: https://www.cnblogs.com/8335IT/p/16891954.html

相关文章