AVFoundationErrorDomain Code=-11800 NSOSStatusErrorDomain Code=-17507

What I am trying to do

Record a stream of CMSampleBuffer that lack timestamps

Problem

I am trying to add timestamps and it fails to append the new sample buffer

Steps to reproduce:

  1. get video stream from external camera, h.264 encoded in .mp4 format
  2. create filepath to save video and handle auth/permissions
  3. create a variable frameDuration = CMTime(seconds: 1.0/30.0, preferredTimescale: CMTimeScale(NSEC_PER_SEC))
  4. create a variable for next presentation timestamp nextPTS: CMTime = CMTimeMake(value: 0, timescale: 0)
  5. Setup AVAssetWriter using CMSampleBufferGetFormatDescription(mySampleBuffer)

Setup AVAssetWriter Func

   private func setupAssetWriter(format formatDescription: CMFormatDescription?) -> Bool {
    // allocate the writer object with our output file URL
    guard let videoWriter = try? AVAssetWriter(outputURL: URL(fileURLWithPath: self.path), fileType: AVFileType.mp4),
       formatDescription != nil else {
         print("Error: No Format For Video to create AVAssetWriter")
         return false
       }
    self.assetWriter = videoWriter
    // initialize a new input for video to receive sample buffers for writing
    // passing nil for outputSettings instructs the input to pass through appended samples, doing no processing before they are written
    let videoInput = AVAssetWriterInput(mediaType: .video, outputSettings: nil, sourceFormatHint: formatDescription)
    videoInput.expectsMediaDataInRealTime = true
    guard videoWriter.canAdd(videoInput) else {
      print("Error: Cannot add Video Input to AVAssetWriter")
      return false
    }
    videoWriter.add(videoInput)
     
    // initiates a sample-writing at time 0
    self.nextPTS = CMTime.zero
    videoWriter.startWriting()
    videoWriter.startSession(atSourceTime: CMTime.zero)
    self.assetWriter = videoWriter
    self.assetWriterInput = videoInput
    return true
  }
  1. Append frames as they come in

   func appendFrame(_ sampleBuffer: CMSampleBuffer) {
    // set up the AVAssetWriter using the format description from the first sample buffer captured
    if self.assetWriter == nil {
      let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer)
      guard self.setupAssetWriter(format: formatDescription) else {
        print("Error: Failed to set up asset writer")
        return
      }
    }
     
    // re-time the sample buffer - in this sample frameDuration is set to 30 fps
    var timingInfo = CMSampleTimingInfo.invalid // a way to get an instance without providing 3 CMTime objects
    timingInfo.duration = self.frameDuration
    timingInfo.presentationTimeStamp = self.nextPTS
    var sbufWithNewTiming: CMSampleBuffer? = nil
    guard CMSampleBufferCreateCopyWithNewTiming(allocator: kCFAllocatorDefault,
                          sampleBuffer: sampleBuffer,
                          sampleTimingEntryCount: 1, // numSampleTimingEntries
                          sampleTimingArray: &timingInfo,
                          sampleBufferOut: &sbufWithNewTiming) == 0 else {
      print("Error: Failed to set up CMSampleBufferCreateCopyWithNewTiming")
      return
    }
     
    // append the sample buffer if we can and increment presentation time
    guard let writeInput = self.assetWriterInput, writeInput.isReadyForMoreMediaData else {
      print("Error: AVAssetWriterInput not ready for more media")
      return
    }
    guard let sbufWithNewTiming = sbufWithNewTiming else {
      print("Error: sbufWithNewTiming is nil")
      return
    }
     
    if writeInput.append(sbufWithNewTiming) {
      self.nextPTS = CMTimeAdd(self.frameDuration, self.nextPTS)
    } else {
      let error = self.assetWriter!.error
      NSLog("Error: Failed to append sample buffer: \(error!)")
    }
  }

Cannot append the sample buffer, the NSLog("Error: Failed to append sample buffer: \(error!)")

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-17507), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x283cf7810 {Error Domain=NSOSStatusErrorDomain Code=-17507 "(null)"}}

I can't find any code -17507 references online

Accepted Reply

I was setting the frame duration in a funky way, changing it to this for 30fps made it work  self.frameDuration = CMTime(value: 1, timescale: 30)

Replies

That error could indicate a sandboxing problem. Do you have sufficient permissions to write to the output file?

  • I've been struggling to make a recording from an external video stream. I use this func to handle auth, do you think it is improper? I am able to save empty/corrupt files so I assume I am able to save files suddenly when I try this method to set CMSampleBuffer timestamp it fails with this unknown error

    private func handlePhotoLibraryAuth() {     if PHPhotoLibrary.authorizationStatus() != .authorized {       PHPhotoLibrary.requestAuthorization { authStatus in         if authStatus != .authorized {           print(authStatus)           // I never get this error         }       }     }   }

Add a Comment

I was setting the frame duration in a funky way, changing it to this for 30fps made it work  self.frameDuration = CMTime(value: 1, timescale: 30)