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

macOS:AVAssetWriter执行markAsFinished/finishWriting时崩溃(审核反馈)

AVAssetWriter finishWriting 崩溃排查思路
  • 确保所有AVAssetWriter操作线程安全
    AVAssetWriter的所有方法(包括append(_:)、markAsFinished()、finishWriting(completionHandler:))都不是线程安全的,必须在同一个串行队列中执行。你的stopVideoWriter是异步函数,若采集样本的append操作和停止操作不在同一队列,极易引发竞态条件导致崩溃。建议创建一个专用串行队列,比如:

    private let writerQueue = DispatchQueue(label: "com.yourapp.video-writer.queue")
    

    所有涉及AVAssetWriter及输入的操作,都通过writerQueue.async或sync调度执行,避免跨线程操作。

  • 等待所有append操作完成再执行结束流程
    官方文档明确要求必须等所有append(_:)或append(_:withPresentationTime:)调用返回后,才能调用finishWriting。你当前的代码直接标记输入为完成并调用finishWriting,可能存在未完成的append操作在后台执行,引发崩溃。可以用DispatchGroup跟踪所有append任务:

    // 每次append前调用
    writerGroup.enter()
    videoWriterInput.append(sampleBuffer) { success in
        // 处理结果
        writerGroup.leave()
    }
    // 停止时等待所有append完成
    writerGroup.wait()
    videoWriterInput.markAsFinished()
    audioWriterInput.markAsFinished()
    videoWriter.finishWriting(...)
    
  • 修复completionHandler中的引用问题
    你在completionHandler中使用[self]强引用,可能导致循环引用或对象提前释放时的野指针访问。改为弱引用后再处理资源释放:

    videoWriter.finishWriting { [weak self] in
        guard let self = self else { return }
        self.videoWriter = nil
        self.videoWriterInput = nil
        self.audioWriterInput = nil
    }
    
  • 采集并分析错误日志
    即使本地测试无问题,审核环境下可能存在输入失败、资源不足等异常。在停止流程中添加错误日志采集:

    if videoWriter.status == .failed {
        print("Video writer failed: \(videoWriter.error?.localizedDescription ?? "unknown error")")
    }
    if let videoError = videoWriterInput.error {
        print("Video input error: \(videoError.localizedDescription)")
    }
    if let audioError = audioWriterInput.error {
        print("Audio input error: \(audioError.localizedDescription)")
    }
    

    这些日志能帮助定位审核环境中的具体问题,比如权限不足、样本格式不兼容等。

  • 模拟审核环境测试
    本地测试通常用高配置设备或最新系统,审核团队可能使用旧iOS版本、低内存设备或特殊机型(如iPad)。尝试在以下环境测试:

    • 不同iOS版本(尤其是当前最低兼容版本)
    • 低内存设备或通过Xcode模拟内存警告
    • 后台运行其他占用相机/麦克风的应用,模拟资源竞争场景
  • 检查文件写入权限与路径
    确认录制文件的保存路径有写入权限,避免因路径无效或权限不足导致finishWriting时崩溃。可以用FileManager提前验证路径:

    let fileURL = // 你的保存路径
    let fileManager = FileManager.default
    if fileManager.fileExists(atPath: fileURL.path) {
        try? fileManager.removeItem(at: fileURL)
    }
    guard fileManager.createFile(atPath: fileURL.path, contents: nil, attributes: nil) else {
        // 路径不可写,处理错误
        return
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 12:46:14