在CMTime和AVFoundation中通过单帧移动 [英] Movement by a single frame in CMTime and AVFoundation

查看:134
本文介绍了在CMTime和AVFoundation中通过单帧移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

间歇性地工作,在一些执行中它会做正确的事情并推进一帧,但是大部分时间我都要按3或4次按钮才会前进一帧。

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.

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

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.

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

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

感谢您的帮助!

推荐答案

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

The answer to your question is in the second line of code where you remove the "nominal" from nominalFrameRate.

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

Your code assumes that the frame rate in your video is constant. This is incorrect.

视频可以具有常量fps,但它没有。例如。如果你在可变照明条件下使用手机拍摄电影,那么帧曝光时间可能会发生变化,帧速率也会发生相反的变化。

A video can have a constant fps, but it doesn't have to. E.g. if you shoot a film with your phone in variable lighting conditions then the frame exposure time can change and your frame rate will vary inversely.

要捕捉到帧边界,您需要使用AVAssetReader来逐步执行各个帧。每个帧都标有一个演示时间戳(它的t),但是如果你踩到的话并不重要,除非你正在更新一个位置标记。

To "snap" to frame boundaries, you need to use an AVAssetReader to step through the individual frames. Each frame is tagged with a Presentation Time Stamp (its "t"), but if you're stepping that doesn't matter so much, unless you're updating a position marker.

这篇关于在CMTime和AVFoundation中通过单帧移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆