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进行加持。


闲言碎语

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



相关文章
|
2月前
|
存储 前端开发 API
在网页中进行音频录制
【10月更文挑战第9天】
229 58
|
6月前
|
数据采集 人工智能 文字识别
ADB命令来捕获设备屏幕快照和发送鼠标事件来实现抓取公众号文章
ADB命令来捕获设备屏幕快照和发送鼠标事件来实现抓取公众号文章。解决方案: 1.通过ADB命令来捕获设备屏幕快照,传递给电脑并且保存在本地文件; 2.通过百度飞桨ocr解析图片获取内容并保存; 3.根据解析的内容和坐标,向手机发送鼠标事件(点击和上下,左右滑动)来控制页面的跳转。
102 1
|
缓存 监控 前端开发
调用摄像机播放画面,并且实现录制GIF动图预览和下载
调用摄像机播放画面,并且实现录制GIF动图预览和下载
|
C++
Qt图片定时滚动播放器
可以显示jpg、jpeg、png、bmp。可以从电脑上拖动图到窗口并显示出来或者打开文件选择,定时滚动图片 重载实现dragEnterEvent(拖拽)、dropEvent(拖拽放下)、resizeEvent(窗口大小改变)
131 0
|
Web App开发 JavaScript 中间件
高版本Chrome VUE页面播放RTSP实时视频流,并抓图、录像、回放、倍速等
因为项目上需要把海康威视摄像头集成到WEB网页中播放,于是开始了对WEB播放摄像头方案的各种折腾。 2015年之前还可以用VLC原生播放器在Chrome、Firefox等浏览器中直接播放,延迟比较低,效果也还不错。可惜好景不长,从 2015年Chrome、Firefox等浏览器取消了对 NPAPI插件的支持,海康威视官方提供的 web3.0开发包也只能在低版本浏览器播放。
892 1
|
移动开发 编解码 前端开发
这段代码可以将Canvas录制为webm视频文件
2020年6月我做了一个给程序员专用的虚拟鼓励师插件叫“Rainbow Fart Waifu”,VSCode和HBuilderX的插件市场里都可以搜到。
429 0
这段代码可以将Canvas录制为webm视频文件
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )
587 0
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(二)
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(二)
884 0
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(二)
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(一)
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(一)
1492 0
【FFmpeg】ffplay 播放视频命令 ( 播放 | 暂停 | 停止 | 音量控制 | 进度控制 | 音频流 / 视频流 / 字幕流 / 节目切换 )(一)
用触发器在PowerPoint控制音频的播放
用触发器在PowerPoint控制音频的播放
343 0
用触发器在PowerPoint控制音频的播放