Create an image index file for a video

In this article we show you how to create an image index for a video file and how to use it on a website.
 

We are going to show you how you can create an image index file for a video. This images are used in video player seekbars when you hover the cursor over different parts of the seekbar on video websites. The target is that when you hover the cursor over a part of the seekbar, you could see a popup with a little thumbnail of that part of the video.

We will be using ffmpeg to extract some images from the video and then use them as thumbnails of the different parts of the video.

Then we will create an image using a php script and the gd library. This will be a big image containing all the thumbnails inside so a visitor browser has only to download one bigger image and does not have to deal with hundreds of thumbnails (if a video is too long and we have one thumbnail every 2 seconds, you can have thousands of thumbnails).

At last, with a little Javascript JQuery coding and a bit of CSS code we will have our seekbar with thumbnails. Well, you can use in a seekbar or in another thing, whatever you want. It's up to you.

Here is the original video that we are going to work with.

Let's start.

Extracting the thumbnails

First, we have to extract the images that will be our thumbnails. We are goint to use ffmpeg with the following command:

ffmpeg -i example.mp4 -vf scale=80:45 -r 1/2 thumb%04d.jpg

With this command we will all extract one image every 2 seconds from the video example.mp4. The output files are called thumb0001.jpg, thumb0002.jpg, thumb0003.jpg and so on... Read more about how to extract frames from a video using ffmpeg.

In the previous command we are also resizing all the images to have a 80x45 pixels resolution. We usually will be reducing the thumbnails images from the video as we will be using them in a popup that is smaller than the video. Read more about how to resize videos using ffmpeg.

As our video has a duration of 50 seconds, we have extracted 25 thumbnail images.

Creating the index image

Now, we know that we have 25 thumbnail images, each of them has a resolution of 80x45 pixels, we are going to put them together in one bigger image. We are going to use a very simple php script using the gd library to create the image and saving it as a jpg file. Here is the script:

<?php
// We create an image resource for the big index image
$img = imagecreate(80,1125);

// We loop through all the thumbnails extracted before
for ($i=1;$i<=25;$i++) {
  
  // Prepare the filename
  $filename = 'thumb' . sprintf('%04d', $i) . '.jpg';
  
  // Open the thumbnail jpg file
  $thumb = imagecreatefromjpeg($filename);
  
  // Copy the image from the thumbnail to the next position of the index image
  imagecopy($img, $thumb, 0, ($i-1)*45, 0, 0, 80, 45);
}

// Save the index image as indeximage.jpg
imagejpeg($img,'indeximage.jpg');
?>

This script will open all the thumbnails and copy them into one exact position of the big image index file one after each other. In this case this script is only valid for this case (we'll see later how to create an index image for any video)

After running this script, we get the file indeximage.jpg that has all the thumbnails together. Here is the image:

As you can see it has the aspect of an old movie film. Each of the images that you can see in this image are one frame from each moment of the video. We have a frame every two seconds.

Using the index image in a website

At last we have to use the image in a website. For this example we are putting a div element here that will work as a seekbar for the video. Just hover the cursor over it and see what happens.

 

 

If you move the cursor from left to right over the grey div you will see different thumbnails of the video that represent that moment of the video. This is achieved with a little jQuery coding in which we change the css style of the image shown on the popup. We select the right part of the image depending on the position over the seekbar. We need only the following HTML code:

<style type="text/css">
div.seekbar{background-color:#f3f3f3;height:10px;width:90%;margin:0 auto;display:block;position:relative;}
div.sb-pup {background-color:#f3f3f3;padding:10px 10px;border:1px solid black;position:absolute;display:none;}
div.sb-img {background-image:url('/sites/default/files/field/image/indeximage.jpg');width:80px;height:45px;}
</style>

<!-- HTML div structure for seekbar and popup -->
<div class="seekbar"><div class="sb-pup"><div class="sb-img"></div></div></div>

<script>
// Whenever the mouse enters the div we show the popup
jQuery('div.seekbar').mouseover(function(){jQuery('div.sb-pup').show();});

// When the mouse cursor exits the seekbar we hide the popup
jQuery('div.seekbar').mouseout(function(){jQuery('div.sb-pup').hide();});

// When we move the cursor inside the seekbar we prepare new popup position and new thumbnail
jQuery('div.seekbar').mousemove(function(event){
  // We calculate new absolute position for popup
  var x=event.pageX;
  var pX=jQuery('div.seekbar').offset().left;
  x = x-pX;
  var pos = Math.round(x) + "px";
  
  // We update popup position with the new calculated position
  jQuery('div.sb-pup').get(0).style.left=pos;

  // In this case the duration is fixed (50 seconds video)
  var duration = 50;
  var ewidth = jQuery('div.seekbar').width();
  var newTime = (x/(ewidth))*duration;
  
  // We calculate where in the image is the thumbnail for the time we are pointing at in the seekbar
  var iposY = Math.floor(newTime/2) * 45;

  // We set new background-position css style so the image appears updated if needed
  jQuery('div.sb-img').get(0).style.backgroundPosition='-0px -'+iposY+'px';
});
</script>

In this case, as it was when we created the image, we are working with fixed parameters (50 seconds, and one image each 45 pixels) in order to not get too complex. The ideal solution should work with different variables as thumbnails size, or video duration.

    Did you find this article helpful?

Tags: