2017-08-27 87 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