2017-09-13 163 views
1

我使用此擴展名將視頻文件從AVAsset保存到tmp文件夾。問題是,當我使用AVAssetExportPresetHighestQuality類型的視頻文件無法由於這個原因,保存:AVAssetExportPreset類型的AVAssetExportSession問題

錯誤域= AVFoundationErrorDomain代碼= -11800「的操作可能 無法完成」的UserInfo = {NSUnderlyingError = {0x1748482e0錯誤 域= NSOSStatusErrorDomain代碼= -12780 「(空)」}, NSLocalizedFailureReason =出現未知錯誤(-12780), NSLocalizedDescription =操作無法完成}

還有些時候,甚至當我我正在使用AVAssetExportPresetHighestQuality它ves視頻,但以隨機順序。

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

此問題與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 
    } 
}