1

I'm creating a PDF output tool using jsPDF but need to add multiple pages, each holding a canvas image of a video frame. I am stuck on the logic as to the best way to achieve this as I can't reconcile how to queue the operations and wait on events to achieve the best result. To start I have a video loaded into a video tag and can get or set its seek point simply with:

video.currentTime

I also have an array of video seconds like the following:

var vidSecs = [1,9,13,25,63];

What I need to do is loop through this array, seek in the video to the seconds defined in the array, create a canvas at these seconds and then add each canvas to a PDF page. I have a create canvas from video frame function as follows:

function capture_frame(video_ctrl, width, height){
    if(width == null){
        width = video_ctrl.videoWidth;
    }
    if(height == null){
        height = video_ctrl.videoHeight;
    }
    canvas = document.createElement('canvas');
    canvas.width  = width;
    canvas.height = height;
    var ctx = canvas.getContext('2d');
    ctx.drawImage(video_ctrl, 0, 0, width, height);
    return canvas;
}

This function works fine in conjunction with the following to add an image to the PDF:

function addPdfImage(pdfObj, videoObj){    
    pdfObj.addPage();
    pdfObj.text("Image at time point X:", 10, 20);
    var vidImage = capture_frame(videoObj, null, null);
    var dataURLWidth = 0;
    var dataURLHeight = 0;
    if(videoObj.videoWidth > pdfObj.internal.pageSize.width){
        dataURLWidth = pdfObj.internal.pageSize.width;
        dataURLHeight = (pdfObj.internal.pageSize.width/videoObj.videoWidth) * videoObj.videoHeight;
    }else{
        dataURLWidth = videoObj.videoWidth;
        dataURLHeight = videoObj.videoHeight;
    }
    pdfObj.addImage(vidImage.toDataURL('image/jpg'), 'JPEG', 10, 50, dataURLWidth, dataURLHeight);
}

My logic confusion is how best to call these bits of code while looping through the vidSecs array as the problem is that setting the video.currentTime needs the loop to wait for the video.onseeked event to fire before code to capture the frame and add it to the PDF can be run.

I've tried the following but only get the last image as the loop has completed before the onseeked event fires and calls the frame capture code.

for(var i = 0; i < vidSecs.length; i++){
    video.currentTime = vidSecs[i];
    video.onseeked = function() {
        addPdfImage(jsPDF_Variable, video);
    };            
}

Any thoughts much appreciated.

Diplonics
  • 435
  • 1
  • 4
  • 12

2 Answers2

0

This is not a real answer but a comment, since I develop alike application and got no solution. I am trying to extract viddeo frames from webcam live video stream and save as canvas/context, updated every 1 - 5 sec. How to loop HTML5 webcam video + snap photo with delay and photo refresh?

I have created 2 canvases to be populated by setTimeout (5000) event and on test run I don't get 5 sec delay between canvas/contextes, sometimes, 2 5 sec. delayed contextes get populated with image at the same time.

So I am trying to implement Draw HTML5 Video onto Canvas - Google Chrome Crash, Aw Snap

var toggle = true;

function loop() {

toggle = !toggle;
if (toggle) {
    if (!v.paused) requestAnimationFrame(loop);
    return;
}

/// draw video frame every 1/30 frame
ctx.drawImage(v, 0, 0);

/// loop if video is playing
if (!v.paused) requestAnimationFrame(loop);
}

to replace setInterval/setTimeout to get video and video frames properly synced

" Use requestAnimationFrame (rAF) instead. The 20ms makes no sense. Most video runs at 30 FPS in the US (NTSC system) and at 25 FPS in Europe (PAL system). That would be 33.3ms and 40ms respectively. "

I am afraid HTML5 provided no quality support for synced real time live video processing via canvas/ context, since HTML5 offers no proper timing since was intended to be event/s controlled and not run as real time run app code ( C, C++ ...).

My 100+ queries via search engine resulted in not a single HTML5 app I intend to develop. What worked for me was Snap Photo from webcam video input, Click button event controlled.

If I am wrong, please correct me.

a a
  • 1
  • 5
  • follow-up Muaz Khan looks to be one of the most advanced HTML5 video processing developer. Ask him directly http://www.muazkhan.com/ https://twitter.com/muazkh https://twitter.com/WebRTCWeb https://www.webrtc-experiment.com/RTCMultiConnection/RecordRTC-and-RTCMultiConnection.html https://stackoverflow.com/questions/41487635/thumbnails-from-a-video-with-javascript-html5?rq=1 – a a Jun 20 '17 at 01:04
0

Two approaches:

  1. create a new video element for every seek event, code provided by Chris West
  2. reuse the video element via async/await, code provided by Adrian Wong
TracyYXChen
  • 173
  • 1
  • 9