Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何将Canvas绘制过程转为视频 #30

Open
akira-cn opened this issue Aug 10, 2020 · 2 comments
Open

如何将Canvas绘制过程转为视频 #30

akira-cn opened this issue Aug 10, 2020 · 2 comments

Comments

@akira-cn
Copy link
Owner

如果我们用Canvas实现了一些动画效果,需要将它回放出来,很多人通常就是用录屏工具将屏幕内容录下来播放,很少有人知道,Canvas可以直接通过现代浏览器支持的 Media Streams API 来转成视频。

Canvas对象支持captureStream方法,这个方法会返回一个MediaStream对象。然后,我们可以通过这个对象创建一个MediaRecorder来录屏。

我们看一个简单的例子。

录制视频

首先我们写一个非常简单的Canvas动画效果,代码如下:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const {width, height} = canvas;

ctx.fillStyle = 'red';

function draw(rotation = 0) {
  ctx.clearRect(0, 0, 1000, 1000);
  ctx.save();
  ctx.translate(width / 2, height / 2);
  ctx.rotate(rotation);
  ctx.translate(-width / 2, -height / 2);
  ctx.beginPath();
  ctx.rect(200, 200, 200, 200);
  ctx.fill();
  ctx.restore();
}

function update(t) {
  draw(t / 500);
  requestAnimationFrame(update);
}
update(0);

这个效果实现一个200宽高的矩形在画布中心旋转。

接下来,我们将这个效果录制下来,假设我们录制6秒的视频,首先我们要获取MediaStream对象:

const stream = canvas.captureStream();

然后,我们创建一个MediaRecorder:

const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });

接着我们可以注册ondataavailable事件,将数据记录下来:

const data = [];
recorder.ondataavailable = function (event) {
  if (event.data && event.data.size) {
    data.push(event.data);
  }
};

在onstop事件里,我们通过Blob对象,将数据写入到页面上的video标签中。

recorder.onstop = () => {
  const url = URL.createObjectURL(new Blob(data, { type: 'video/webm' }));
  document.querySelector("#videoContainer").style.display = "block";
  document.querySelector("video").src = url;
};

如果你不了解Blob对象,可以看这篇文章

最后,我们开始录制视频,并设定在6秒钟之后停止录制:

recorder.start();

setTimeout(() => {
  recorder.stop();
}, 6000);

这样,就可以达到我们想要的录屏效果了。

完整的代码在这里

与音频结合

Canvas录制好的视频,我们还可以将它和音频结合,方法是通过ffmpeg的Web端来合成。

浏览器可以通过WebAssembly来集成ffmpeg,具体的项目在这里,有兴趣的同学可以研究下。

ffmpeg的Web API用起来还比较复杂,奇舞团的同学开发了一个非常好用的封装,项目地址在这里,可以在这里看到具体的例子

总结

在一些需要动态回放需求的场景里,我们可以用Canvas来实时创建视频然后回放,从而不必使用JS重新绘制,这是一种比较节省资源的方式。另外,Canvas的录制功能对于一些在线教学的场景也很有价值,录屏软件消耗资源较多,而在Web上直接录制Canvas,这可能是一种更简单便捷的方式。

@KaiOrange
Copy link

666

@HypnosNova
Copy link

https://github.com/ValeeraJS/WebRTCRecorder
我有自己的开源库。非常好用

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants