0

私は基本的に、30fps でタイムコードを開始するボタンを押したいと思っています。(1/30 秒ごとに呼び出されます)。タイムコードをコンピューターに内蔵されている時計に合わせたい。NSDate を使用して HH:mm:ss で現在の時刻を簡単に取得できますが、カウンターをゼロから開始し、HH:mm:ss:ff のような形式のフレームを実装する必要があります。

考え?

4

2 に答える 2

3

a を使用して、ビデオ カードの精度でパルスを生成します。これは、またはディスパッチ キューCVDisplayLinkよりもはるかに正確です。NSTimerCoreMedia/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
于 2013-02-04T23:11:34.580 に答える
0

これは、NSTimerオブジェクトを使用し、呼び出しで視覚的な更新を行うことで機能するはずです。3.3333ミリ秒ごとに起動するようにタイマーを設定できます。私が見る唯一の問題は、非常に長いストレッチであり、タイムコードはわずかにずれています。また、これがビデオ関連の場合、一部のビデオは24 fpsでエンコードされるため、注意してください。次に、カウンター= 30でない限り、タイマーによって起動されたメソッドでカウンターに+1を実行させ、1にリセットします。NSDateFormatterオブジェクトをカスタムフォーマット文字列で初期化して、現在の時刻を挿入できるはずです。そして、ユーザーに表示したい形式のカウンター変数。

于 2013-02-04T22:57:58.197 に答える