前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Canvas实时回显和录制

Canvas实时回显和录制

作者头像
前端小鑫同学
发布2022-12-26 08:44:47
1.5K0
发布2022-12-26 08:44:47
举报
文章被收录于专栏:小鑫同学编程历险记

在线教育类的产品中经常会遇到的一个场景就是实时显示学生的答题过程并且支持回溯,通常我们想到的做法就是通过记录坐标和重新绘制来达到产品的要求,再查看了相关资料后知道了Canvas元素的captureStream()API可以实时返回捕捉的画布,那我们就来了解一下这个API的使用吧。

关键API: HTMLCanvasElement.captureStream()

语法:

MediaStream = canvas.captureStream(frameRate);

参数:
  • frameRate 帧捕获速率(FPS)
    • 可选参数
    • 未设置:画布更改时捕获新的一帧。
    • 设置为0:捕获单个帧。
    • 设置为25:每帧捕获速率25的双精度浮点值。返回值:
  • MediaStream 对象 兼容性:
image.png
image.png

注意:

  • Firefox 41和Firefox 42中需要手动开启,将canvas.capturestream.enabled 设置 true
  • 详细的API还是要参考MDN,我还将一些常见的前端用到的网站进行了汇总也可以通过IT200.CN访问,静态页面不存储任何个人信息。 Demo演示 代码为React版本,参考书籍《WebRTC音视频开发》。
准备我们的布局

准备一个canvas元素来做我们的答题板。

准备一个video元素来实时显示我们在答题板上的操作。

准备一个按钮来启动同步显示答题板并进行录制

准备一个按钮来停止录制

代码语言:javascript
复制
<div className="container">
  <div>
 <p>画板区</p>
 <canvas ref={this.canvasRef}></canvas>
  </div>
  <div>
 <p>视频区</p>
   <video ref={this.videoRef} playsInline autoPlay></video>
  </div>
  <button onClick={this.startCaptureCanvas}>开始</button>
  <button onClick={this.stopRecord}>停止</button>
</div>
看一下流程图
image.png
image.png
开始实施

初始化画板答题器

准备画布:初始化宽高数据,将画布填充一个颜色并指定画笔的粗细和颜色

代码语言:javascript
复制
initCanvas = () => {
    canvas = this.canvasRef.current;
    canvas.width = 500;
    canvas.height = 350;
    context = canvas.getContext("2d");
    context.fillStyle = "#ccc";
    context.fillRect(0, 0, canvas.width, canvas.height);

    context.lineWidth = 1;
    context.storkeStyle = "#000";

    canvas.addEventListener("mousedown", this.startAction);
    canvas.addEventListener("mouseup", this.endAction);
};

跟随手指划线:

  1. 初始化画笔原点
  2. 移动画笔绘制轨迹
  3. 结束时移除事件
代码语言:javascript
复制
startAction = (event) => {
    context.beginPath();
    context.moveTo(event.offsetX, event.offsetY);
    context.stroke();
    canvas.addEventListener("mousemove", this.moveAction);
};

moveAction = (event) => {
  context.lineTo(event.offsetX, event.offsetY);
  context.stroke();
};

endAction = () => {
  canvas.removeEventListener("mousemove", this.moveAction);
};

streamcanvas流向video

代码语言:javascript
复制
startCaptureCanvas = async (e) => {
 stream = canvas.captureStream(25);
 const video = this.videoRef.current;
 video.srcObject = stream;
};

启动答题板录制

start设置数值的作用是录制的媒体按指定大小切块,避免内容过大。

ondataavailable:保存每次回调的数据块

代码语言:javascript
复制
startRecord = (stream) => {
  recordeBlobs = [];
  mediaRecorder = new MediaRecorder(stream, {
    mimeType: "video/webm",
  });
  mediaRecorder.onstop = (event) => {
    console.log("录制完成");
  };
  mediaRecorder.ondataavailable = (event) => {
    if (event.data &amp;&amp; event.data.size > 0) {
      recordeBlobs.push(event.data);
    }
  };
  mediaRecorder.start(100);
};

停止录制后,清空相关对象获取视频文件

代码语言:javascript
复制
stopRecord = () => {
 mediaRecorder.stop();
 stream.getTracks().forEach((track) => track.stop());
 stream = null;
 const blob = new Blob(recordeBlobs, { type: "video/webm" });
 const url = window.URL.createObjectURL(blob);
 const a = document.createElement("a");
 a.style.display = "none";
 a.href = url;
 a.download = "canvas.webm";
 document.body.appendChild(a);
 a.click();
 setTimeout(() => {
   document.body.removeChild(a);
   window.URL.revokeObjectURL(url);
 }, 100);
};

完整代码(私聊获取)

效果预览
111.gif
111.gif
思路扩展
  • API的使用是很简单的,要是对接远程服务器在其他端进行显示还是需要Socket进行加持。闲言碎语
  • 你们有做过这样的功能吗?你是怎么实现的呀?
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-08-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 关键API: HTMLCanvasElement.captureStream()
    • 语法:
      • 参数:
        • 准备我们的布局
          • 看一下流程图
            • 开始实施
              • 效果预览
                • 思路扩展
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档