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

AVFoundation视频裁剪时出现AVFoundationErrorDomain Code=-11800错误的排查求助

AVFoundation视频裁剪时出现AVFoundationErrorDomain Code=-11800错误的排查求助

大家好,我正在尝试从Photos App中选择视频并进行裁剪操作,但在执行exportSession.exportAsynchronously时遇到了错误,实在搞不清楚问题出在哪,想请各位帮忙排查下。

以下是我的完整代码:

import UIKit
import AVFoundation
import AVKit
import Photos
import PhotosUI

class ViewController: UIViewController, PHPickerViewControllerDelegate {

    func loadVideo(url: URL) -> AVAsset? {
        return AVAsset(url: url)
    }

    func trimVideo(asset: AVAsset, startTime: CMTime, endTime: CMTime, completion: @escaping (URL?, Error?) -> Void) {
        // Create an export session with the desired output URL and preset.
        guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {
            completion(nil, NSError(domain: "com.yourapp.trimVideo", code: 1, userInfo: [NSLocalizedDescriptionKey: "Failed to create AVAssetExportSession."]))
            return
        }

        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        let outputURL = documentsDirectory.appendingPathComponent("trimmedVideo.mp4")

        // Remove the existing file if it exists
        try? FileManager.default.removeItem(at: outputURL)

        exportSession.outputURL = outputURL
        exportSession.outputFileType = AVFileType.mp4
        exportSession.shouldOptimizeForNetworkUse = true

        // Set the time range for trimming
        let timeRange = CMTimeRangeFromTimeToTime(start: startTime, end: endTime)
        exportSession.timeRange = timeRange

        // Perform the export
        exportSession.exportAsynchronously {
            switch exportSession.status {
            case .completed:
                completion(exportSession.outputURL, nil)
            case .failed:
                completion(nil, exportSession.error)
            case .cancelled:
                completion(nil, NSError(domain: "com.yourapp.trimVideo", code: 2, userInfo: [NSLocalizedDescriptionKey: "Export cancelled"]))
            default:
                break
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
        debugPrint("1")
        picker.dismiss(animated: true,completion: nil)
        debugPrint("2")
        guard let provider = results.first?.itemProvider else { return }
        debugPrint("3")
        if provider.hasItemConformingToTypeIdentifier(UTType.movie.identifier) {
            debugPrint("4")
            provider.loadFileRepresentation(forTypeIdentifier: UTType.movie.identifier) { [self] (videoURL, error) in
                debugPrint("5")
                cropVideo(sourceURL1: videoURL as! URL, statTime: 10, endTime: 20)
            }
        }
    }

    @IBAction func btnClicked(_ sender: Any) {
        var config = PHPickerConfiguration(photoLibrary: .shared())
        config.selectionLimit = 1
        config.filter = .videos
        let vc = PHPickerViewController(configuration: config)
        vc.delegate = self
        present(vc, animated: true)
    }

    func cropVideo(sourceURL1: URL, statTime:Float, endTime:Float)
    {
        debugPrint("21")
        let manager = FileManager.default
        debugPrint("22")
        guard let documentDirectory = try? manager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true) else {return}
        debugPrint("23")
        let mediaType = "mp4"
        debugPrint("24")
        if mediaType == UTType.movie.identifier || mediaType == "mp4" as String {
            debugPrint("25")
            let asset = AVAsset(url: sourceURL1 as URL)
            let length = Float(asset.duration.value) / Float(asset.duration.timescale)
            print("video length: \(length) seconds")
            debugPrint("26")
            let start = statTime
            let end = endTime
            debugPrint("27")
            var outputURL = documentDirectory.appendingPathComponent("output")
            do {
                debugPrint("28")
                try manager.createDirectory(at: outputURL, withIntermediateDirectories: true, attributes: nil)
                outputURL = outputURL.appendingPathComponent("\(UUID().uuidString).\(mediaType)")
            }catch let error {
                debugPrint("29")
                print(error)
            }
            //Remove existing file
            _ = try? manager.removeItem(at: outputURL)
            debugPrint("30")
            guard let exportSession = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetHighestQuality) else {return}
            exportSession.outputURL = outputURL
            exportSession.outputFileType = .mp4
            debugPrint("31")
            let startTime = CMTime(seconds: Double(start ), preferredTimescale: 1000)
            let endTime = CMTime(seconds: Double(end ), preferredTimescale: 1000)
            let timeRange = CMTimeRange(start: startTime, end: endTime)
            debugPrint("32")
            exportSession.timeRange = timeRange
            exportSession.exportAsynchronously{
                switch exportSession.status {
                case .completed:
                    print("exported at \(outputURL)")
                case .failed:
                    print("failed \(String(describing: exportSession.error))")
                case .cancelled:
                    print("cancelled \(String(describing: exportSession.error))")
                default: break
                }
            }
        }
    }
}

完整报错信息

Optional(Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSUnderlyingError=0x2818544b0 {Error Domain=NSOSStatusErrorDomain Code=-16979 "(null)"}, NSLocalizedFailureReason=An unknown error occurred (-16979), NSURL=file:///private/var/mobile/Containers/Shared/AppGroup/35D28117-572C-484E-969C-A9515EF42CDF/File%20Provider%20Storage/photospicker/version=1&uuid=6C291C6C-F254-44F5-83C2-C15980750530&mode=compatible&noloc=0.mp4, NSLocalizedDescription=The operation could not be completed})

我检查了视频资源的有效性,也确认了输出路径是可写的,但导出就是失败了,有没有大佬能帮我分析下可能的原因,或者给些排查方向?


备注:内容来源于stack exchange,提问作者Chup bae

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.22 08:54:28