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;

In reply to Video Thumbnail Script by MonkE

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.