2017-10-16 66 views
2

使用案例iOS的11 replaykit資產作家身份失敗隨機

我使用的是iOS 11 Replaykit框架,試圖從畫面記錄幀,並從應用程序和麥克風音頻。

問題

隨機,當我把我的.append(sampleBuffer)獲得AVAssetWriterStatus.failedAssetWriter.Error顯示

Error Domain=AVFoundationErrorDomain Code=-11823 "Cannot Save" UserInfo={NSLocalizedRecoverySuggestion=Try saving again., NSLocalizedDescription=Cannot Save, NSUnderlyingError=0x1c044c360 {Error Domain=NSOSStatusErrorDomain Code=-12412 "(null)"}}

枝節問題:我玩重複的聲音時,應用程序是記錄嘗試驗證錄製的音頻,但是當我開始錄製時,即使在視頻和外部音頻麥克風正在工作的位置,聲音也會停止。

如果您需要更多信息,我可以將其他代碼上傳到GitHub。

理念

因爲有時記錄保存(我可以導出到照片應用程序和回放視頻),我認爲它必須是異步的問題在那裏我裝出來的東西秩序。請讓我知道,如果你看到任何!

我想要的一個想法是將文件保存到/ Documents中的自己的文件夾,而不是直接發送給/ Documents,以防出現奇怪的權限錯誤。雖然我相信這會造成一致的錯誤,而不是僅僅有時會破裂。

我的代碼

func startRecording() { 
    guard let firstDocumentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first else { return } 

    let directoryContents = try! FileManager.default.contentsOfDirectory(at: URL(fileURLWithPath: firstDocumentDirectoryPath), includingPropertiesForKeys: nil, options: []) 
    print(directoryContents) 

    videoURL = URL(fileURLWithPath: firstDocumentDirectoryPath.appending("/\(arc4random()).mp4")) 

    print(videoURL.absoluteString) 

    assetWriter = try! AVAssetWriter(url: videoURL, fileType: AVFileType.mp4) 

    let compressionProperties:[String:Any] = [...] 
    let videoSettings:[String:Any] = [...] 
    let audioSettings:[String:Any] = [...] 

    videoInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings) 
    audioMicInput = AVAssetWriterInput(mediaType: .audio, outputSettings: audioSettings) 
    audioAppInput = AVAssetWriterInput(mediaType: .audio, outputSettings: audioSettings) 

    guard let assetWriter = assetWriter else { return } 
    guard let videoInput = videoInput else { return } 
    guard let audioAppInput = audioAppInput else { return } 
    guard let audioMicInput = audioMicInput else { return } 

    videoInput.mediaTimeScale = 60 
    videoInput.expectsMediaDataInRealTime = true 
    audioMicInput.expectsMediaDataInRealTime = true 
    audioAppInput.expectsMediaDataInRealTime = true 

    if assetWriter.canAdd(videoInput) { 
     assetWriter.add(videoInput) 
    } 

    if assetWriter.canAdd(audioAppInput) { 
     assetWriter.add(audioAppInput) 
    } 

    if assetWriter.canAdd(audioMicInput) { 
     assetWriter.add(audioMicInput) 
    } 

    assetWriter.movieTimeScale = 60 

    RPScreenRecorder.shared().startCapture(handler: recordingHandler(sampleBuffer:sampleBufferType:error:)) { (error:Error?) in 
     if error != nil { 
      print("RPScreenRecorder.shared().startCapture: \(error.debugDescription)") 
     } else { 
      print("start capture complete") 
     } 
    } 
} 

func recordingHandler (sampleBuffer:CMSampleBuffer, sampleBufferType:RPSampleBufferType, error:Error?){ 
    if error != nil { 
     print("recordingHandler: \(error.debugDescription)") 
    } 

    if CMSampleBufferDataIsReady(sampleBuffer) { 
     guard let assetWriter = assetWriter else { return } 
     guard let videoInput = videoInput else { return } 
     guard let audioAppInput = audioAppInput else { return } 
     guard let audioMicInput = audioMicInput else { return } 

     if assetWriter.status == AVAssetWriterStatus.unknown { 
      print("AVAssetWriterStatus.unknown") 
      if !assetWriter.startWriting() { 
       return 
      } 
      assetWriter.startSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(sampleBuffer)) 
     } 

     if assetWriter.status == AVAssetWriterStatus.failed { 
      print("AVAssetWriterStatus.failed") 
      print("assetWriter.error: \(assetWriter.error.debugDescription)") 
      return 
     } 

     if sampleBufferType == RPSampleBufferType.video { 
      if videoInput.isReadyForMoreMediaData { 
       print("=appending video data") 
       videoInput.append(sampleBuffer) 
      } 
     } 

     if sampleBufferType == RPSampleBufferType.audioApp { 
      if audioAppInput.isReadyForMoreMediaData { 
       print("==appending app audio data") 
       audioAppInput.append(sampleBuffer) 
      } 
     } 

     if sampleBufferType == RPSampleBufferType.audioMic { 
      if audioMicInput.isReadyForMoreMediaData { 
       print("===appending mic audio data") 
       audioMicInput.append(sampleBuffer) 
      } 
     } 
    } 
} 

func stopRecording() { 
    RPScreenRecorder.shared().stopCapture { (error) in 
     guard let assetWriter = self.assetWriter else { return } 
     guard let videoInput = self.videoInput else { return } 
     guard let audioAppInput = self.audioAppInput else { return } 
     guard let audioMicInput = self.audioMicInput else { return } 

     if error != nil { 
      print("recordingHandler: \(error.debugDescription)") 
     } else { 
      videoInput.markAsFinished() 
      audioMicInput.markAsFinished() 
      audioAppInput.markAsFinished() 

      assetWriter.finishWriting(completionHandler: { 
       print(self.videoURL) 
       self.saveToCameraRoll(URL: self.videoURL) 
      }) 
     } 
    } 
} 

回答

0

我有類似的問題。我首先檢查videoURL文件是否已經存在。如果是這樣,請先將其刪除,然後錯誤消失。

+0

你能分享你的代碼嗎? – Ros