You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用AVFoundation录制Mac屏幕时AVCapture Session录制失败求助

解决AVFoundation命令行录屏工具的Cannot Capture错误(Code=-11844)

我之前在做Mac命令行录屏工具时也碰到过一模一样的错误,结合AVFoundation在非GUI环境下的特性,这个问题通常和权限、配置或者命令行环境的特殊性有关,咱们一步步来排查:

1. 优先检查屏幕录制权限

MacOS对屏幕录制有严格的权限控制,命令行工具的权限逻辑和GUI应用不一样:

  • 打开「系统偏好设置」→「安全性与隐私」→「隐私」→「屏幕录制」
  • 把你的命令行工具(或者运行它的终端/Xcode,如果是调试的话)添加到权限列表里
  • 重启终端/Xcode或者你的工具,确保权限生效

很多时候这个错误就是因为权限没给到位,AVFoundation没法访问屏幕捕获接口。

2. 检查Capture Session的配置是否合理

错误里提到的图形子系统问题,大概率和输入输出的格式不兼容有关:

  • 避免使用自定义的过高分辨率,先试试用系统预设的AVCaptureSessionPresetHigh(Swift里是.high)
  • 检查AVCaptureScreenInput的preferredActiveFormat,确保选择的是当前显示器支持的格式,比如可以通过screenInput.availableActiveFormats枚举所有支持的格式,选一个合适的
  • 不要同时尝试捕获多个屏幕或者不支持的像素格式(比如某些旧Mac不支持4K@60fps的录制)

3. 确保命令行工具运行了RunLoop

GUI应用默认有NSApplication的事件循环,但命令行工具没有,而AVFoundation的Capture Session依赖RunLoop来处理捕获事件:

  • 如果你用Objective-C,在启动录制后要启动RunLoop,比如:
// 启动录制后,让RunLoop运行指定时长
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]];
  • 如果是Swift,类似这样:
// 运行RunLoop直到指定时间点
RunLoop.current.run(until: Date().addingTimeInterval(10))

要是不启动RunLoop,Capture Session还没初始化完成,程序就直接退出了,自然会抛出捕获失败的错误。

4. 排查硬件/系统兼容性

如果上面的方法都没用,可能是硬件或者系统版本的问题:

  • 确认你的Mac系统版本是否支持AVCaptureScreenInput(这个API从macOS 10.11开始可用)
  • 旧款Mac的图形硬件可能不支持某些高分辨率录制,试试降低录制分辨率再测试

示例代码片段(Swift)

这里给一个简化的正确配置示例,你可以参考调整:

import AVFoundation

class RecorderDelegate: NSObject, AVCaptureFileOutputRecordingDelegate {
    func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
        if let error = error {
            print("录制出错:\(error.localizedDescription)")
        } else {
            print("录制完成,文件路径:\(outputFileURL.path)")
        }
        // 退出RunLoop
        RunLoop.current.stop()
    }
}

let recorderDelegate = RecorderDelegate()
let session = AVCaptureSession()
session.sessionPreset = .high

// 创建屏幕输入
guard let screenInput = AVCaptureScreenInput(displayID: CGMainDisplayID()), session.canAddInput(screenInput) else {
    fatalError("无法初始化屏幕输入")
}
session.addInput(screenInput)

// 创建视频输出
let movieOutput = AVCaptureMovieFileOutput()
guard session.canAddOutput(movieOutput) else {
    fatalError("无法添加视频输出")
}
session.addOutput(movieOutput)

// 开始录制
let outputPath = "/tmp/screen_recording.mp4"
let outputURL = URL(fileURLWithPath: outputPath)
movieOutput.startRecording(to: outputURL, recordingDelegate: recorderDelegate)

// 启动RunLoop
session.startRunning()
RunLoop.current.run()

先从权限和RunLoop这两个最常见的问题入手排查,应该能解决大部分情况。

内容的提问来源于stack exchange,提问作者Suresh Kumar S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:41:20