Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Video Thumbnail Script

by MonkE (Hermit)
on Mar 11, 2007 at 03:43 UTC ( [id://604177]=CUFP: print w/replies, xml ) Need Help??

My collection of home movies consists of snippets of video ranging in length from 1 to 15 minutes. To keep track of them, I use a postgres SQL database with a custom, web-based front end. The interface looked a bit bland so I decided to spice it up a bit by adding a dynamically generated thumbnail for each video. The following is a CGI script that uses mplayer to extract a thumbnail from a video. The parameters are "dir" and "filename", which are local pathnames (not URLs) to the file. The script works quite well for my needs, but any feedback would be welcome.
#!/usr/bin/perl use strict; use warnings; use POSIX qw/strftime/; use CGI qw/:standard/; sub handle_error($) { my $msg = shift or die; print header(-type => 'text/plain'), $msg; die; } my $num_frames = 7; my $thumb_dir = '/tmp'; my $thumb_offset_pct = 15; my $thumb_offset; my $thumb_pathname; my $video_pathname = param('dir') or die; $video_pathname .= '/' . param('filename') or die; # clean up from previous incarnations # TODO make this multi-user capable, so that muliple simultaneous inst +ances do not walk on each other for (1..$num_frames+1) { $thumb_pathname = sprintf("%s/%8.8d.jpg", $thumb_dir, $_); unlink $thumb_pathname or die if -f $thumb_pathname; } # determine the length of the video my ($video_len) = grep(/^ID_LENGTH=/, (`mplayer -identify \"$video_pat +hname\" -nosound -vc dummy -vo null`)); if ( $video_len !~ /^[^=]+=(.*)$/ ) { die 'Unable to read video length'; } $video_len = $1; # this mplayer command will produce a series of JPEG images, one of wh +ich will be our thumbnail $thumb_offset = int( $video_len * $thumb_offset_pct / 100 ); my $cmd = "mplayer -zoom -ss $thumb_offset -nosound -vo jpeg:outdir=/t +mp -frames $num_frames -vf scale=250:-3 \"$video_pathname\" > /dev/nu +ll 2>&1"; my $retval = system($cmd); #handle_error 'Command failed: ' . $cmd if $retval != 0; binmode STDOUT; # choose the highest numbered frame, since lower numbered # frames tend to be incomplete. my $frame = $num_frames + 1; while ($frame ge 1) { $thumb_pathname = sprintf("%s/%8.8d.jpg", $thumb_dir, $frame); last if -f $thumb_pathname; $frame--; } handle_error 'No thumbnail created.' if ! -f $thumb_pathname; # now we have chosen the right pathname # get the last-modified timestamp for the video in question, # so that we can set the HTTP last-modified header. my @info = stat($video_pathname) or die 'Unable to stat() video +'; my @ts = gmtime($info[9]); my $timestamp = strftime("%a, %d %b %Y %H:%M:%S GMT", @ts); open IMG, '<' . $thumb_pathname or die 'Unable to open thumbnail'; print header( -type => 'image/jpeg', -last_modified => $timestamp); print <IMG>; close IMG;

Replies are listed 'Best First'.
Re: Video Thumbnail Script
by DancesWithBumbleBees (Novice) on Mar 30, 2007 at 19:01 UTC

    Oh, man.. Being soo brand new at this and of all the gabillion snippets of code (nodes??) I could stumble upon right off the bat, yours 'bout knocked me off my chair just now.. If, down the road, it turns out to be something that could be applied to a very special project I've just become associated with, you'll be the first to hear (for the purpose of permissions, gracious credits, et al)..

    Very cool.. :)

Re: Video Thumbnail Script
by Anonymous Monk on Apr 01, 2007 at 21:21 UTC
    Hello MonkE, I wanted to get a thumbnail of a video file (.avi or .wmv) and also get the length (play time) of the video. I came across your script here but not quite know how to use it. I'm familiar with php but new to cgi, I try execute your cgi but couldn't get it to work. Can you tell me the steps in using your Video thrmbnail Script? Thanks in advance, -d

      First thing: I don't recommend you use it on an internet-facing web server. I just threw it together for my own mollification. It is not hardened for internet use. Let's face it, it's accepting local pathnames as parameters. It's not internet-safe.

      CGI scripts frequently go in the cgi-bin directory of your web server or wherever it's configured to look for CGI scripts. Also, this particular script assumes that you are on a Unix-based system (the mplayer command invocations are Unix-specific).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://604177]
Approved by Joost
Front-paged by liverpole
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-04-19 08:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found