在画布上绘制视频

Iga*_*gal 0 javascript video jquery html5 canvas

我正在尝试从video画布上的元素中绘制视频.我写了以下JS代码:

$(function () {
    var video = $("#video");
    video.bind("loadedmetadata", function () {
        var vw = this.videoWidth;
        var vh = this.videoHeight;
        var canvas = $('#canvas');
        canvas.width(vw).height(vh);
        var context = canvas.getContext("2d");

        video.addEventListener("play", function () { draw(video, context, vw, vh); }, false);
    });
});
function draw(video, context, vw, vh)
{
    if (video.paused || video.ended)
    {              
        return false;
    }

    context.drawImage(video, 0, 0, vw, vh);
    setTimeout(draw, 20, video, context, vw, vh);
}
Run Code Online (Sandbox Code Playgroud)

这是我的HTML:

<body>
<video id="video" autoplay controls>
    <source src="src1.avi" />
    <source src="src2.mov" />
    <source src="src3.ogg" />
    <source src="src4.avi" />
</video>
<canvas id="canvas">
    Please update your browser.
</canvas>
Run Code Online (Sandbox Code Playgroud)

JSFiddle 在这里

我可以看到视频播放,但它没有重新绘制到画布上.哪里是我的错?

小智 5

如果你不能完全确定你在做什么,那么使用带有视频和画布(和音频)等元素的jQuery会遇到麻烦.

你是例如电话getContext(),videoWidth,videoHeight等上不会很好地工作jQuery的对象,同时也混合香草的JavaScript与jQuery如bind()addEventListener().

我的第一个建议是在使用这些元素时使用普通的JavaScript,因为不仅生活变得不那么麻烦,而且你也会获得一些对这些元素至关重要的性能.

其次,始终使用requestAnimationFrame视频和画布.没有机会与setTimeout/ 正确地同步这些setInterval.rAF将确保更新帧以在正确的时间进行监控.使用视频,您可以切换速度,因为视频很少超过30 FPS(在欧洲它是25 FPS),它将为您提供一些额外的性能空间.

这是一个有效的代码(仍然需要清理......):

HTML - preload = "auto"在播放之前添加到视频标记以捕获元数据:

<video id="video" preload=auto autoplay controls>
Run Code Online (Sandbox Code Playgroud)

JavaScript的

var video = $("#video")[0];               // video element itself is at index 0 
var vw;
var vh;

var canvas = $('#canvas')[0];             // canvas element itself is at index 0
var context = canvas.getContext("2d");    // getContext on canvas element itself

// setup canvas when metadata is available
video.addEventListener("loadedmetadata", function() {
    vw = this.videoWidth || this.width;   // these are on video element itself
    vh = this.videoHeight || this.height;
    canvas.width = vw
    canvas.height = vh;
}, false);

// call it straight, use global (or parent) variables
video.addEventListener("play", draw, false);

function draw() {
    if (video.paused || video.ended) {
        return;
    }

    context.drawImage(video, 0, 0, vw, vh);

    requestAnimationFrame(draw);  // loop anim. using rAF
}
Run Code Online (Sandbox Code Playgroud)