Creating video framegrabs from the command line

So, I’ve been hacking around with different methods for getting stills from video files via the command line. This is part of a larger project I’m working on, but I figured I’d document what I’ve come up with to hopefully make things easier for folks in the future.

Click the link for more…

So, first off, if you’re not working on a Mac OSX / OSX Server platform, your options are pretty limited. You’re pretty much guaranteed to end up using something related to ffmpeg, unless you go for commercial software.

In my case, this needs to happen via some interaction with a php script, so the easiest approach is to use the ffmpeg-php extension. This is actually a very cool extension, though it’s rather fiddly to get installed right. You can get all sorts of information about a video, and extract whatever information you need.

A few downsides present themselves though. First off, ffmpeg is what we might fairly call “patent encumbered.” Because nobody is paying the MPEG-LA for use of the mpeg codecs, ffmpeg is in violation of any number of patents. Now, you’re fairly unlikely to be personally harmed for using it, but it’s important to be aware of the legality.

Next, and more pressing, ffmpeg is terrible for doing frame grabs. You get lots of control, but it gets slower as a linear function of how far into the video you need to seek. It almost seems like it converts every frame of the video up to and including your target frame. On my 2ghz g5, it can do a grab of the first frame of a video instantly, but grabbing a frame from 10 minutes in can take up to 60 seconds. That’s unacceptable. I need to poke in the code a bit more to get a better sense of why that’s happening – it happens with both the CVS and stable branch, no matter how I compile it.

As best as I can tell, if you’re on a non-Mac platform, that’s really the only free way to do it. So let’s move on to the Mac options.

First, you can use applescript (via osacript) to make Quicktime do it for you. You’ll need QT Pro. This may be a good option for very low volume uses where you can monitor the display. Unfortunately, my experience with applescript and Quicktime is that things often go awry. Further, you’re limited to performing one operation at a time, which is tough to do when you’re deal with web access. You’d need to create a backend to do batch processing at intervals – no fun!

Next, you can use the QT_Tools software. This is a very lightweight set of applications which make calls into the Quicktime API. If you’re looking to learn the Quicktime API, these are actually pretty helpful too. The source is available, but developer support is limited.

Semi-related, you should take a look at the movtoy4m software. It also uses the Quicktime API via the command line to do simple video processing. It’s pretty helpful for pulling basic information. It is essentially abandoned at this point.

So that’s where I’m at. I think for my solution, I’ll end up using the QT_Tools route. I’m somewhat tempted to learn how to write a php extension and just code my own PHP-Quicktime ext. I get the feeling though that this wouldn’t be nearly as easy as it seems. Perhaps I’ll just make some very stripped down binaries I can call from within PHP.

Anyone have a fantastic option that I haven’t thought of?

9 thoughts on “Creating video framegrabs from the command line

  1. Here’s the applescript, if anyone’s curious. Run it from osascript with the movie as arg1 and the frame number as arg 2. A lot of this code came from Apple’s QT examples.
    on run argv
    tell application “QuickTime Player”
    activate
    open item 1 of argv as POSIX file
    set the current time of movie 1 to item 2 of argv as number
    if not (exists movie 1) then error “No movies are open.”
    stop every movie
    set the new_file to “image.jpg”
    set AppleScript’s text item delimiters to “:”
    set the new_name to the last text item of (the new_file as string)
    set the destination_folder to desktop & “:”
    set AppleScript’s text item delimiters to “”
    set the current_time to current time of movie 1
    select none of movie 1
    copy movie 1
    make new movie
    paste movie 1
    — create a unique temp folder
    repeat
    set this_name to (random number from 100000 to 999999) as string
    tell application “Finder”
    if not (exists folder this_name of the desktop) then
    set the temp_folder to (make new folder at desktop with properties {name:this_name}) as alias
    exit repeat
    end if
    end tell
    end repeat
    set the tempfile_name to “TEMP_IMAGE”
    set the target_file to ((temp_folder as string) & tempfile_name)
    — export the image as a JPEG
    export movie 1 to file target_file as image sequence using settings preset “JPEG, 25 fps”
    quit
    end tell
    end run

  2. Very nice. If you’re happy to involve Applescript, you might add iMagine Photo to your list:
    A very nice piece of freeware which can also export movies. (It’s essentially a scripting interface for the QuickTime graphics API.)

  3. Don’t know if your found http://www.videoscript.com/
    from their page – “VideoScript is free to download and use. Some extra features are available in the professional version”
    it might do the things you want to do – doesn’t have php integrated, but your migth be able to store things,…
    Sven

  4. I’m looking for this functionality right now, I get quicktimes from a camera ftp’d to a website, I then need to extract the 2nd frame from each quicktime via php and display it on a page. I was going to write a java command line version of the extract then call it from php, but if you have made any headway in the php integration I’d love to see it.

  5. On the subject of PHP…
    I know for a fact that PHP4 is better (at least at this time) until all of the bugs are worked out of PHP5. Just like any other script, software etc. it takes time to work out all the bugs. As of right now our website contains about 800 professionally designed and written PHP scripts however even our programmers, coders know that majority of the scripts will work the best with PHP4. That is not
    to say that we dont have some that will work with both however usually coding or “tweaking” them to work with both costs us too much development time.
    So, for now. IMHO stick with PHP4 until all the bugs are worked out of PHP5, then
    go for it.
    Also, just for reference we also have some PHP scripts for posting videos (yes even in quicktime) that will stream from the users browser. Without any plugins or ffmpeg codex installed on the hosting account.
    PopScript.com

  6. Use mplayer!!!
    mplayer video.avi -vo jpeg
    Try that! does a 30second decent res 40meg MOV file in about 1min on my system.
    (your welcome)

  7. Unfortunately, that amount of time is exactly the problem. Mplayer and ffmpeg get linearly slower as the video gets longer. That doesn’t work for a web app. I needed extraction times on the order of 1/10th of a second. So, that’s why I went the custom code route…

  8. VLC rocks for still image extraction — cross platform, plus it jumps around instantaneously. It might not be quite as fast as your applescript, but it beats the crap out of twiddling your thumbs waiting for ffmpeg. Here’s a sample command:
    C:VLCvlc.exe -V image –image-out-format png –start-time=200 –stop-time=202 –image-out-prefix g:ripstest –image-out-ratio 24 g:ripsmr1022.mpg vlc:quit

Leave a Reply to grant Cancel reply