javascript - 我可以从 JavaScript 中的隐藏 Canvas 捕获流吗?

标签 javascript canvas webrtc webgl mediastream

我目前正在开发一个 API,它将 videoTrack 作为输入并返回处理后的 videoTrack。我已成功在 Canvas 上绘制处理后的视频,并希望使用 canvas.captureStream() 从中捕获 videoStream。

事实证明,只有当我将 Canvas 加载到 DOM document.body.appendChild(myTempCanvas) 并保持显示时,我才能捕获非空白流,如果我隐藏 Canvas myTempCanvas.style.display="none"

那么有什么方法可以捕获流并保持 Canvas 隐藏吗?

示例:如果取消注释 canvas.style.display = "none"; 行,则 output_video 也会变为空白。

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Demo</title>
</head>
<body>
<div class="container">
  <video autoplay class="input_video" ></video>
  <canvas class="output_canvas"></canvas>
  <video autoplay class="output_video" ></video>
</div>
<script>
    const video = document.getElementsByClassName("input_video")[0];
    const canvas = document.getElementsByClassName("output_canvas")[0];
    const output_video = document.getElementsByClassName("output_video")[0];
    let imageCapture = null;
    let tmpStream = null;

    navigator.mediaDevices.getUserMedia({
      video: true
    })
    .then((stream) => {
      imageCapture = new ImageCapture(stream.getVideoTracks()[0]);
      window.requestAnimationFrame(frameloop);
      tmpStream = canvas.captureStream(20);
      // canvas.style.display = "none";
      output_video.srcObject = tmpStream;
    })

    function frameloop() {
      imageCapture.grabFrame()
      .then(imageBitmap => {
        drawCanvas(canvas, imageBitmap);
        window.requestAnimationFrame(frameloop);
      })
    }

    /* Utils */
    function drawCanvas(canvas, img) {
      canvas.width = getComputedStyle(canvas).width.split('px')[0];
      canvas.height = getComputedStyle(canvas).height.split('px')[0];
      let ratio  = Math.min(canvas.width / img.width, canvas.height / img.height);
      let x = (canvas.width - img.width * ratio) / 2;
      let y = (canvas.height - img.height * ratio) / 2;
      canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height);
      canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height,
              x, y, img.width * ratio, img.height * ratio);
    }

</script>
</body>
</html>


</script>
</body>
</html>

最佳答案

在您的 drawCanvas 中函数将 Canvas 宽度和高度设置为其计算出的 CSS 宽度和高度。
当你通过display:none隐藏 Canvas 时,或者当未将其附加到文档中时,这些值将为 "0px" ,因为 Canvas 不在 CSSOM 中。

宽度或高度为零的 Canvas 无法产生任何输出。


设置 Canvas 宽度或高度是一个非常慢的操作,在 Chrome 中,每次这样做都会分配一个全新的图像位图,并添加到所有 Canvas 上下文的默认值的重置中。
因此,永远不要在所有帧中设置 Canvas 宽度或高度,仅当它确实发生变化时,并且不要将其设置为 <canvas> 的计算大小。元素,将其设置为输入图像的大小,然后相应地设置 CSS 大小。

关于javascript - 我可以从 JavaScript 中的隐藏 Canvas 捕获流吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69311507/

相关文章:

javascript - 变异观察者: How To Get Current Data From Mutation Record?

javascript - 修复等距柏林噪声中的高度问题

encryption - WebRTC SRTP解密

ssl - WebRTC websocket SSL 证书用于工作但不再工作? ERR_INSECURE_RESPONSE

javascript - IE8 : changing parent. 位置上的跨域 Iframes 问题会强制弹出新窗口。如果在点击事件上,它会按预期工作

javascript - 使用JQuery向下滑动到内部链接目的地?

javascript - 如何挂载MVC Nodejs + Express

javascript - 如何按路径而不是区域裁剪 Canvas 图像

javascript - 如何更改 HTML Canvas 中每个数组元素的不透明度

IOS 12 WebRTC - 如何将 RTCMediaStream 传递到 wkwebview?