none
Get a thumbnail image from a video file!!

    Question

  • Hello,

     

    How can i get a snapshot image from a video file programatically? e.g. get the first frame of the video file.

    Is there any free library i can import?

     

    Thanks a lot

    Thursday, May 24, 2007 11:00 AM

Answers

  • Well, I think it actually does use the mplayer.exe not the library, as those look alot like the command line arguments that you can send to mplayer in windows as well.  Your point about unable to detect errors... well that isn't entirely true as you can redirect the standard error of the process, but it is still a valid point.

    If you look up the command line switches for mplayer, and use the System.Diagnostics.Process class, you will be able to do what you need... although I'll admit a nice library with source provided for easy debugging would be a lot nicer if someone happens to know of one.

    -mwalts
    Monday, May 28, 2007 10:42 PM
  • You're right, mwalts.

    Now here is one sample written in VB.NET, which generates thumbnail image from uploaded video file.

    I have marked relevant code in blue font. Please refer to it.

     

    Code Snippet

    Imports System.Drawing
      Imports System.IO

     

    Public Class admin_upimg
        Inherits Web.PageBase
        Protected WithEvents Btnup As System.Web.UI.WebControls.Button
        Protected WithEvents uplTheFile As System.Web.UI.HtmlControls.HtmlInputFile
        Protected WithEvents fileinfo As System.Web.UI.WebControls.Label

      Protected WithEvents chkslt As System.Web.UI.WebControls.CheckBox
        Protected WithEvents Txtslt As System.Web.UI.WebControls.TextBox
        Protected WithEvents Txt As System.Web.UI.WebControls.TextBox
        Protected WithEvents Chkonly As System.Web.UI.WebControls.CheckBox
        Protected WithEvents Chkshow As System.Web.UI.WebControls.CheckBox
        Protected WithEvents Txtfileadd As System.Web.UI.WebControls.TextBox

     

        <System.Diagnostics.DebuggerStepThrough()>

        Private Sub InitializeComponent()

        End Sub

     

        Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
            InitializeComponent()
          End Sub

     

        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
          End Sub

     

        Private Sub Btnup_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btnup.Click

          Txtfileadd.Text = ""
            Txtslt.Text = ""


            If uplTheFile.PostedFile.ContentLength = 0 Then
                fileinfo.Visible = False
                Txtfileadd.Text = "The file length cannot be 0."
                Exit Sub
            Else
                fileinfo.Visible = True
            End If
            Dim temnow As String = System.DateTime.Now.ToString("yyMMddhhffffff")


            'Save picture

            If Chkonly.Checked Then
            Else
                uplTheFile.PostedFile.SaveAs(Server.MapPath("../images/upload" + "/" + temnow + ".jpg"))
            End If


            'Generate thumbnail image from uploaded video file
            If chkslt.Checked Then
                Try
                    Dim Image As System.Drawing.Image

                    If Chkonly.Checked Then
                        Image = System.Drawing.Image.FromStream(uplTheFile.PostedFile.InputStream)
                    Else
                        Image = System.Drawing.Image.FromFile(Server.MapPath("../images/upload" + "/" + temnow + ".jpg"))
                    End If

                  Dim width = Image.Width
                    Dim height = Image.Height
                    Dim newwidth As Integer
                    Dim newheight As Integer

                    If width > height Then
                        newwidth = 120
                        newheight = Image.Height / Image.Width * newwidth
                    Else
                        newheight = 90
                        newwidth = Image.Width / Image.Height * newheight
                    End If

                    Dim callb As System.Drawing.Image.GetThumbnailImageAbort
                      Dim anewimage = Image.GetThumbnailImage(newwidth, newheight, callb, New System.IntPtr)

                    anewimage.Save(Server.MapPath("../images/upload" + "/" + temnow + "t" + ".jpg"))
                    Image.Dispose()

                    Txtslt.Text = "../images/upload" + "/" + temnow + "t" + ".jpg"

                    Response.Write("<script>opener.SetTitleImg(""" & Txtslt.Text & """);</script>")
                Catch
                    Txtslt.Text = "Fail to generate thumbnail maybe due to incorrect image format"
                End Try
            End If

            If Chkonly.Checked Then

            Else
                Txtfileadd.Text = "../images/upload" + "/" + temnow + ".jpg"
                If Chkshow.Checked Then
                    Response.Write("<script>opener.SetBodyImg(""" & "<IMG sRc=" & Txtfileadd.Text & ">" & """);</script>")
                End If
            End If

     

        End Sub


    End Class

     

    Hope that helps!

     

     

    Tuesday, May 29, 2007 7:42 AM

All replies

  • 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 pathname of the file.

    Video Thumbnail Script

    #!/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;

     http://www.perlmonks.org/?node_id=604177

     

     

    Monday, May 28, 2007 8:13 AM
  • First thanks for reply as hardly to get replies these days

     

    But it is really funny to have a reply for CGI here in microsoft forums and specifically in C# forums,

    Any way i could hardly understand the code but :

    1-we use the mplay exe program and not the library:

    This is a very problem-causing technique as we run the mplayer in a separate process which makes us unable to detect errors, And also we cannot detect the time when it finish grabing the thumbnail!!

    Most websites need to enter data of the video or the thumbs in the DB so it is important to detect if the operation successfully finished or not... because all of this must go into one transaction.

     

    2-We cannot use the libraries of the mplayer as it is not COM or .Net and it is not static functions so we cannot anyway call classes methods of this library

     

    Regards

    Monday, May 28, 2007 7:47 PM
  • Well, I think it actually does use the mplayer.exe not the library, as those look alot like the command line arguments that you can send to mplayer in windows as well.  Your point about unable to detect errors... well that isn't entirely true as you can redirect the standard error of the process, but it is still a valid point.

    If you look up the command line switches for mplayer, and use the System.Diagnostics.Process class, you will be able to do what you need... although I'll admit a nice library with source provided for easy debugging would be a lot nicer if someone happens to know of one.

    -mwalts
    Monday, May 28, 2007 10:42 PM
  • You're right, mwalts.

    Now here is one sample written in VB.NET, which generates thumbnail image from uploaded video file.

    I have marked relevant code in blue font. Please refer to it.

     

    Code Snippet

    Imports System.Drawing
      Imports System.IO

     

    Public Class admin_upimg
        Inherits Web.PageBase
        Protected WithEvents Btnup As System.Web.UI.WebControls.Button
        Protected WithEvents uplTheFile As System.Web.UI.HtmlControls.HtmlInputFile
        Protected WithEvents fileinfo As System.Web.UI.WebControls.Label

      Protected WithEvents chkslt As System.Web.UI.WebControls.CheckBox
        Protected WithEvents Txtslt As System.Web.UI.WebControls.TextBox
        Protected WithEvents Txt As System.Web.UI.WebControls.TextBox
        Protected WithEvents Chkonly As System.Web.UI.WebControls.CheckBox
        Protected WithEvents Chkshow As System.Web.UI.WebControls.CheckBox
        Protected WithEvents Txtfileadd As System.Web.UI.WebControls.TextBox

     

        <System.Diagnostics.DebuggerStepThrough()>

        Private Sub InitializeComponent()

        End Sub

     

        Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
            InitializeComponent()
          End Sub

     

        Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
          End Sub

     

        Private Sub Btnup_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Btnup.Click

          Txtfileadd.Text = ""
            Txtslt.Text = ""


            If uplTheFile.PostedFile.ContentLength = 0 Then
                fileinfo.Visible = False
                Txtfileadd.Text = "The file length cannot be 0."
                Exit Sub
            Else
                fileinfo.Visible = True
            End If
            Dim temnow As String = System.DateTime.Now.ToString("yyMMddhhffffff")


            'Save picture

            If Chkonly.Checked Then
            Else
                uplTheFile.PostedFile.SaveAs(Server.MapPath("../images/upload" + "/" + temnow + ".jpg"))
            End If


            'Generate thumbnail image from uploaded video file
            If chkslt.Checked Then
                Try
                    Dim Image As System.Drawing.Image

                    If Chkonly.Checked Then
                        Image = System.Drawing.Image.FromStream(uplTheFile.PostedFile.InputStream)
                    Else
                        Image = System.Drawing.Image.FromFile(Server.MapPath("../images/upload" + "/" + temnow + ".jpg"))
                    End If

                  Dim width = Image.Width
                    Dim height = Image.Height
                    Dim newwidth As Integer
                    Dim newheight As Integer

                    If width > height Then
                        newwidth = 120
                        newheight = Image.Height / Image.Width * newwidth
                    Else
                        newheight = 90
                        newwidth = Image.Width / Image.Height * newheight
                    End If

                    Dim callb As System.Drawing.Image.GetThumbnailImageAbort
                      Dim anewimage = Image.GetThumbnailImage(newwidth, newheight, callb, New System.IntPtr)

                    anewimage.Save(Server.MapPath("../images/upload" + "/" + temnow + "t" + ".jpg"))
                    Image.Dispose()

                    Txtslt.Text = "../images/upload" + "/" + temnow + "t" + ".jpg"

                    Response.Write("<script>opener.SetTitleImg(""" & Txtslt.Text & """);</script>")
                Catch
                    Txtslt.Text = "Fail to generate thumbnail maybe due to incorrect image format"
                End Try
            End If

            If Chkonly.Checked Then

            Else
                Txtfileadd.Text = "../images/upload" + "/" + temnow + ".jpg"
                If Chkshow.Checked Then
                    Response.Write("<script>opener.SetBodyImg(""" & "<IMG sRc=" & Txtfileadd.Text & ">" & """);</script>")
                End If
            End If

     

        End Sub


    End Class

     

    Hope that helps!

     

     

    Tuesday, May 29, 2007 7:42 AM
  • Thanks mwalts i used Process.WaitForExit() and worked as expected.

    Sorry Martin, i dont know if u r sure about what u r posting!! i don't think - My little knowlege - that i can grap thumbnails from videos that way!!

    I cannot use Image.FromStream(file1.PostedFile.InputStream) except the uploaded file is an image file!!

    How that worked with you?

     

    Invalid parameter used exception will be generated!!

    Tuesday, May 29, 2007 2:50 PM
  • hi thanks a lot....
    I was looking for the same thing..
    But I am working with silverlight .

    If u please help me.


    Thanks a lot in advance.
    Wednesday, September 17, 2008 2:37 PM
  • I have seen this code and tried to understand,Probably it's generating 1 image ,But I need 5 or more images at diffrent time for the particular video.
    So Please help me.
    Wednesday, September 17, 2008 2:46 PM
  • I mean generating images for Chapters of same video.
    Wednesday, September 17, 2008 3:01 PM