green php elephants - elephpantsThanks to the powerful command line ffmpeg package and PHP’s ability to execute server commands through shell_exec, generating a thumbnail image from a given video file becomes a snap!

First, install the ffmpeg package onto your Ubuntu server with:

sudo apt-get install ffmpeg

Once installed, we can then turn our attention to the PHP script that will be doing the slog work. Essentially it uses ffmpeg to process the video file and create the image for us, meaning that in actual fact, the PHP script has very little to do with the actual donkey work!

function createVideoThumbnails($videopath,$imagepath) {
    $status = false;

    // where ffmpeg is located, such as /usr/sbin/ffmpeg
    $ffmpeg = '/usr/bin/ffmpeg';

    // the input video file
    $video = $videopath;

    if (file_exists($video)) {

        // where you'll save the image
        $image = $imagepath;

        // default time to get the image
        $second = 1;

        // get the duration and a random place within the video file
        $cmd = "$ffmpeg -i \"$video\" 2>&1";
        if (preg_match('/Duration: ((\d+):(\d+):(\d+))/s', `$cmd`, $time)) {
            $total = ($time[2] * 3600) + ($time[3] * 60) + $time[4];
            $second = rand(1, ($total - 1));
        }

        // get the screenshot
        $cmd = "$ffmpeg -i \"$video\" -deinterlace -an -ss $second -t 00:00:01 -r 1 -y -vcodec mjpeg -f mjpeg \"$image\" 2>&1";
        $return = `$cmd`;

        if (file_exists($image)) {
            $status = true;
        } else {
            $status = false;
        }
    } else {
        $status = false;
    }
    return $status;
}

We make two calls to the ffmpeg function, the first to work out the duration of the video which we then use to make a random call as to where to take the thumbnail from in terms of starting point. The second call actually generates the thumbnail image, using the fully qualified video and image paths that we passed to the function right at the start.

So pretty simple stuff in other words. Note that if you want to specify the size of the generated screenshot, you can make use of the -s parameter. For example:

$cmd = "$ffmpeg -i \"$video\" -deinterlace -an -ss $second -t 00:00:01 -r 1 -y -vcodec mjpeg -s 180x135 -f mjpeg \"$image\" 2>&1";

Nifty.