我基本上想按下一個按鈕,以30fps開始時間碼。 (每1/30秒調用一次)。我希望時間碼被引用到計算機內置的時鐘中。我可以很容易地使用NSDate獲取HH:mm:ss的當前時間,但是我需要計數器從零開始並實現幀格式,如HH:mm:ss:ff從計算機時鐘引用的時間碼
想法?
我基本上想按下一個按鈕,以30fps開始時間碼。 (每1/30秒調用一次)。我希望時間碼被引用到計算機內置的時鐘中。我可以很容易地使用NSDate獲取HH:mm:ss的當前時間,但是我需要計數器從零開始並實現幀格式,如HH:mm:ss:ff從計算機時鐘引用的時間碼
想法?
使用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
這應該使用NSTimer對象並在調用中執行可視化更新。您可以將計時器設置爲每3.3333毫秒觸發一次。我看到的唯一問題是延長很長時間,時間碼會稍微偏離。另外,如果這與視頻有關,請注意,因爲某些視頻以24 fps編碼。然後我會有一個計數器在定時器觸發的方法中執行+1,除非counter = 30,那麼我將它重置爲1.您應該能夠使用自定義格式字符串初始化NSDateFormatter對象以插入當前時間和您想要顯示給用戶的格式的計數器變量。
我懷疑的NSTimer,如果說火每10.0/3.0毫秒,會像時鐘一樣精確。 –
NSTimer對我來說不夠準確。 – objectiveccoder001
我一直在搞這個... – objectiveccoder001
太棒了!問題,_ref來自哪裏? – objectiveccoder001
這是否比找到使用coreVideo顯示SMPTE時間碼的方式更好? – objectiveccoder001
對不起,'_ref'是'_link',我正在從我的測試項目中複製和粘貼...我懷疑有一個快速的方法讓CVTimeSTamp給你一個合適的smpteTime字段,但是我的日常工作讓我從完成我的研究:)現在我會採取一個NSDate並將其轉換成從午夜SMPTE幀數,抵消了正常運行時間,yada yada divmod ... – iluvcapra