AVAssetWriterInput and readyForMoreMediaData

Is AVAssetWriterInput readyForMoreMediaData supported in the background thread? If readyForMoreMediaData is NO, can I lock in the main thread and wait until the value changes to YES?

I use AVAssetWriterInput, clicking data on it (i.e. without using requestMediaDataWhenReadyOnQueue), and I set expectsMediaDataInRealTime, and 99.9% of the time I can just call appendSampleBuffer (or appendPixelBuffer) on it as fast as my application can generate frames .

This works great if you do not turn on the device (iPhone 3GS) for 15 minutes or so in the middle of an AVAssetWriter session. After waking up the device, appendPixelBuffer sometimes receives an error message: "The pixel buffer cannot be added when readyForMoreMediaData NO." Hence my question - what is the best answer to readyForMoreMediaData = NO, and if I can just wait a bit in the main thread, for example:

while ( ![assetWriterInput readyForMoreMediaData] )
{
    Sleep for a few milliseconds
}
+5
source share
2 answers

Be careful not to block the thread, here is what I did before this did not work:

while (adaptor.assetWriterInput.readyForMoreMediaData == FALSE) {
  [NSThread sleepForTimeInterval:0.1];
}

The above approach sometimes did not work on my iPad2. This fixes the problem:

while (adaptor.assetWriterInput.readyForMoreMediaData == FALSE) {
  NSDate *maxDate = [NSDate dateWithTimeIntervalSinceNow:0.1];
  [[NSRunLoop currentRunLoop] runUntilDate:maxDate];
}
+3

- , . Swift 4. . F.E. NSCondition:

func startRecording() {
        // start recording code goes here 

    readyForMediaCondition = NSCondition()
    readyForMediaObservation = pixelBufferInput?.assetWriterInput.observe(\.isReadyForMoreMediaData, options: .new, changeHandler: { [weak self](_, change) in
        guard let isReady = change.newValue else {
            return
        }

        if isReady {
            self?.readyForMediaCondition?.lock()
            self?.readyForMediaCondition?.signal()
            self?.readyForMediaCondition?.unlock()
        }
    })
}

:

func grabFrame(time: CMTime? = nil) {
    readyForMediaCondition?.lock()
    while !pixelBufferInput!.assetWriterInput.isReadyForMoreMediaData {
        readyForMediaCondition?.wait()
    }
    readyForMediaCondition?.unlock()

    // append your framebuffer here
}

readyForMediaObservation?.invalidate()
0

All Articles