在CMTime和AVFoundation中通过单帧移动

时间:2011-06-23 23:26:51

标签: ios avfoundation cmtime

我正在尝试使用AVFoundation播放视频。我使用以下代码作为按钮,使播放前进一帧。

间歇性地工作,在一些执行中它会做正确的事情并前进一帧,但是大多数时候我必须按下按钮3或4次才会前进一帧。

这让我觉得这是一种精确的问题,但我无法弄清楚它是什么。每次运行时,新的CMTime似乎都会以相同的数量前进。

我的另一个理论是,它可能是由于currentTime没有按照我的帧速率设置为精确的帧边界(由搜索视频引起)。但我不知道如何以我的帧速率“捕捉”到最近的帧。

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];

感谢您的帮助!

2 个答案:

答案 0 :(得分:5)

您的问题的答案在第二行代码中,您从nominalFrameRate中删除“名义”。

您的代码假定视频中的帧速率不变。这是不正确的。

视频可以具有常量fps,但并非如此。例如。如果您在可变照明条件下使用手机拍摄胶片,则帧曝光时间可能会发生变化,帧速率也会相反。

要“捕捉”到边框,您需要使用AVAssetReader逐步浏览各个帧。每个帧都标有一个演示时间戳(它的“t”),但是如果你踩踏没那么重要,除非你正在更新一个位置标记。

答案 1 :(得分:4)

这不是很明显(因为奇怪的是它仅在AVPlayerItem而不是AVPlayer中可用)但如果AVPlayerItem为canStepForward/canStepBackward返回YES,那么您可以调用stepByCount:(NSInteger)stepCount:向前或向后移动某个帧数。