Canvas实时回显和录制

简介: Canvas实时回显和录制

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


关键API: HTMLCanvasElement.captureStream()


语法:

MediaStream = canvas.captureStream(frameRate);


参数:

  • frameRate 帧捕获速率(FPS)
  • 可选参数
  • 未设置:画布更改时捕获新的一帧。
  • 设置为0:捕获单个帧。
  • 设置为25:每帧捕获速率25的双精度浮点值。


返回值:

  • MediaStream 对象


兼容性:

1.png注意:


  • Firefox 41和Firefox 42中需要手动开启,将canvas.capturestream.enabled 设置 true
  • 详细的API还是要参考MDN,我还将一些常见的前端用到的网站进行了汇总也可以通过IT200.CN访问,静态页面不存储任何个人信息。


Demo演示


代码为React版本,参考书籍《WebRTC音视频开发》。


准备我们的布局

  1. 准备一个canvas元素来做我们的答题板。
  2. 准备一个video元素来实时显示我们在答题板上的操作。
  3. 准备一个按钮来启动同步显示答题板并进行录制
  4. 准备一个按钮来停止录制
<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>


看一下流程图

2.png


开始实施

  1. 初始化画板答题器

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

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. 结束时移除事件
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);
};


  1. streamcanvas流向video
startCaptureCanvas = async (e) => {
    stream = canvas.captureStream(25);
    const video = this.videoRef.current;
    video.srcObject = stream;
};


  1. 启动答题板录制


  • start设置数值的作用是录制的媒体按指定大小切块,避免内容过大。
  • ondataavailable:保存每次回调的数据块
startRecord = (stream) => {
    recordeBlobs = [];
    mediaRecorder = new MediaRecorder(stream, {
      mimeType: "video/webm",
    });
    mediaRecorder.onstop = (event) => {
      console.log("录制完成");
    };
    mediaRecorder.ondataavailable = (event) => {
      if (event.data && event.data.size > 0) {
        recordeBlobs.push(event.data);
      }
    };
    mediaRecorder.start(100);
};


  1. 停止录制后,清空相关对象获取视频文件
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);
};


  1. 完整代码(私聊获取)


效果预览

3.png


思路扩展

  • API的使用是很简单的,要是对接远程服务器在其他端进行显示还是需要Socket进行加持。


闲言碎语

  • 你们有做过这样的功能吗?你是怎么实现的呀?



相关文章
|
数据可视化 前端开发 JavaScript
vue3+threejs可视化项目——引入threejs加载钢铁侠模型(第二步)
vue3+threejs可视化项目——引入threejs加载钢铁侠模型(第二步)
1574 3
|
API 图形学
Winform控件优化之自定义控件的本质【从圆角控件看自定义的本质,Region区域无法反锯齿的问题】
自定义控件的本质只有两点:重绘控件Region区域(圆角、多边形、图片等),这是整个控件的真实范围;重绘图形,在原有Region范围内,重绘不同的图形(圆角、多边形、图片等)作为背景......
857 0
Winform控件优化之自定义控件的本质【从圆角控件看自定义的本质,Region区域无法反锯齿的问题】
|
1月前
|
NoSQL 算法 Linux
OpenOCD下载安装保姆级教程(附安装包,非常详细)
OpenOCD是一款开源片上调试工具,支持JTAG/SWD接口,提供GDB Server、TCL脚本自动化等功能,可实现断点调试、Flash烧录、FPGA编程等,广泛应用于嵌入式开发与量产测试,被誉为“穷人的Lauterbach”。跨平台且免费,配置灵活但稍复杂,是嵌入式工程师的高效调试利器。
|
11月前
|
小程序 数据安全/隐私保护 UED
创新陪玩代练模式:小程序源码软件开发的挑战与机遇
随着互联网娱乐行业的蓬勃发展,陪玩代练服务成为新兴休闲娱乐方式,满足玩家在游戏、学习、健身等多方面的陪伴与指导需求。小程序作为连接玩家与陪玩人员的平台,面临技术实现难度(如实时语音通信、高并发处理)、数据安全、功能多样化及用户体验优化等挑战,同时也孕育着巨大机遇。市场竞争激烈,小程序需具备独特卖点以脱颖而出。
334 0
创新陪玩代练模式:小程序源码软件开发的挑战与机遇
|
人工智能 前端开发 架构师
2025年前端局势分析,我该不该转行?
2024年,前端领域经历了快速变化,AIGC的兴起和市场HC减少使得前端工程师面临挑战。尽管AI工具如通义灵码和Cursor能高效生成代码,但AI无法完全取代前端工程师,因其缺乏逻辑、沟通和创新能力。前端工作不仅限于编码,还包括需求分析、代码评审等。未来,前端不会“死亡”,而是持续演变。面对大环境的压力,提升综合能力、拥抱变化、持续学习和保持身心健康是关键。转型方向包括升管理、做架构师或转讲师等。稳住2025年,需适应变化、不断学习并探索更多可能性。
2205 16
|
人工智能
用AI人模拟社会学实验,居然成功了?斯坦福、NYU用GPT-4模仿人类,准确度惊人!
斯坦福大学和纽约大学的研究团队利用GPT-4模型成功模拟了人类在社交互动中的行为模式,实验结果显示AI能以惊人准确度模仿人类对话,甚至在在线论坛和社交媒体上与真人难以区分。这一突破不仅展示了AI在社会学研究中的巨大潜力,还引发了对AI伦理和透明度的深入探讨。尽管存在一些局限性和挑战,这项研究为未来社会学实验提供了新工具和方法。[论文地址:https://docsend.com/view/qeeccuggec56k9hd]
628 2
|
存储 JSON 关系型数据库
【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解
【unity实战】制作unity数据保存和加载系统——大型游戏存储的最优解
866 2
|
存储 安全 网络安全
网络安全中的安全审计与合规性:技术深度解析
【7月更文挑战第7天】安全审计与合规性是保障网络安全的重要环节。通过安全审计,企业可以及时发现并修复安全漏洞,提高系统的安全性;通过合规性管理,企业可以确保自身在法律法规和行业标准方面的合规性,降低违规风险。然而,在实施安全审计与合规性管理的过程中,企业也面临着技术复杂性、数据量大以及法规和合规性要求变化等挑战。因此,企业需要不断加强技术投入和人员培训,提高自身的安全审计与合规性管理水平。
|
C# iOS开发 Java
****Objective-C 中的方法的调用
oc语言中采用特定的语言调用类或者实例(对象)的方法称为发送消息或者方法调用。 oc中方法的调用有两种:  第一种: [类名或对象名 方法名];   [ClassOrInstance method]; [ClassOrInstance method:arg1]; ...
1380 0

热门文章

最新文章