I'm attempting to play a video with AVFoundation. I am using the following code for a button that advances the playback by one frame.
It works intermittently, on some executions it will do the right thing and advance one frame, but most times I will have to press the button 3 or 4 times before it will advance a frame.
This makes me think it is some kind of precision issue, but I can't figure out what it is. Each time it is run the new CMTime appears to be advancing by the same amount.
My other theory is that it could be caused by the currentTime not being set to an exact frame boundary at my frame rate (caused by seeking through the video). But I don't know how to "snap" to the nearest frame at my frame rate.
AVAssetTrack *videoTrack = ...;
Float64 frameRate = [videoTrack nominalFrameRate];
CMTime currentTime = [self.playerItem currentTime];
CMTime oneFrame = CMTimeMakeWithSeconds(1.0 / frameRate, currentTime.timescale);
CMTime added = CMTimeAdd(currentTime, oneFrame);
[self.player seekToTime:added toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
Thanks for your help!
It isn't very obvious (since strangely it's only available in AVPlayerItem rather than AVPlayer) but if the AVPlayerItem returns YES for canStepForward/canStepBackward
then you can call stepByCount:(NSInteger)stepCount:
to move forwards or backwards by a certain number of frames.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With