AVAssetExportSession дает мне код AVFoundationErrorDomain = -11800

Я сталкиваюсь с теми же проблемами в ios 13.3 на реальном устройстве, он работает в симуляторе ios 13.2, но дает ошибку ниже.

Error Domain = AVFoundationErrorDomain Code = -11800 «Операция не может быть завершена» UserInfo = {NSLocalizedFailureReason = Произошла неизвестная ошибка (-17508), NSLocalizedDescription = Операция не может быть завершена, NSUnderlyingError = 0x2816d11d0 {Error Domain = NSOSStatusErrorDomain 17508 "(ноль)"}}

Вот мой код, в котором я хочу преобразовать файл .mov в mp4.

class func encodeVideo(at videoURL: String, completionHandler: ((URL?, Error?) -> Void)?)  {  
    let avAsset = AVURLAsset(url: URL.init(fileURLWithPath: videoURL), options: nil)  

    let startDate = Date()  

    //Create Export session  
    guard let exportSession = AVAssetExportSession(asset: avAsset, presetName: AVAssetExportPresetPassthrough) else {  
        completionHandler?(nil, nil)  
        return  
    }  

    //Creating temp path to save the converted video  
    let filename = "Video_\(Date().timeIntervalSince1970).mp4"  
      // Below Folder Path used tor getting directory path  
    let strfilePath = (FolderPath.temporaryDirectory.getDirectoryPath as NSString).appendingPathComponent(filename)  
    let filePath = URL.init(fileURLWithPath: strfilePath)  

    //Check if the file already exists then remove the previous file  
    if FileManager.default.fileExists(atPath: filePath.path) {  
        do {  
            try FileManager.default.removeItem(at: filePath)  
        } catch {  
            completionHandler?(nil, error)  
        }  
    }  

    exportSession.outputURL = filePath  
    exportSession.outputFileType = AVFileType.mp4  
    exportSession.shouldOptimizeForNetworkUse = true  
    let start = CMTimeMakeWithSeconds(0.0, preferredTimescale: 0)  
    let range = CMTimeRangeMake(start: start, duration: avAsset.duration)  
    exportSession.timeRange = range  

    exportSession.exportAsynchronously(completionHandler: {() -> Void in  
        switch exportSession.status {  
        case .failed:  
            print(exportSession.error ?? "NO ERROR")  
            completionHandler?(nil, exportSession.error)  
        case .cancelled:  
            print("Export canceled")  
            completionHandler?(nil, nil)  
        case .completed:  
            //Video conversion finished  
            let endDate = Date()  

            let time = endDate.timeIntervalSince(startDate)  
            print(time)  
            print("Successful!")  
            print(exportSession.outputURL ?? "NO OUTPUT URL")  
            completionHandler?(exportSession.outputURL, nil)  

            default: break  
        }  

    })  
}  

person Dhaval Patel    schedule 14.12.2019    source источник


Ответы (3)


let strfilePath = (FolderPath.temporaryDirectory.getDirectoryPath as NSString).appendingPathComponent(filename)  

вы не можете хранить в этой папке напрямую, но вам нужно сохранить файл во вложенной папке, например нравится:

let documentDirectoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! as NSURL

let strfilePath = documentDirectoryURL.appendingPathComponent("Subfolder/filename.mp4") as URL  

Далее вы можете прочитать эту статью

person Mobi    schedule 13.02.2020
comment
Это не тот случай, но у меня такие же проблемы. - person Dhaval Patel; 13.02.2020

Наконец, я решаю свои проблемы с помощью AVMutableComposition, а не напрямую с использованием ресурса AVURL. Я добавляю аудио- и видеодорожку в AVMutableComposition.

person Dhaval Patel    schedule 21.02.2020

Это код, который я использую для преобразования .mov в .mp4

  var outputURL: URL!

   func exportVideo(key:String, inputurl: URL, presetName: String, outputFileType: AVFileType = .mp4, fileExtension: String = "mp4", then completion: @escaping (URL?) -> Void) {

        let asset = AVAsset(url: inputurl)

        outputURL = FileManager.default.temporaryDirectory.appendingPathComponent(key)

        if let session = AVAssetExportSession(asset: asset, presetName: presetName) {
            session.outputURL = outputURL
            session.outputFileType = outputFileType

            session.shouldOptimizeForNetworkUse = true
            session.exportAsynchronously {
                switch session.status {
                case .completed:
                    completion(self.outputURL)
                case .cancelled:
                    debugPrint("Video export cancelled.")
                    completion(nil)
                case .failed:
                    let errorMessage = session.error?.localizedDescription ?? "n/a"
                    debugPrint("Video export failed with error: \(errorMessage)")
                    completion(nil)
                default:
                    break
                }
            }
        } else {
            completion(nil)
        }
    }

Затем я вызываю эту функцию, чтобы получить выходной URL преобразованного файла и использовать его.

exportVideo(key: key, inputurl: path, presetName: AVAssetExportPresetHighestQuality, outputFileType: .mp4, fileExtension: "mp4") { (outputURL) in 

    // do whatever with the file here
}
person Maruta    schedule 20.02.2020