我基本上想按一个按钮,以30fps开始时间码。 (每隔1/30秒调用一次)。我希望时间码能够参考计算机内置的时钟。我可以很容易地使用NSDate获取HH:mm:ss的当前时间,但是我需要计数器从零开始并实现格式化为HH的帧:mm:ss:ff
思想?
答案 0 :(得分:3)
使用CVDisplayLink
生成具有视频卡准确性的脉冲,这将比NSTimer
或调度队列更准确。 CoreMedia / CoreVideo本身也在谈论SMPTE。
CVReturn MyDisplayCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp *inNow,
const CVTimeStamp *inOutputTime,
CVOptionFlags flagsIn,
CVOptionFlags *flagsOut,
void *displayLinkContext) {
CVSMPTETime timecodeNow = inNow->smpteTime; // it's that easy!
DoStuffWith(timecodeNow); // you might have to modulo this run a bit if the display framerate is greater than 30fps.
return kCVReturnSuccess;
}
CVDisplayLinkRef _link;
CVDisplayLinkCreateWithCGDisplay(CGMainDisplayID(),&_link);
CVDisplayLinkSetOutputCallback(_link, MyDisplayCallback, NULL);
CVDisplayLinkStart(_link);
编辑:在玩了一下之后,我注意到来自displaylink的SMPTE字段没有被填写,但OTOH的主机时间是准确的。只需使用:
inNow->videoTime / inNow->videoTimeScale;
获取正常运行时间的秒数,
inNow->videTime % inNow->videoTimeScale
得到余数。
据我所知:
@implementation JHDLTAppDelegate
CVReturn MYCGCallback(CVDisplayLinkRef displayLink,
const CVTimeStamp *inNow,
const CVTimeStamp *inOutputTime,
CVOptionFlags flagsIn,
CVOptionFlags *flagsOut,
void *displayLinkContext) {
dispatch_async(dispatch_get_main_queue(), ^{
JHDLTAppDelegate *obj = (__bridge JHDLTAppDelegate *)displayLinkContext;
uint64_t seconds = inNow->videoTime / inNow->videoTimeScale;
[obj.outputView setStringValue:[NSString stringWithFormat:@"days: %llu/hours: %llu/seconds: %llu (%llu:%u)",
seconds / (3600 * 24),
seconds / 3600,
seconds,
inNow->videoTime, inNow->videoTimeScale]];
});
return kCVReturnSuccess;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
CVDisplayLinkCreateWithCGDisplay(CGMainDisplayID(), &_ref);
CVDisplayLinkSetOutputCallback(_ref, MYCGCallback, (__bridge void *)self);
CVDisplayLinkStart(_ref);
}
- (void)dealloc
{
CVDisplayLinkStop(_ref);
CVDisplayLinkRelease(_ref);
}
@end
答案 1 :(得分:0)
这应该可以使用NSTimer对象并在调用中进行可视化更新。您可以将计时器设置为每3.3333毫秒触发一次。我看到的唯一问题是很长时间,时间码会略微偏离。此外,如果这与视频相关,请小心,因为某些视频以24 fps编码。然后我会有一个计数器在计时器触发的方法中执行+1,除非counter = 30,然后我将它重置为1.您应该能够使用自定义格式字符串初始化NSDateFormatter对象以插入当前时间以及您希望向用户显示的格式的计数器变量。