【问题标题】:Adding video to Javascript Canvas将视频添加到 Javascript 画布
【发布时间】:2013-12-04 17:09:50
【问题描述】:

是否可以添加一个循环播放到 HTML5 画布的背景视频?这就是我目前所做的工作,只是想添加一个可以播放到背景的简单视频。我可以使用 video 标签将视频添加到 HTML,但希望它在画布本身上播放。

<canvas id="ex1" width="525" height="200" style="border: 5px solid black;" ></canvas>

<p id="text"> Increase/Decrease Speed</p>
<input type="button" value="+" id="btnAdd">
<input type="button" value="-" id="btnSub">

<script>
var x = 0;
var y = 15;
var speed = 10;
var isRight = true;

document.getElementById('text').innerText = speed;

document.getElementById('btnAdd').addEventListener('click', function (event) {

    if (isRight) speed++;
    else speed--;
    document.getElementById('text').innerText = speed;

    });

document.getElementById('btnSub').addEventListener('click', function (event) {
    if (isRight) speed--;
    else speed++;
    document.getElementById('text').innerText = speed;

    });

function animate() {

    reqAnimFrame = window.mozRequestAnimationFrame ||   window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame;

    reqAnimFrame(animate);

    x += speed;

    if (x <= 0 || x >= 475) {
        speed = -speed;

        isRight = !isRight;
    }
    document.getElementById('text').innerText = speed;

    draw();
  }

 function draw() {
    var canvas = document.getElementById("ex1");
    var context = canvas.getContext("2d");

    context.clearRect(0, 0, 525, 200);
    context.fillStyle = "#ff00ff";
    context.fillRect(x, y, 40, 40);
  }

animate();
  </script>

【问题讨论】:

  • 基本过程是创建一个视频元素并用 CSS 隐藏它,然后使用画布上下文的 drawImage 方法在动画循环中将视频绘制到画布上。
  • 我在发布的代码中没有看到任何与视频相关的内容?

标签: javascript html canvas


【解决方案1】:

可以将当前在视频元素中运行的帧复制到画布。使用 setInterval 我们必须定期对视频元素进行采样并将其复制到画布上。它可以用来做有趣的事情。

来自 Mozilla drawImage

第一个参数可以是任何要绘制到上下文中的元素;该规范允许任何图像元素(即

这是一个锅炉板代码示例 -

var videoElement, canvasContext;

videoElement.addEventListener('play', function(){
    copyCurrentFrameIntoCanvas(this);
    setInterval(copyCurrentFrameIntoCanvas,10,this);
},false);

function copyCurrentFrameIntoCanvas(videoElement) {
    canvasContent.drawImage(videoElement,0,0,<width>,<height>);
}

您需要适当地初始化我认为您已经知道的 videoElement 和 canvasContent。还要适当地替换 占位符。

【讨论】:

    【解决方案2】:

    您可以创建一个离屏视频元素,这样您就不必处理 CSS 或导致额外的重排。创建屏幕外视频元素很简单:

    /// element
    var video = document.createElement('video');
    
    /// set video elemet size
    video.width = 640;
    video.height = 360;
    
    /// setup with auto preload and loop
    video.preload = 'auto';
    video.loop = true;
    

    现在您可以附加一个事件处理程序,以便在准备好播放视频时开始绘制:

    video.addEventListener('canplay', start, false);
    

    现在设置视频的来源。您需要使用video.canPlayType('&lt;mime-type-here&gt;') 方法检查浏览器可以播放哪些类型,但为简单起见,我们直接设置源:

    video.src = 'link/to/video.ogv';
    

    在处理程序中,我们现在可以更新视频。由于requestAnimationFrame 尝试每秒更新 60 次,我们可以将其减少到一半,因为视频很少超过 30 FPS(美国,欧洲 25):

    function start() {
    
        /// get context from canvas (canvas not shown in example)        
        var ctx = canvas.getContext('2d'),
            toggle = true;                  /// this is used to reduce FPS
    
        /// start video
        video.play();
    
        /// start loop
        requestAnimationFrame(loop);
    
        function loop() {
    
            /// reduce frame-rate to half
            toggle = !toggle;    
    
            if (toggle) {
                requestAnimationFrame(loop);
                return;
            }
    
            /// draw video frame
            ctx.draw(video, 0, 0);
    
            requestAnimationFrame(loop);
        }
    }
    

    免责声明:未经测试,但您可以看到主要步骤。代码应该创建视频元素并在它准备好时自动启动它。然后它将循环运行,每 30 FPS(左右)将视频帧绘制到画布上。

    注意:Safari 浏览器不支持 iOS 中带有视频元素的 drawImage(目前正在撰写此答案)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-07
      • 2012-02-27
      • 2021-11-03
      • 1970-01-01
      • 2016-06-17
      • 2021-04-20
      • 1970-01-01
      • 2021-11-16
      相关资源
      最近更新 更多