Author Topic: Using ffmpeg to generate uploaded video thumbnails  (Read 115501 times)

0 Members and 1 Guest are viewing this topic.

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Using ffmpeg to generate uploaded video thumbnails
« on: March 24, 2006, 10:39:55 AM »
Hello All !!

Let me start my first post with a Congratulations on a fantastic system... I Have performed various mods and on the most part they were quite easy to configure.

There is one item missing for me which is the generation of thumbnails from video files. Searching through the forum has lead to a couple posts about this topic, but none that actually suggest the use of ffmpeg as the tool to save the day  :lol:

I've tried to investigate the ImageMagick and GD2 solutions but both of them appear to not really support video too well.

From analyzing ffmpeg and testing it from the command line - it appears to generate a thumbnail from quite a range of different video sources.

Here is where i need help. i have the command required to generate the thumbnail - BUT i don't know where to put it. :roll:


The command i use is

Code: [Select]
ffmpeg -i 1.mpg -f singlejpeg -t 0.001 1.jpg
The only variables that would need to pass to it are the exe location, source video file & destination thumbnail name

I think the best implementation of it would be the same way that ImageMagick is handled in the system:
1. Control panel asks for the location of the .exe
2. extensions are associated to it
3. the command gets executed the same time as normal images are handled.

Considdering the great demand for video these days, i think it should be considdered as a standard feature of 4Images (Just like Imagemagick).

I Am using 4I 1.7.2 (with a couple cool mods  8) )

Can anybody do this?

Cheers,
WeZ

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #1 on: March 27, 2006, 01:23:18 PM »
Hi All,

I think to acheive this i need to modify the admin/checkimages.php file?

Has anybody got a clue on where i can even start?

Thanks

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #2 on: March 27, 2006, 09:41:17 PM »
Hi All,

Please can someone help me...

I placed the ffmpeg binary into the system32 dir and also the 4images root.

I created this code
Code: [Select]
function Generate_VideoThumb($src, $dest) {
  global $convert_options;

  $command = "ffmpeg -i ".$src." -f singlejpeg -t 0.001 ".$dest;
  system($command);
  return (file_exists($dest)) ? 1 : 0;
}

and placed it into image_utils.php

i also changed

Code: [Select]

function create_thumbnail($src, $dest, $quality, $dimension, $resize_type) {
  global $convert_options;

  if (file_exists($dest)) {
    @unlink($dest);
  }
  $image_info = (defined("IN_CP")) ? getimagesize($src) : @getimagesize($src);
 if (!$image_info) {
    return false;
  }
  $width_height = get_width_height($dimension, $image_info[0], $image_info[1], $resize_type);
  $resize_handle = "resize_image_".$convert_options['convert_tool'];
  if ($resize_handle($src, $dest, $quality, $width_height['width'], $width_height['height'], $image_info)) {
    @chmod($dest, CHMOD_FILES);
    return true;
  }
  else {
    return false;
  }
}


to

Code: [Select]
function create_thumbnail($src, $dest, $quality, $dimension, $resize_type) {
  global $convert_options;

  if (file_exists($dest)) {
    @unlink($dest);
  }
  $image_info = (defined("IN_CP")) ? getimagesize($src) : @getimagesize($src);
   if (!$image_info) {
  if ($Generate_VideoThumb($src, $dest)) {
return true;
}
else {
    return false;
    }
  }
  $width_height = get_width_height($dimension, $image_info[0], $image_info[1], $resize_type);
  $resize_handle = "resize_image_".$convert_options['convert_tool'];
  if ($resize_handle($src, $dest, $quality, $width_height['width'], $width_height['height'], $image_info)) {
    @chmod($dest, CHMOD_FILES);
    return true;
  }
  else {
    return false;
  }
}

Please can someone tell me why it is not working??

Offline IcEcReaM

  • Hero Member
  • *****
  • Posts: 714
    • View Profile
    • My little Testboard
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #3 on: March 27, 2006, 10:48:36 PM »
try to replace this:
Code: [Select]
if ($Generate_VideoThumb($src, $dest)) {
with this
Code: [Select]
if (Generate_VideoThumb($src, $dest)) {
in your image_utils.php

Coding is a everlasting competition between programmers who tries to write larger, better and idiot-safe programs and the universe producing larger and stupider idiots...
...so far the universe won
bump

Offline V@no

  • If you don't tell me what to do, I won't tell you where you should go :)
  • Global Moderator
  • 4images Guru
  • *****
  • Posts: 17.849
  • mmm PHP...
    • View Profile
    • 4images MODs Demo
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #4 on: March 28, 2006, 04:05:16 AM »
and unless ffmpeg is registered in the system, you will need add full path to it. i.e. C:\\WINDOWS\\SYSTEM32\\ffmpeg.exe
Your first three "must do" before you ask a question:
Please do not PM me asking for help unless you've been specifically asked to do so. Such PMs will be deleted without answer. (forum rule #6)
Extension for Firefox/Thunderbird: Master Password+    Back/Forward History Tweaks (restartless)    Cookies Manager+    Fit Images (restartless for Thunderbird)

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #5 on: March 28, 2006, 09:34:56 AM »
Hello  IcEcReaM and V@no !!

From all the posts i've read on this forum, my help could'nt have come in a better form than you 2...


From both of your valuable Input I have changed the blocks of code to read:

Code: [Select]
function create_thumbnail($src, $dest, $quality, $dimension, $resize_type) {
  global $convert_options;

  if (file_exists($dest)) {
    @unlink($dest);
  }
  $image_info = (defined("IN_CP")) ? getimagesize($src) : @getimagesize($src);
  if (!$image_info) {
  if (Generate_VideoThumb($src, $dest)) {
return true;
}
else {
    return false;
    }
  }
  $width_height = get_width_height($dimension, $image_info[0], $image_info[1], $resize_type);
  $resize_handle = "resize_image_".$convert_options['convert_tool'];
  if ($resize_handle($src, $dest, $quality, $width_height['width'], $width_height['height'], $image_info)) {
    @chmod($dest, CHMOD_FILES);
    return true;
  }
  else {
    return false;
  }
}

and

Code: [Select]
function Generate_VideoThumb($src, $dest) {
  global $convert_options;

  $command = "C:\\WINDOWS\\SYSTEM32\\ffmpeg.exe -i ".$src." -f singlejpeg -t 0.001 ".$dest;
  system($command);
  return (file_exists($dest)) ? 1 : 0;
}

I Have a feeling that there is someplace else that needs a little code because right now, I'm not even sure if it is being executed as i'm not getting any errors or anything...

hang on... Let me check the logs...

ok, I've attached a text file of what was found in my server logs...

There is no Line 223 in my image_utils.php and i have attached my admin_functions for your perusal...

How can i debug this Function? :roll:


Once again, thanks for your help...

WeZ

Offline V@no

  • If you don't tell me what to do, I won't tell you where you should go :)
  • Global Moderator
  • 4images Guru
  • *****
  • Posts: 17.849
  • mmm PHP...
    • View Profile
    • 4images MODs Demo
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #6 on: March 28, 2006, 09:42:02 AM »
debug is easy:
instead of system($command); use: echo $command;
then if it print something on the screen copy it and then paste it in the command prompt (you might need replace \\ with only single back slash)
and see if it create the screenshot.
If it didnt print anything, then you know the function wasnt executed.

as of errors, you must have added a space/newline, whatever before <?php or after ?> in image_utils.php
Your first three "must do" before you ask a question:
Please do not PM me asking for help unless you've been specifically asked to do so. Such PMs will be deleted without answer. (forum rule #6)
Extension for Firefox/Thunderbird: Master Password+    Back/Forward History Tweaks (restartless)    Cookies Manager+    Fit Images (restartless for Thunderbird)

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #7 on: March 28, 2006, 10:37:38 AM »
Hi V@no,

thanks for the speedy reply...

debug is easy:
instead of system($command); use: echo $command;
then if it print something on the screen copy it and then paste it in the command prompt (you might need replace \\ with only single back slash)
and see if it create the screenshot.
If it didnt print anything, then you know the function wasnt executed.

Correct, it did not print anything...

as of errors, you must have added a space/newline, whatever before <?php or after ?> in image_utils.php

This this i did by mistake yesterday - I used the section after the "?>" as a scratchpad to write my code before inserting it into the function... this was rectified yesterday already so i guess these errors are old...

not sure if i'm happy or sad to not get any errors...  :|

Anyway... i did some more testing and found that if i put echo code into the  if (!$image_info) query:
Code: [Select]
function create_thumbnail($src, $dest, $quality, $dimension, $resize_type) {
  global $convert_options;

  if (file_exists($dest)) {
    @unlink($dest);
  }
  $image_info = (defined("IN_CP")) ? getimagesize($src) : @getimagesize($src);
  if (!$image_info) {
  if (Generate_VideoThumb($src, $dest)) {
echo $src.$dest;
return true;
}
else {
echo $src.$dest;
    return false;
    }
  }
  $width_height = get_width_height($dimension, $image_info[0], $image_info[1], $resize_type);
  $resize_handle = "resize_image_".$convert_options['convert_tool'];
  if ($resize_handle($src, $dest, $quality, $width_height['width'], $width_height['height'], $image_info)) {
    @chmod($dest, CHMOD_FILES);
    return true;
  }
  else {
    return false;
  }
}

it still did not output anything... so i put an echo outside the query as well like this:
Code: [Select]
function create_thumbnail($src, $dest, $quality, $dimension, $resize_type) {
  global $convert_options;

  if (file_exists($dest)) {
    @unlink($dest);
  }
  $image_info = (defined("IN_CP")) ? getimagesize($src) : @getimagesize($src);
  if (!$image_info) {
  if (Generate_VideoThumb($src, $dest)) {
echo $src.$dest;
return true;
}
else {
echo $src.$dest;
    return false;
    }
  }
  echo $src.$dest;
  $width_height = get_width_height($dimension, $image_info[0], $image_info[1], $resize_type);
  $resize_handle = "resize_image_".$convert_options['convert_tool'];
  if ($resize_handle($src, $dest, $quality, $width_height['width'], $width_height['height'], $image_info)) {
    @chmod($dest, CHMOD_FILES);
    return true;
  }
  else {
    return false;
  }
}

and my results were that i did not get an output for video files but on an uploaded image i got this echoed output:
Quote
./data/media/1/alpha9.jpg./data/thumbnails/1/alpha9.jpg

so i would say that when uploading a video it is not even calling the "create_thumbnail" function at all?

Anyplace else i should be editing code?

Kind Regards,
Wesley.
« Last Edit: March 28, 2006, 11:22:20 AM by WeZ »

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #8 on: March 28, 2006, 03:51:06 PM »
Hello All,

Bit of a breakthrough, but not there yet...

If i changed this code on member.php

from

Code: [Select]
    // Uplad thumb file
    $new_thumb_name = "";
    if (!empty($HTTP_POST_FILES['thumb_file']['tmp_name']) && $HTTP_POST_FILES['thumb_file']['tmp_name'] != "none" && !$uploaderror) {
      $new_thumb_name = $site_upload->upload_file("thumb_file", "thumb", $upload_cat, basename($new_name));
      if (!$new_thumb_name) {
        $msg .= (($msg != "") ? "<br />" : "")."<b>".$lang['thumb_upload_error'].": ".$new_thumb_name."</b><br />".$site_upload->get_upload_errors();
        @unlink(MEDIA_TEMP_PATH."/".$new_name);
        $uploaderror = 1;
      }
    }
    elseif (check_remote_thumb($remote_thumb_file)) {
      $new_thumb_name = $remote_thumb_file;
    }
    elseif ($config['auto_thumbnail'] == 1 && !empty($HTTP_POST_FILES['media_file'.$fileext]['tmp_name']) && $HTTP_POST_FILES['media_file'.$fileext]['tmp_name'] != "none" && !$uploaderror) {
      if ($direct_upload) {
        $src = MEDIA_PATH."/".$cat_id."/".$new_name;
        $dest = THUMB_PATH."/".$cat_id."/".$new_name;
      }
      else {
        $src = MEDIA_TEMP_PATH."/".$new_name;
        $dest = THUMB_TEMP_PATH."/".$new_name;
      }
      $do_create = 0;
      if ($image_info = @getimagesize($src)) {
        if ($image_info[2] == 1 || $image_info[2] == 2 || $image_info[2] == 3) {
          $do_create = 1;
        }
      }
      if ($do_create) {
        require_once(ROOT_PATH.'includes/image_utils.php');
        $convert_options = init_convert_options();
        if (!$convert_options['convert_error']) {
          $dimension = (intval($config['auto_thumbnail_dimension'])) ? intval($config['auto_thumbnail_dimension']) : 100;
          $resize_type = (intval($config['auto_thumbnail_resize_type'])) ? intval($config['auto_thumbnail_resize_type']) : 1;
          $quality = (intval($config['auto_thumbnail_quality']) && intval($config['auto_thumbnail_quality']) <= 100) ? intval($config['auto_thumbnail_quality']) : 100;

          if (create_thumbnail($src, $dest, $quality, $dimension, $resize_type)) {
            $new_thumb_name = $new_name;
          }
        }
      }
    }

    if (!$uploaderror) {
      $additional_field_sql = "";
      $additional_value_sql = "";
      if (!empty($additional_image_fields)) {
        $table = ($direct_upload) ? IMAGES_TABLE : IMAGES_TEMP_TABLE;
        $table_fields = $site_db->get_table_fields($table);
        foreach ($additional_image_fields as $key => $val) {
          if (isset($HTTP_POST_VARS[$key]) && isset($table_fields[$key])) {
            $additional_field_sql .= ", $key";
            $additional_value_sql .= ", '".un_htmlspecialchars(trim($HTTP_POST_VARS[$key]))."'";
          }
        }
      }

to

Code: [Select]
    // Uplad thumb file
    $new_thumb_name = "";
    if (!empty($HTTP_POST_FILES['thumb_file']['tmp_name']) && $HTTP_POST_FILES['thumb_file']['tmp_name'] != "none" && !$uploaderror) {
      $new_thumb_name = $site_upload->upload_file("thumb_file", "thumb", $upload_cat, basename($new_name));
      if (!$new_thumb_name) {
        $msg .= (($msg != "") ? "<br />" : "")."<b>".$lang['thumb_upload_error'].": ".$new_thumb_name."</b><br />".$site_upload->get_upload_errors();
        @unlink(MEDIA_TEMP_PATH."/".$new_name);
        $uploaderror = 1;
      }
    }
    elseif (check_remote_thumb($remote_thumb_file)) {
      $new_thumb_name = $remote_thumb_file;
    }
    elseif ($config['auto_thumbnail'] == 1 && !empty($HTTP_POST_FILES['media_file'.$fileext]['tmp_name']) && $HTTP_POST_FILES['media_file'.$fileext]['tmp_name'] != "none" && !$uploaderror) {
      if ($direct_upload) {
        $src = MEDIA_PATH."/".$cat_id."/".$new_name;
        $dest = THUMB_PATH."/".$cat_id."/".$new_name;
      }
      else {
        $src = MEDIA_TEMP_PATH."/".$new_name;
        $dest = THUMB_TEMP_PATH."/".$new_name;
      }
      $do_create = 0;
      if ($image_info = @getimagesize($src)) {
        if ($image_info[2] == 1 || $image_info[2] == 2 || $image_info[2] == 3) {
          $do_create = 1;
        }
      }
      require_once(ROOT_PATH.'includes/image_utils.php');
      $convert_options = init_convert_options();
      if ($do_create) {
        if (!$convert_options['convert_error']) {
          $dimension = (intval($config['auto_thumbnail_dimension'])) ? intval($config['auto_thumbnail_dimension']) : 100;
          $resize_type = (intval($config['auto_thumbnail_resize_type'])) ? intval($config['auto_thumbnail_resize_type']) : 1;
          $quality = (intval($config['auto_thumbnail_quality']) && intval($config['auto_thumbnail_quality']) <= 100) ? intval($config['auto_thumbnail_quality']) : 100;

          if (create_thumbnail($src, $dest, $quality, $dimension, $resize_type)) {
            $new_thumb_name = $new_name;
          }
          }
        }
      else {
if (Generate_VideoThumb($src, $dest)) {
return true;
}
else {
return false;
}
      }
  }

    if (!$uploaderror) {
      $additional_field_sql = "";
      $additional_value_sql = "";
      if (!empty($additional_image_fields)) {
        $table = ($direct_upload) ? IMAGES_TABLE : IMAGES_TEMP_TABLE;
        $table_fields = $site_db->get_table_fields($table);
        foreach ($additional_image_fields as $key => $val) {
          if (isset($HTTP_POST_VARS[$key]) && isset($table_fields[$key])) {
            $additional_field_sql .= ", $key";
            $additional_value_sql .= ", '".un_htmlspecialchars(trim($HTTP_POST_VARS[$key]))."'";
          }
        }
      }

And It WORKS!! however as you can see from my server logs (and checking on the disk verifies this):
Code: [Select]
frame= 1 q=1.6 Lsize= 2kB time=0.0 bitrate= 426.6kbits/s
Stream #0.0 -> #0.0
Stream mapping:
Stream #0.0: Video: mjpeg, 352x288, 25.00 fps, q=2-31, 200 kb/s
Output #0, singlejpeg, to './data/thumbnails/4/gymnastics_3.mpg':
Stream #0.1: Audio: mp2, 44100 Hz, stereo, 128 kb/s
Stream #0.0: Video: mpeg1video, 352x288, 25.00 fps
Duration: 00:00:23.4, bitrate: 674 kb/s
Input #0, mpeg, from './data/media/4/gymnastics_3.mpg':

The problem as you can see is that the "$dest" variable i am passing the command has an extension of the file i.e. in this case $dest = "/data/thumbnails/4/gymnastics_3.mpg" and hence ffmpeg created a thumbnail with an mpg extension.

I think the best option would be in my code below:
Code: [Select]
function Generate_VideoThumb($src, $dest) {
  global $convert_options;

  $command = "C:\\WINDOWS\\SYSTEM32\\ffmpeg.exe -i ".$src." -f singlejpeg -t 0.001 ".$dest;
  system($command);
  return (file_exists($dest)) ? 1 : 0;
}
to insert a line of code that replaces the last 3 chars of $dest with "jpg"

Somebody able to help me with this?

Offline V@no

  • If you don't tell me what to do, I won't tell you where you should go :)
  • Global Moderator
  • 4images Guru
  • *****
  • Posts: 17.849
  • mmm PHP...
    • View Profile
    • 4images MODs Demo
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #9 on: March 28, 2006, 03:59:34 PM »
ok, first of all, there is no return in member.php
second, try replace
Code: [Select]
if (Generate_VideoThumb($src, $dest)) {
return true;
}
else {
return false;
}
with:
Code: [Select]
if (in_array(get_file_extension($new_name), array("mpg", "mpeg", "avi")) && Generate_VideoThumb($src, $dest.".jpg")) {
  $new_thumb_name = $new_name.".jpg";
}
Your first three "must do" before you ask a question:
Please do not PM me asking for help unless you've been specifically asked to do so. Such PMs will be deleted without answer. (forum rule #6)
Extension for Firefox/Thunderbird: Master Password+    Back/Forward History Tweaks (restartless)    Cookies Manager+    Fit Images (restartless for Thunderbird)

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #10 on: March 28, 2006, 04:51:14 PM »
Hi V@no,

ok, first of all, there is no return in member.php

What do you mean?

Offline V@no

  • If you don't tell me what to do, I won't tell you where you should go :)
  • Global Moderator
  • 4images Guru
  • *****
  • Posts: 17.849
  • mmm PHP...
    • View Profile
    • 4images MODs Demo
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #11 on: March 29, 2006, 02:05:23 AM »
I ment, you have return true; / return false; in member.php. where were you trying to return? its not a function ;) and theoreticaly it should be equal to exit or die()...(I might be wrong about the last ;))
Your first three "must do" before you ask a question:
Please do not PM me asking for help unless you've been specifically asked to do so. Such PMs will be deleted without answer. (forum rule #6)
Extension for Firefox/Thunderbird: Master Password+    Back/Forward History Tweaks (restartless)    Cookies Manager+    Fit Images (restartless for Thunderbird)

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #12 on: March 29, 2006, 07:56:54 PM »
Hey V@no,

Just an update - thanks to your code you gave me (without the return  :wink:) ... things have been moving smoothly...

i got it all to work quite nicely, however ffmpeg seems to be really short on codecs. what makes it more difficult is that it does not use the built in codec staore that windows media player would use...

it has to be built with all codecs availalbe etc etc etc... what a mission...

i have changed to use mplayer and that seems to work quite nicely... so far it has converted every video i have thrown at it...

it's a bit of a hack, but here is the code:
Code: [Select]
function Generate_VideoThumb($src, $dest) {
  global $convert_options;
  $command = "C:\\mplayer\\mplayer.exe ".$src." -ss 00:00:05 -nosound -vo jpeg:smooth=75 -vop scale=120:80 -frames 1 > imagegenoutput.txt";
  system($command);
  unlink("00000001.jpg");
  unlink("imagegenoutput.txt");
  rename("00000002.jpg",$dest);
  return (file_exists($dest)) ? 1 : 0;
}

the reason i output to imagegenoutput.txt is coz the bloody program echo's the result regardless of how i try and beat it to submission...

i also can't get it to only generate 1 thumbnail - hence the unlink on 00000001.jpg

also you can't specify the file name (it creates it for you) - hence why i do this rename buggerup...


as i said, it's a bit of a hack, but at least my video's are coming in nicely  :D  :D  :D

my upload and multiupload is working fine, I am currently tackling the batch import mod to cater for video (i might be out my depth here  :? )

Anyway, just my .02 worth...

Cheers
WeZ

Offline WeZ

  • Jr. Member
  • **
  • Posts: 72
    • View Profile
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #13 on: April 13, 2006, 07:10:35 PM »
Hi All,

Just a quick one from a newbie...

with my command below, how to i place a " around the $src ?

Code: [Select]
$command = "C:\\mplayer\\mplayer.exe ".$src." -ss 00:00:05 -nosound -vo jpeg:smooth=75 -vop scale=120:80 -frames 1 > imagegenoutput.txt";

The code above works for any file without any spaces, but how to i put a " in the command string without it terminating the string?

hope you get what im on about?

Cheers

Offline V@no

  • If you don't tell me what to do, I won't tell you where you should go :)
  • Global Moderator
  • 4images Guru
  • *****
  • Posts: 17.849
  • mmm PHP...
    • View Profile
    • 4images MODs Demo
Re: Using ffmpeg to generate uploaded video thumbnails
« Reply #14 on: April 14, 2006, 01:01:25 AM »
just escape them with a backslash:[qcode]$command = "C:\\mplayer\\mplayer.exe \"".$src."\" -ss 00:00:05 -nosound -vo jpeg:smooth=75 -vop scale=120:80 -frames 1 > imagegenoutput.txt";[/qcode]
Your first three "must do" before you ask a question:
Please do not PM me asking for help unless you've been specifically asked to do so. Such PMs will be deleted without answer. (forum rule #6)
Extension for Firefox/Thunderbird: Master Password+    Back/Forward History Tweaks (restartless)    Cookies Manager+    Fit Images (restartless for Thunderbird)