【问题标题】:Is there a way to send video data from a video tag/MediaStream to an OffscreenCanvas?有没有办法将视频数据从视频标签/MediaStream 发送到 OffscreenCanvas?
【发布时间】:2019-06-25 05:12:21
【问题描述】:

基本上我希望能够有效地执行相同的代码:


const video = document.getElementById('video');
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');

const draw = () => {
  context.drawImage(video, 0, 0);
  requestAnimationFrame(draw);
}

video.onplay = () => {
  requestAnimationFrame(draw);
}

仅使用屏幕外画布。我可以通过消息将图像发送给屏幕外画布所在的工作人员,但不能发送视频,因为它直接绑定到HTMLElement。目前有没有办法以某种方式在屏幕外画布中呈现视频数据或MediaStream

【问题讨论】:

  • 您找到解决方法了吗?我也有同样的问题

标签: javascript canvas web-worker media-source mediastream


【解决方案1】:

您可以通过以下更改修改脚本,将视频帧发送到 Web Worker 中的 OffscreenCanvas:

const worker = new Worker('my-worker.js');
const video = document.getElementById('video');
const stream = video.captureStream();
const [track] = stream.getVideoTracks();
const imageCapture = new ImageCapture(track);
const canvas = document.getElementById('canvas');
const offscreen = canvas.transferControlToOffscreen();

worker.postMessage({ offscreen }, [offscreen]);

const draw = () => {
  imageCapture.grabFrame().then(imageBitmap => {
    worker.postMessage({ imageBitmap }, [imageBitmap]);
  });

  requestAnimationFrame(draw);
};

video.onplay = () => {
  requestAnimationFrame(draw);
};

my-worker.js

let canvas;
let context;

addEventListener('message', event => {
  if (event.data.offscreen) {
    canvas = event.data.offscreen;
    context = canvas.getContext('2d');
  } else if (event.data.imageBitmap && context) {
    context.drawImage(event.data.imageBitmap, 0, 0);
    // do something with frame
  }
});

参考文献

【讨论】:

  • 感谢您的回复,但我想我正在寻找一种方法来通过使用屏幕外画布来卸载 requestAnimationFrame 调用,因为当标签模糊时 requestAnimationFrame 会被浏览器限制。这解决了我最初的问题,但是有没有办法在没有计时器/requestAnimationFrame 调用的情况下将视频放到屏幕外画布上?
  • @JacobGreenway 取决于视频的src。但是requestAnimationFrame() 在生成它们的选项卡失去焦点时也会在 Web Worker 中受到限制,因此您需要变得更聪明,而不仅仅是在 Web Worker 中运行您的原始代码。
  • 不幸的是,仍然只支持 Blink 浏览器,对于 FF,您可以使用 createImageBitmap 方法传入
  • 如果工人不处理动画,这样做有什么好处?
  • @hoodsy grabFrame()postMessage() 使用 Transferable 对象调用在 DOM 线程中不是非常昂贵的计算,因此它有很多空闲时间来处理用户事件和重绘,而drawImage() 和其他画布上下文方法的昂贵工作被推送到工作线程,不会对网页的响应性产生负面影响。
猜你喜欢
  • 2021-12-24
  • 1970-01-01
  • 2020-05-16
  • 1970-01-01
  • 2020-11-30
  • 2023-03-16
  • 1970-01-01
  • 2021-12-15
  • 2021-10-18
相关资源
最近更新 更多