Meet ScreenCaptureKit
System & Services 进阶 20m

认识 ScreenCaptureKit

Meet ScreenCaptureKit

2022年6月6日

在 Apple 官方观看视频

一句话判断

macOS 上高性能屏幕捕获的官方方案——ScreenCaptureKit 提供了从单个窗口到整个显示器的灵活捕获能力,支持实时调整配置,且 CPU 开销比现有方案更低。

这场 Session 讲了什么

ScreenCaptureKit 团队的 Ernest 介绍了这个全新的 macOS 框架。它的设计目标是替代现有的屏幕捕获方式,为屏幕共享、游戏直播、内容创作等场景提供高性能、灵活、隐私安全的解决方案。

Session 从核心功能讲起,然后介绍了 API 的主要构建块(SCStream、SCShareableContent、SCContentFilter、SCStreamConfiguration),最后演示了如何配置和启动一个捕获流。

值得深挖的点

SCShareableContent 的三层结构。SCDisplay 代表显示器,SCRunningApplication 代表运行中的应用,SCWindow 代表窗口。三者组合起来构成了所有可分享的内容。你可以查询设备上所有的可分享内容,也可以指定参数过滤。只有屏幕上的窗口才会被返回。

两种 SCContentFilter 模式。显示独立(display independent)的窗口过滤器——捕获指定窗口,即使它在多个显示器间移动也能跟随。显示相关(display dependent)的过滤器——可以选择包含或排除特定的窗口和应用。音频只能在应用级别过滤。

“无限镜像”效应的解法。在捕获整个显示器内容时,你的捕获应用自身的窗口也会被捕获,形成无限镜像。解法是创建一个 display dependent 的过滤器,排除你自己的应用。一行代码搞定。

SCStreamConfiguration 的场景化配置。低动态内容(文字、表格):4K 分辨率 + 10fps,音频关闭。高动态内容(视频、游戏):1080p + 60fps + 隐藏鼠标光标 + 启用音频。所有参数都可以在流运行中动态调整。

代码片段

// 获取可分享内容,过滤屏幕上的窗口
SCShareableContent.getExcludingDesktopWindows(
    false, onScreenWindowsOnly: true
) { content, error in
    guard let content = content else { return }
    // content.windows, content.applications, content.displays
}

// 创建排除自身应用的过滤器
let ownApp = content.applications.first {
    $0.bundleIdentifier == Bundle.main.bundleIdentifier
}
let filter = SCContentFilter(
    display: content.displays.first!,
    excludingApplications: [ownApp!],
    exceptingWindows: []
)

// 场景化配置
let config = SCStreamConfiguration()
// 高动态内容配置
config.width = 1920
config.height = 1080
config.minimumFrameInterval = CMTime(value: 1, timescale: 60) // 60fps
config.showsCursor = false
config.capturesAudio = true
config.sampleRate = 48000
config.channelCount = 2

// 创建并启动流
let stream = SCStream(filter: filter, configuration: config, delegate: self)
stream.addStreamOutput(self, type: .screen, sampleHandlerQueue: .main)
try stream.startCapture()

最佳实践

  • 屏幕共享类应用一定要排除自身窗口,避免”无限镜像”
  • 根据内容类型选择分辨率和帧率的平衡点——不是所有场景都需要最高参数
  • 所有配置参数都可以在流运行中实时修改,善用这个特性做动态质量调整
  • 音频捕获需要在隐私设置中获得”屏幕录制”权限
  • 使用 sampleHandlerQueue 指定回调队列,避免阻塞主线程
  • 对于直播场景,关注 CPU 开销——ScreenCaptureKit 利用 GPU 加速,开销比传统方案低

还有什么值得关注

  • 配套 Session “Take ScreenCaptureKit to the next level” 涵盖更高级的用法
  • 视频和音频样本通过 SCStreamOutput 协议回调交付
  • 框架支持最高原生显示器分辨率和帧率
  • 隐私保护是内置的:首次使用需要用户授权,授权记录在系统偏好设置的屏幕录制隐私项中
WWDC 2022