如何使用ScreenCaptureKit捕获完整桌面及所有窗口?
使用ScreenCaptureKit捕获完整显示器及所有窗口的问题与解决方法
ScreenCaptureKit存在一处异常限制(或BUG):看似无法直接捕获完整桌面,但已有大量应用实现该功能,说明技术上是可行的——苹果官方的ScreenCaptureKit示例应用也会触发这个问题。
问题现象
在官方示例应用中:
- 当
isAppExcluded启用时,捕获流正常工作; - 若将
isAppExcluded设为false(对应应用内的复选框),捕获流会立即停止; - 若编译时直接将
isAppExcluded设为false并启动应用,捕获流始终无法启动; - 上述两种异常场景下,只要将
isAppExcluded切回true,捕获流就能恢复正常。
相关代码(官方示例)
guard let display = selectedDisplay else { fatalError("No display selected.") } var excludedApps = [SCRunningApplication]() // 如果用户选择从流中排除当前应用,通过Bundle ID匹配排除 if isAppExcluded { excludedApps = availableApps.filter { app in Bundle.main.bundleIdentifier == app.bundleIdentifier } } // 创建带有排除应用的内容过滤器 filter = SCContentFilter(display: display, excludingApplications: excludedApps, exceptingWindows: [])
解决方法
要捕获完整显示器及所有窗口,核心是避免给exceptingWindows参数传空数组,即使不需要例外窗口,也应传入nil,或使用更简洁的构造方法。
修改后的代码示例1(保留排除应用逻辑)
guard let display = selectedDisplay else { fatalError("No display selected.") } var excludedApps = [SCRunningApplication]() if isAppExcluded { excludedApps = availableApps.filter { app in Bundle.main.bundleIdentifier == app.bundleIdentifier } } // 将exceptingWindows设为nil,而非空数组 filter = SCContentFilter(display: display, excludingApplications: excludedApps, exceptingWindows: nil)
修改后的代码示例2(无需排除应用时)
guard let display = selectedDisplay else { fatalError("No display selected.") } // 使用仅指定display的构造方法,默认捕获该显示器所有内容 filter = SCContentFilter(display: display)
原因说明
ScreenCaptureKit的SCContentFilter构造逻辑存在特殊处理:当指定display且传入空的exceptingWindows数组时,框架会错误判定为“仅捕获无窗口的桌面空白区域”,而非整个显示器的全部内容。传入nil则表示无例外窗口,会正确捕获该显示器下的所有元素——包括所有应用窗口和桌面本身。
内容的提问来源于stack exchange,提问作者Ryan Patterson
相关产品推荐
相关产品推荐

