【问题标题】:Playing video on HTML Canvas在 HTML Canvas 上播放视频
【发布时间】:2021-12-17 12:07:54
【问题描述】:

我正在尝试将视频播放到 HTML Canvas。没有问题,除非我尝试隐藏视频源并仅显示画布。在这种情况下,我只会得到一个“白屏”。如果视频元素没有被隐藏,一切都会按预期工作。我不想显示视频元素和画布元素,我只想显示具有“流式传输”视频源的画布元素。有什么建议?附上代码示例...

let sourcevideo = document.getElementById("sourcevideo");
let outputcanvas = document.getElementById("outputcanvas");
let canvasctx = outputcanvas.getContext("2d");

function initCanvas() {
  outputcanvas.width = sourcevideo.videoWidth;
  outputcanvas.height = sourcevideo.videoHeight;
  console.log(outputcanvas.width, outputcanvas.height);
  drawVideo();
}

function drawVideo() {
  canvasctx.drawImage(
    sourcevideo,
    0,
    0,
    outputcanvas.width,
    outputcanvas.height
  );
  requestAnimationFrame(drawVideo);
}

sourcevideo.addEventListener("loadeddata", initCanvas);
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Document</title>
</head>

<body>
  <div id="videocontainer">
    <video id="sourcevideo" controls src="https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c4/Physicsworks.ogv/Physicsworks.ogv.240p.vp9.webm"></video>
  </div>
  <canvas id="outputcanvas"></canvas>
</body>

</html>

【问题讨论】:

    标签: javascript html5-canvas html5-video


    【解决方案1】:

    首先,使用 $('#sourcevideo').css('visibility', 'hidden'); 隐藏视频容器的可见性,然后您将看到静止图像,以防止使用 autoplay="autoplay",这样做您的视频元素将隐藏,您的画布也将正确运行视频。

    let sourcevideo = document.getElementById("sourcevideo");
    let outputcanvas = document.getElementById("outputcanvas");
    let canvasctx = outputcanvas.getContext("2d");
    
    function initCanvas() {
      outputcanvas.width = sourcevideo.videoWidth;
      outputcanvas.height = sourcevideo.videoHeight;
      console.log(outputcanvas.width, outputcanvas.height);
      drawVideo();
    }
    
    function drawVideo() {
      canvasctx.drawImage(
        sourcevideo,
        0,
        0,
        outputcanvas.width,
        outputcanvas.height
      );
      requestAnimationFrame(drawVideo);
    }
    sourcevideo.addEventListener("loadeddata", initCanvas);
    sourcevideo.style.visibility = 'hidden';
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8" />
      <meta http-equiv="X-UA-Compatible" content="IE=edge" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Document</title>
    </head>
    
    <body>
      <div>
        <canvas id="outputcanvas"></canvas>
      </div>
      <div id="videocontainer">
        <video id="sourcevideo" autoplay="autoplay" controls src="https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c4/Physicsworks.ogv/Physicsworks.ogv.240p.vp9.webm"></video>
      </div>
    
    </body>
    
    </html>

    【讨论】:

    • 这真的很接近我正在寻找的东西,但是有没有办法摆脱现在隐藏的视频元素留下的“空白空间”?
    • @ArtemisJ 现在检查更新的答案,我刚刚移动了 div
    【解决方案2】:

    您可以设置一个包含display: none 样式的CSS 类以应用于video 元素(如下面的代码所示,.hidden {display:none;})。由于视频元素的类是在 HTML 中设置的,因此它应该隐藏视频元素,但在页面加载时仍会播放带有 autoplay 的视频。

    下面的代码显示了如何根据需要在不同的类中应用display: nonevisibility: hidden(在此示例中使用按钮)。

    const sourcevideo = document.getElementById("sourcevideo");
    const outputcanvas = document.getElementById("outputcanvas");
    const canvasctx = outputcanvas.getContext("2d");
    
    function initCanvas() {
      outputcanvas.width = sourcevideo.videoWidth;
      outputcanvas.height = sourcevideo.videoHeight;
      drawVideo();
    }
    
    function drawVideo() {
      canvasctx.drawImage(
        sourcevideo,
        0,
        0,
        outputcanvas.width,
        outputcanvas.height
      );
      requestAnimationFrame(drawVideo);
    }
    
    sourcevideo.addEventListener("loadeddata", initCanvas);
    .hidden {
      display: none;
    }
    <div id="videocontainer">
      <canvas id="outputcanvas"></canvas>
      <video id="sourcevideo" class="hidden" controls autoplay src="https://upload.wikimedia.org/wikipedia/commons/transcoded/c/c4/Physicsworks.ogv/Physicsworks.ogv.240p.vp9.webm"></video>
    </div>

    【讨论】:

    • 感谢您的详细回复。上面的内容在附加到按钮时有效,但在不被按钮调用而只是作为事件(如加载数据)时,它并不完全有效(至少正如我希望的那样)。因此,为了扩展和阐明所需状态,最终用户“可见”并占用网页空间的唯一内容是画布元素,该元素已在其上“绘制”了源视频。我能来的最接近的是其他海报的建议,并在 sourcevideo 上使用 style.visibility 来隐藏它,但在这种情况下它仍然留下一个空白区域
    • 是的,visibility: hiddendisplay:none 之间的区别在于visibility: hidden 保留了元素所在的块空间,包括宽度和高度。 display: none 样式没有。我刚刚更新了我的答案以在开始时包含此内容,而不是按需添加按钮。
    猜你喜欢
    • 2020-05-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多