2017-08-27 143 views
1

我的音频和视频将来自文档目录。当我将视频保存到照片中时,一切正常。但是这个错误发生了,它不会被保存。我想合并音频和视频并保存到照片库ios swift

失败可选(错误域= AVFoundationErrorDomain代码= -11800 “操作无法完成” 的UserInfo = {NSUnderlyingError = {0x17044a2f0误差区域= NSOSStatusErrorDomain代码= -12842 “(空)”},NSLocalizedFailureReason =的出现未知错误(-12842),NSLocalizedDescription =操作无法完成})

这里是我的FUNC

func getData(){ 
     let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! 

     do { 
      // Get the directory contents urls (including subfolders urls) 
      let directoryContents = try FileManager.default.contentsOfDirectory(at: documentsUrl, includingPropertiesForKeys: nil, options: []) 
      print(directoryContents) 

      // if you want to filter the directory contents you can do like this: 
      videoUrlforMarge = directoryContents.filter{ $0.pathExtension == "mov" } as [AnyObject] 
      //videoUrlforMarge.append(directoryContents[1] as AnyObject) 
      print("this video \(videoUrlforMarge[0])") 

      audioUrl = directoryContents.filter{ $0.pathExtension == "caf" } as [AnyObject] 

     } catch let error as NSError { 
      print(error.localizedDescription) 
     } 

    } 

这里是我的合并FUNC

func mergeFilesWithUrl(videoUrl:NSURL, audioUrl:NSURL) 
    { 
     let mixComposition : AVMutableComposition = AVMutableComposition() 
     var mutableCompositionVideoTrack : [AVMutableCompositionTrack] = [] 
     var mutableCompositionAudioTrack : [AVMutableCompositionTrack] = [] 
     let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction() 


     //start merge 



     let aVideoAsset : AVAsset = AVAsset(url: videoUrl as URL) 
     let aAudioAsset : AVAsset = AVAsset(url: audioUrl as URL) 

     mutableCompositionVideoTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)) 
     mutableCompositionAudioTrack.append(mixComposition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)) 

     guard aVideoAsset.tracks(withMediaType: AVMediaTypeVideo).count > 0 && aAudioAsset.tracks(withMediaType: AVMediaTypeAudio).count > 0 else{ 
      return 
     } 
     let aVideoAssetTrack : AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0] 
     let aAudioAssetTrack : AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaTypeAudio)[0] 



     do{ 
      try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: kCMTimeZero) 

      try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero, aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: kCMTimeZero) 

     }catch{ 

     } 

     totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(kCMTimeZero,aVideoAssetTrack.timeRange.duration) 

     let mutableVideoComposition : AVMutableVideoComposition = AVMutableVideoComposition() 
     mutableVideoComposition.frameDuration = CMTimeMake(1, 30) 

     mutableVideoComposition.renderSize = CGSize(width: 1280, height: 720) 


     let VideoFilePath = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("mergeVideo\(arc4random()%1000)d")!.appendingPathExtension("mp4").absoluteString 
     if FileManager.default.fileExists(atPath: VideoFilePath) 

     { 
      do 

      { 
       try FileManager.default.removeItem(atPath: VideoFilePath) 
      } 
      catch { } 

     } 
     let tempfilemainurl = NSURL(string: VideoFilePath)! 
     let sourceAsset = AVURLAsset(url: tempfilemainurl as URL, options: nil) 
     let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetMediumQuality)! 
     assetExport.outputFileType = AVFileTypeQuickTimeMovie 
     assetExport.outputURL = tempfilemainurl as URL 


     assetExport.exportAsynchronously {() -> Void in 
      switch assetExport.status 
      { 
      case AVAssetExportSessionStatus.completed: 
       DispatchQueue.main.async(execute: { 
        do 
        { 

         self.userreponsevideoData = try NSData(contentsOf: tempfilemainurl as URL, options: NSData.ReadingOptions()) 
         print("MB - \(self.userreponsevideoData.length) byte") 
         let assetsLib = ALAssetsLibrary() 
         assetsLib.writeVideoAtPath(toSavedPhotosAlbum: tempfilemainurl as URL!, completionBlock: nil) 




        } 
        catch 
        { 

         print(error) 
        } 
       }) 
      case AVAssetExportSessionStatus.failed: 
       print("failed \(String(describing: assetExport.error))") 
      case AVAssetExportSessionStatus.cancelled: 
       print("cancelled \(String(describing: assetExport.error))") 
      default: 
       print("complete") 

      } 

     } 
} 

等FUNC我打电话合并FUNC

func Action(){ 
    guard videoUrlforMarge.count > 0 && audioUrl.count > 0 else{ 
       return 
      } 
      let videoUrl = videoUrlforMarge[0] 
      let url = NSURL(fileURLWithPath: videoUrl.absoluteString!!) 
      let audio = audioUrl[0] 
      let urla = NSURL(fileURLWithPath: audio.absoluteString!!) 

      self.mergeFilesWithUrl(videoUrl: url as NSURL , audioUrl: 
    urla as NSURL 

} 
+0

没有重播。为什么为什么: – behtito

+0

您是否向.plist添加了所需的警告?(隐私 - 照片库使用说明)用户是否批准您访问照片库? – Mozahler

+0

是的..我添加了这个 – behtito

回答

0
import Photos 
import PhotosUI 

我想你已经做了大量的工作,提供信息和代码。这是星期天早上在这里,所以也许专家正在睡觉?由于您的错误信息非常隐蔽,我在考虑它的权限问题,也许您还没有更新Info.plist以包含所需的“隐私 - 照片库使用说明”条目。另外,当第一次运行时,用户必须接受您的访问请求才能使存储库工作。 [你不显示的代码,代码的请求没有(和接收)从照片库中的数据 - 为什么我觉得这是问题,就是] 这样的要求:

func configureGalleryAccess() { 

    PHPhotoLibrary.requestAuthorization({(_ status: PHAuthorizationStatus) -> Void in switch status { 
     case .authorized: 
      print("PHAuthorizationStatusAuthorized") 
      self.postAuthorizationLoadController() // replace with your code 
     case .denied: 
      print("PHAuthorizationStatusDenied") 
     case .notDetermined: 
      print("PHAuthorizationStatusNotDetermined") 
     case .restricted: 
      print("PHAuthorizationStatusRestricted") 
     } 
    }) 
} 

错误信息是抱怨你正在尝试保存一个它不允许的零对象。因此,通过调试器运行程序,在保存对象/照片之前设置断点。如果您发现无法预期的地方,请备份,直到找到问题所在。在保存可选项时,请在保存前检查零。

+0

是否需要任何模块导入phphotoLibrary – behtito

+0

是的,我把它添加到上面:照片和(可能 - 取决于使用)PhotosUI – Mozahler

+0

仍然同样的问题:( – behtito

相关问题