javascripthtmlvideocanvasdrawimage

HTML5 Canvas drawImage from video not showing on first draw


I have a video element with a canvas overlay. Then I have a drawing tool setup to draw over the video and a save button that does a drawImage from both the video and then the canvas to save a comped frame. However, the first time I press Save I only get the result from the canvas drawImage, the video does not show. On subsequent Saves I receive both images properly layered. I thought this might be an issue with loading of the video image, but the video is fully loaded before I hit save and can even advance frames and have it work properly on the 2nd Save.

Here is the code...

<div style="width:960px; height:540px; display:inline-block;">
    <video id="video" src="media/_tmp/AA_017_COMP_v37.mov" width="960" height="540" ></video>
</div>
<canvas id="canvas" width="960" height="540" style="position:absolute; top:40px; left:9px; z-index:100;"></canvas>
<input type="button" value="save" id="btn" size="30" onclick="save()" style="float:left; padding:4px; margin-right:4px;" >
<div id="saved" style="border:1px solid #000; position:absolute; top:626px; left:10px; bottom:40px; width:958px; overflow:auto;">SAVED:</div>


function save() {

    //COMP CANVAS OVER VIDEOFRAME
    var video = document.getElementById("video");
    var currentFrame = Math.floor((<?php echo $mov_frames ?> / video.duration) * video.currentTime);

    var compCanvas = document.createElement('canvas');
    compCanvas.width = video.width;
    compCanvas.height = video.height;
    compContext = compCanvas.getContext('2d');
    compContext.drawImage(video, 0, 0);
    compContext.drawImage(canvas, 0, 0);
    var dataURL = compCanvas.toDataURL();

    $("#saved").append('<div style="width:954px; border-bottom:1px solid #000; padding:2px 2px 0 2px;"><img id="compFrame_'+currentFrame+'" width="180" height="90" src="'+dataURL+'" />Frame: '+currentFrame+'</div>');
}

Solution

  • As this is on OSX with Safari there is some bad news:

    Note: Video as a source for the canvas drawImage() method is not currently supported on iOS.

    Source

    If this is outdated information I don't know but in either case the current implementation has issues. As established (in comments) the problem is not likely related to codecs as this occur with other formats as well. The fiddle eliminates the toDataURL() method as source so what is left is the drawImage() method.

    As this works on other platform with the provided code, and from the look of it, this is neither the source of the problem so you are here looking at a very possible issue (bug) with the Safari browser on the OSX platform.

    The official documentation quoted above also states this is not supported so this is probably a very early implementation that still has some issues.

    There is not much you can do in that regard but to wait and also report it as an issue (I looked for a reported issue but couldn't find any so I recommend you do this).