canvas - 是否可以将流作为源添加到 html Canvas 元素作为 html 视频元素?

标签 canvas stream media-source mediastream

根据 MDN:

The HTMLMediaElement interface adds to HTMLElement the properties and methods needed to support basic media-related capabilities that are common to audio and video.



HTMLMediaElement.captureStream() .它可以与 <video> 一起使用和 <canvas>元素来捕获它们的流。

相反,可以添加 视频流srcObject<video>元素,然后它显示它。 <canvas> 有可能吗?元素也是?

有没有可能添加流 作为 来源 到 html <canvas>元素?

最佳答案

没有任何 Canvas API 能够使用 MediaStream。
Canvas API 仅适用于原始像素,不包含任何类型的解码器。您必须使用能够进行此解码的 javascript 对象(例如 ImageBitmap)或 HTMLElements。
因此,对于 MediaStream,目前唯一能够解码其视频内容的对象将是 HTMLVideoElement,您将能够 draw on your canvas easily .

2021 年更新
WebCodecs API最近取得了很大的进展,并且变得越来越成熟,现在值得一提的是它作为一种解决方案。
此 API 提供了一个名为 VideoFrame 的新接口(interface)这将soon成为 CanvasImageSources 的一部分类型,含义,我们可以直接用drawImage , texImage2D在任何地方都可以使用这样的 CanvasImageSource。
MediaCapture Transform W3C小组开发了MediaStreamTrackProcessor确实从视频 MediaStreamTrack 返回此类 VideoFrames。
所以我们现在有一种更直接的方法来将 MediaStream 渲染到 Canvas 上,目前它只适用于带有 #enable-experimental-web-platform-features 的 Chrome 浏览器。旗上...

if( window.MediaStreamTrackProcessor ) {
  const canvas = document.querySelector("canvas");
  const ctx = canvas.getContext("2d");
  const track = getCanvasTrack(); // MediaStream.getVideoTracks()[0]
  const processor = new MediaStreamTrackProcessor( track );
  const reader = processor.readable.getReader();
  readChunk();
  function readChunk() {
    reader.read().then( ({ done, value }) => {
      // the MediaStream video can have dynamic size
      if( canvas.width !== value.displayWidth || canvas.height !== value.displayHeight ) {
        canvas.width = value.displayWidth;
        canvas.height = value.displayHeight;
      }
      ctx.clearRect( 0, 0, canvas.width, canvas.height );
      // value is a VideoFrame
      ctx.drawImage( value, 0, 0 );
      value.close(); // close the VideoFrame when we're done with it
      if( !done ) {
        readChunk();
      }
    });
  }
}
else {
  console.error("Your browser doesn't support this API yet");
}

// We can't use getUserMedia in StackSnippets
// So here we use a simple canvas as source
// for our MediaStream.
function getCanvasTrack() {
  // just some noise...
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  const img = new ImageData(300, 150);
  const data = new Uint32Array(img.data.buffer);
  const track = canvas.captureStream().getVideoTracks()[0];

  anim();
  
  return track;
  
  function anim() {
    for( let i=0; i<data.length;i++ ) {
      data[i] = Math.random() * 0xFFFFFF + 0xFF000000;
    }
    ctx.putImageData(img, 0, 0);
    if( track.readyState === "live" ) {
      requestAnimationFrame(anim);
    }
  }
  
}
<canvas></canvas>

作为 glitch project ( source ) 使用相机作为源。

关于canvas - 是否可以将流作为源添加到 html Canvas 元素作为 html 视频元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56093061/

相关文章:

api - YouTube 数据 API V3 未从 channel ID 返回直播

javascript - 无法通过 Media Source API 附加片段,得到“InvalidStateError : An attempt was made to use an object that is not, or is no longer, usable

javascript - 在 JavaScript Canvas 上混合两个图像

javascript - 单击 Canvas 中的对象时出现奇怪的错误?

c# - 如何将流写入独立存储中的 xml 文件

node.js - JSON 中位置 0 处出现意外标记 u - 将文件中的 JSON 字符串数据解析到 Web 服务器时

php - 在线获取签名的最佳方式是什么?

jquery - Fabric.js 元素中的 flex 文本

javascript - 从 mediasource sourcebuffer 中动态附加和删除 mpeg-dash 片段

c++ - ffmpeg和代码生成的碎片化mp4文件的区别