0

I am creating a thumbnail from videos when the web page is loaded, and i am using jquery to do it..

So I have 3 videos in the html -

    <video  width="320" height="240" controls poster="">
  <source src="small.mp4" type="video/mp4">

Your browser does not support the video tag.
</video>
        <video  width="320" height="240" controls poster="">
  <source src="small.mp4" type="video/mp4">

Your browser does not support the video tag.
</video>
        <video  width="320" height="240" controls poster="">
  <source src="small.mp4" type="video/mp4">

Your browser does not support the video tag.
</video>

3 Buttons and 3 image elements -

<button onclick="clicker(0)">GET0</button>
<button onclick="clicker(1)">GET1</button>
<button onclick="clicker(2)">GET2</button>

    <img id="img0">
    <img id="img1">
    <img id="img2">

Using the clicker function, I can create and add the thumbnail source from each video to each img elements . It works fine..

function clicker(i) {
  var video = $("video")[i];
  console.info(video);
  var canvas = document.createElement('canvas');
  canvas.width = 320;
  canvas.height = 240;
  var context = canvas.getContext('2d');
  context.drawImage(video, 0, 0, canvas.width, canvas.height);
  var dataURI = canvas.toDataURL('image/jpeg');
  $('#img'+i).attr("src", dataURI);
}

But when put into a forloop

for (var i = 0;  i < $("video").length; i++) {   

  var video = $("video")[i];
  console.info(video);
  var canvas = document.createElement('canvas');
  canvas.width = 640;
  canvas.height = 480;
  var context = canvas.getContext('2d');
  context.drawImage(video, 0, 0, canvas.width, canvas.height);
  var dataURI = canvas.toDataURL('image/jpeg');
  $('#img'+i).attr("src", dataURI);

}

From what I can gather, the following canvas.toDataURL('image/jpeg'); is not running in the forloop for some reason

The image sources are just black images, and it doesn't work at all.

I can't see any difference whatsoever?

SK2017
  • 753
  • 9
  • 38
  • 2
    Have you put the for loop inside a $(document).ready(function() { ... }); or $(function() { ... }) or otherwise ensure that the for loop is successfully run? – Troels M. B. Jensen May 23 '17 at 09:16
  • Yes, tried putting it in them, and it is definately running – SK2017 May 23 '17 at 09:17
  • have you tried to put the for loop inside a `$(window).on('load', function() { //for loop here });`? instead that inside a document ready – quirimmo May 23 '17 at 09:24
  • Please provide an example in JSBIN live demo. – Giacomo Paita May 23 '17 at 09:28
  • Not related to your problem, but why are you using a `for` loop and reselecting all video elements in every iteration instead of just doing `$("video").each()`? – Lennholm May 23 '17 at 09:35
  • Can you show us when the script is executed? Since a button is waiting for you to click, you might run this loop automatically before the video elements have been loaded fully, which would probably result into this behavior. – Glubus May 23 '17 at 10:00
  • @Glubus How can I show you this? the script is at the end of the file, after the html elements.? – SK2017 May 23 '17 at 10:02
  • @GiacomoPaita - I can't upload the videos to jsbin so It throws a cross origin error when trying to create the jsbin. – SK2017 May 23 '17 at 10:03
  • @SK2017 if the script tags are at he bottom of the body tag, then it shouldn't be a problem. Still you could verify that it's a timing issue by letting the loop be executed by another button that is clicked. – Glubus May 23 '17 at 10:09
  • @SK2017 Also if you'd be able to provide a snippet with full code, on jsfiddle for instance, people might be able to debug. – Glubus May 23 '17 at 10:10
  • https://jsfiddle.net/x1e7b21c/ – SK2017 May 23 '17 at 10:15
  • @SK2017 http://jsbin.com/rehuril/edit?html,output – Giacomo Paita May 23 '17 at 10:44
  • @GiacomoPaita I've update it here http://jsbin.com/yujuluzeme/1/edit?html,js,output – SK2017 May 23 '17 at 10:58
  • you have to wait for your videos have loaded. Assuming they've got an autoplay attribute you can listen to their loadedmetadata event. – Kaiido May 23 '17 at 11:02
  • @SK2017 Seems to be a security issue: https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image – Giacomo Paita May 23 '17 at 16:21

2 Answers2

1

So it seems that load and ready aren't sufficient for making sure the videos have loaded before the jquery trys to rip the image from them..

Get the last video loaded on the page and add an event listener to it, when its finished, run the function to rip images from all the videos.

$('video')[$('video').length - 1].addEventListener('loadeddata', function() 
        {
            getImages();
        });

  function getImages(){


    $("video").each(function(index, value)
    {
            var video = value;
                console.info(video);
                var canvas = document.createElement('canvas');
                canvas.width = 640;
                canvas.height = 480;
                var context = canvas.getContext('2d');
                context.drawImage(video, 0, 0, canvas.width, canvas.height);
                var dataURI = canvas.toDataURL('image/jpeg');
                $('#img'+index).attr("src", dataURI);
                video.setAttribute('poster', dataURI);
        });
    }
Billal Begueradj
  • 20,717
  • 43
  • 112
  • 130
SK2017
  • 753
  • 9
  • 38
0

Instead keep your function as is, (since it is working fine) and call it inside the loop:

for (var i = 0;  i < $("video").length; i++) {   
       clicker(i);
}
Milan Chheda
  • 8,159
  • 3
  • 20
  • 35