在画布上绘制视频 [英] Drawing video on canvas

查看:177
本文介绍了在画布上绘制视频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to draw a video from video element on canvas. I wrote the following JS code:

$(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);
}

这是我的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>

JSFiddle 这里

JSFiddle here

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

I can see the video playing, but it's not being redrawn onto the canvas. Where's my mistake?

推荐答案

如果不是,那么将jQuery与视频和画布(和音频)等元素一起使用会遇到麻烦绝对确定你在做什么。

Using jQuery with elements such as video and canvas (and audio) is asking for trouble if you are not absolute sure what you're doing.

你是在调用 getContext() videoWidth videoHeight 等不能正常运行,并且还将vanilla JavaScript与jQuery混合在一起,例如 bind() addEventListener()

You are for example calling getContext(), videoWidth, videoHeight etc. on the jQuery objects which won't work well, and also mixing vanilla JavaScript with jQuery such as bind() and addEventListener().

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

My first recommendation is to use plain vanilla JavaScript when working with these elements as not only will life become less troublesome, but you'll also gain some performance which can be critical with these elements.

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

Second, always use requestAnimationFrame with video and canvas. There is no chance synching these properly with setTimeout/setInterval. rAF will make sure a frame is updated to monitor at the exact right time. With video you can toggle the speed as video rarely is above 30 FPS (in Europe it's 25 FPS), and it will give you some extra performance space.

这是一个 工作代码 (仍然需要清理......):

Here is a working code (still need clean-up though...):

HTML - 将 preload =auto添加到视频代码中,以便在播放前捕获元数据:

HTML - add preload = "auto" to the video tag to catch meta data before playing:

<video id="video" preload=auto autoplay controls>

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
}

这篇关于在画布上绘制视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆