Realbasic Amazes/Frustrates | Main | Writing my own FTP client...

March 23, 2006

Getting video framerate through the Quicktime API

Please note, this blog has been archived and now lives at www.discretecosine.com

This is a topic in which pitfalls abound, but I think I've just about sorted out the various ways to get an accurate idea of the a video file's framerate. I'm using RealBasic for this, but the calls should be pretty generic in any language that talks to quicktime.

If you poke around a bit, you'll find that the Movie.Timescale property is "sometimes" the number you're looking for. In particular, video files generated from Apple applications (FCP, Compressor) seem to have their timescale set to the framerate. However, many other files will have their timescale set to the sample rate of the audio track, or perhaps to something entirely different.

If you can use the timescale, go for it. It's much faster than the alternative. Note that it may come in as an int - so 2997 instead of 29.97.

What I'm doing is testing whether the timescale number makes reasonable sense in the context of video. I figure I'm not likely to have a video with a framerate higher than 60fps, or lower than 10fps. If the timescale result falls somewhere outside those bounds, I fallback to an alternative method.

By using the GetNextInterestingTime Quicktime call, or in Realbasic using NextInterestingVideoTimeMBS (requires MonkeyBread) you can measure the time between frames. NextInterestingVideoTimeMBS will return the current time in the movie and the duration of time between two "interesting times" (which usually equate to frames). The number you're most interested in is the duration. By calling NextInterestingVideoTime a few times, you can be sure that the duration of each frame is the same.

Once you've got your duration number, you can divide your Timescale by the duration, and get the number of frames per second. You can even reset the Timescale to your new value (multiplied by 100) and then use the TimeDuration call to get the length of the movie in seconds.

Seems to work pretty reliably on the videos I've thrown at it. Anybody have better methods?

Posted by at March 23, 2006 2:19 PM | Tutorials

Comments

Hi there,

I think I've got a better way to do it. I haven't tested it much, but I think that it should work on most files. If you notice, in the Finder, you can select a movie and see what it's duration is. You can execute a shell script to find that value (calculated in seconds). This doesn't require anything like MonkeyBread, but I don't know how you would do it in RealBasic. Below is the Applescript code that I use. (I convert it to minutes here.)

theMovie = a reference to the file you want to find out about

set durationSeconds to do shell script ("mdls -name kMDItemDurationSeconds " & quoted form of POSIX path of theMovie)
set OldDelims to AppleScript's text item delimiters
set AppleScript's text item delimiters to {"kMDItemDurationSeconds = "}
set durationMinutes to ((second text item of durationSeconds) / 60)
set AppleScript's text item delimiters to OldDelims

The actual shell script looks like this:
mdls -name kMDItemDurationSeconds '/Users/UserName/Movies/Artic_Fishing.mpg'

It's response looks like this:
/Users/UserName/Desktop/temp/folder2/Artic_Fishing.mpg -------------
kMDItemDurationSeconds = 20.92

I hope that might be helpful. There are many other characteristics that you can find out through this command. To see them, just run it without the "-name kMDItemDurationSeconds" and it will return everything.

Posted by: Joseph Bayly at January 15, 2007 9:39 PM