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

AVCaptureFileOutputRecordingDelegate代理传递录制URL为nil问题排查

问题分析与修复方案

首先,先揪出最可能的问题——你在代理方法里用错了URL参数!

看你的代码:

urlDelegate?.URL = outputURL

但代理方法的参数明明是outputFileURL啊!你这里写的outputURL应该是你自己定义的某个类变量,但这个变量大概率没有在录制过程中被正确赋值,所以才会是nil。而系统通过代理方法传递给你的、真正的录制完成后的文件URL是outputFileURL,这才是你应该用的那个!

第一步:修正参数错误

把代码改成直接使用代理方法传入的outputFileURL:

func capture(_ output: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    guard error == nil else {
        // 处理录制错误
        print("录制出错:\(error!)")
        return
    }
    // 这里改用参数里的outputFileURL
    urlDelegate?.URL = outputFileURL
}

第二步:检查urlDelegate的生命周期

如果改了参数之后还是nil,那大概率是urlDelegate本身为nil了,常见原因有两个:

  • urlDelegate被声明为weak var,但持有它的对象已经被提前释放(比如你在某个ViewController里设置了delegate,但这个VC在录制完成前就被销毁了)
  • 你根本没有正确给urlDelegate赋值,比如忘记调用cameraObject.urlDelegate = self这类代码

可以在代理方法里加个打印验证:

func capture(_ output: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    guard error == nil else {
        print("录制出错:\(error!)")
        return
    }
    print("outputFileURL: \(outputFileURL)")
    print("urlDelegate是否为nil:\(urlDelegate == nil)")
    urlDelegate?.URL = outputFileURL
}

如果打印出urlDelegate是否为nil:true,那就要去检查你的delegate对象是否还存活,以及赋值逻辑是否正确。

关于“录制是否完成”的疑问

你不用担心——只要didFinishRecordingToOutputFileAt被调用且error为nil,就说明视频录制已经完全完成,文件已经成功写入到outputFileURL对应的路径了。这个方法就是AVCapture框架用来通知你录制结束的回调,不存在“录制未完成”的情况,你之前的困惑应该是因为用错了URL参数导致的错觉。

额外优化建议

如果delegate模式用着别扭,也可以考虑用闭包来传递结果,代码会更简洁直观:

// 在你的相机类里定义一个闭包属性
var onRecordingCompleted: ((URL?) -> Void)?

// 代理方法里调用闭包
func capture(_ output: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!) {
    if error == nil {
        onRecordingCompleted?(outputFileURL)
    } else {
        onRecordingCompleted?(nil)
    }
}

// 使用的时候直接设置闭包
cameraObject.onRecordingCompleted = { url in
    if let url = url {
        // 处理录制完成的URL
    } else {
        // 处理错误
    }
}

内容的提问来源于stack exchange,提问作者dre_84w934

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:38:27