2017-09-13 13 views
1

이 확장 프로그램을 사용하여 AVAsset의 비디오 파일을 tmp 폴더에 저장합니다. "작업이 을 완료 할 수 없습니다"AVAssetExportPreset 유형의 AVAssetExportSession 문제

오류 도메인 = AVFoundationErrorDomain 코드 = -11800 사용자 정보 = {NSUnderlyingError = 0x1748482e0 {: 문제는 내가 AVAssetExportPresetHighestQuality 유형의 비디오 파일을 사용하고 있습니다 때하는 것은 인해 그 이유를 저장할 수 없습니다이다 오류 도메인 = NSOSStatusErrorDomain 코드 = -12780는 "(널)는"}, NSLocalizedFailureReason는 NSLocalizedDescription이 경우에도 또한

몇 번을} 작업을 완료 할 수 없습니다 = 알 수없는 오류가 발생 (-12780)를 = I AVAssetExportPresetHighestQuality sa를 사용하고 있습니다. 비디오는 임의의 순서로 표시됩니다.

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 
    } 
}