Question

This has been driving me nuts for a while now.

I have very little knowledge of QTKit / QTMovie, but have created a little Cocoa app that previews a video and lets you save a 3 second version of it with Handbrake.

The problem is translating the current time on QTKit (QTTime), which is quite vague (seems to be nearest second), to frame number.

If you open a video in Quicktime Player 7, you can choose to see standard time or current frame. If I pass that frame number directly to the Handbrake CLI, the preview comes out super accurate.

So I've been trying to find a way to convert QTTime to absolute frame number, which seems to be based on samples in QTMedia (so confusing).

For instance, with this:

NSArray *videoTracks = [movie tracksOfMediaType:QTMediaTypeVideo];
QTTrack *tcTrack = [videoTracks objectAtIndex:0];

if (tcTrack != nil)
{     
    QTMedia * media = [tcTrack media];
    if (media != nil)
    {
        NSLog(@"sample : %@", [media attributeForKey:QTMediaSampleCountAttribute]);
    }
}

I get the total number of samples, which is the same as the final frame number on Quicktime Player 7.

What I need, I think, is the value for the sample count, at the specific point in time where I am, not the total.

Any thoughts on how I might be able to get that?

Thanks!

P.S:

Also tried using the following:

NSArray *videoTracks = [movie tracksOfMediaType:QTMediaTypeVideo];
QTTrack *tcTrack = [videoTracks objectAtIndex:0];

if (tcTrack != nil)
{     
    QTMedia * media = [tcTrack media];
    if (media != nil)
    {
        NSLog(@"sample : %@", [media attributeForKey:QTMediaSampleCountAttribute]);

        Media qtMedia = [media quickTimeMedia];
        MediaHandler mh = GetMediaHandler(qtMedia);

        long frameNum;

        TimeCodeDef tcDef;
        TimeCodeRecord tcData;
        UserData srcRefH;

        TCTimeCodeToFrameNumber(mh, &tcDef, &tcData, &frameNum);

        NSLog(@"frameNum %ld", frameNum);
        NSLog(@"tcData %d:%d:%d.%d", tcData.t.hours, tcData.t.minutes, tcData.t.seconds, tcData.t.frames);
    }
}

But all I get is:

frameNum -1 / tcData 0:2:0.0

Was it helpful?

Solution

Right, I've found a way of doing it! Thank the binary lord!

Here's my solution:

QTTime time = [movie currentTime];

NSArray *videoTracks = [movie tracksOfMediaType:QTMediaTypeVideo];
QTTrack *tcTrack = [videoTracks objectAtIndex:0];

Track track = tcTrack.quickTimeTrack;

Media media = GetTrackMedia(track);

SInt64 frameNum;

MediaDisplayTimeToSampleNum(media,
                            time.timeValue,
                            &frameNum,
                            NULL,
                            NULL);

NSLog(@"Save frame number %lli", frameNum);

Works like a charm, especially for what I want it too, which is to tell Handbrake CLI to save a 3 second clip from a specific frame (--start-at frame:xxx).

Can I haz my own bounty now?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top