首页 文章

AVAssetExportPreset类型的AVAssetExportSession问题

提问于
浏览
1

我正在使用此扩展程序将视频文件从 AVAsset 保存到tmp文件夹 . 问题是当我使用 AVAssetExportPresetHighestQuality 类型的视频文件由于这个原因无法保存:

错误域= AVFoundationErrorDomain代码= -11800“操作无法完成”UserInfo = {NSUnderlyingError = 0x1748482e0 ,NSLocalizedFailureReason =发生未知错误(-12780), NSLocalizedDescription =操作无法完成}

有时甚至当我使用 AVAssetExportPresetHighestQuality 时它会以随机顺序保存视频 .

extension AVAsset {

    func write(to url: URL, success: @escaping () -> (), failure: @escaping (Error) -> ()) {
        guard let exportSession = AVAssetExportSession(asset: self, presetName: AVAssetExportPresetMediumQuality) else {
            let error = NSError(domain: "domain", code: 0, userInfo: nil)
            failure(error)

            return
        }

        exportSession.outputFileType = AVFileTypeMPEG4
        exportSession.outputURL = url

        exportSession.exportAsynchronously {
            switch exportSession.status {
            case .completed:
                success()
            case .unknown, .waiting, .exporting, .failed, .cancelled:
                let error = NSError(domain: "domain", code: 0, userInfo: nil)
                failure(error)
            }
        }
    }
}

1 回答

  • 2

    此问题与 AVAsset 组件的错误长度有关 . 出于某种原因, AVAsset 轨道具有不同的视频和音频轨道持续时间,这是主要问题 .

    为了解决这个问题,我正在使用 AVAsset 的自定义扩展 . 这个函数将基于视频和音频轨道创建新的 AVAsset ,条件将解决持续时间问题 . 因此,从 normalizingMediaDuration() 获得的 AVAsset 可以成功导出 .

    extension AVAsset {
        func normalizingMediaDuration() -> AVAsset? {
            let mixComposition : AVMutableComposition = AVMutableComposition()
            var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = []
            var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = []
            let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
    
            guard let video = tracks(withMediaType: AVMediaTypeVideo).first else {
                return nil
            }
    
            guard let audio = tracks(withMediaType: AVMediaTypeAudio).first else {
                return nil
            }
    
            mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid))
            mutableCompositionAudioTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid))
    
            let duration = video.timeRange.duration.seconds > audio.timeRange.duration.seconds ? audio.timeRange.duration : video.timeRange.duration
    
            do{
                try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero,duration), of: video, at: kCMTimeZero)
                try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, duration), of: audio, at: kCMTimeZero)
            }catch{
                return nil
            }
    
            totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,duration)
    
            return mixComposition
        }
    }
    

相关问题