多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

RecordRTC Canvas 录制实战:WebPage、Canvas2D、WebGL 动画与音视频混合录制完整指南

RecordRTC Canvas 录制实战:WebPage、Canvas2D、WebGL 动画与音视频混合录制完整指南 示例工程【免费下载链接】WebRTC-ExperimentWebRTC, WebRTC and WebRTC. Everything here is all about WebRTC!!项目地址https://gitcode.com/gh_mirrors/we/WebRTC-Experiment点击查看免费下载导读本文以 WebRTC-Experiment 仓库中 RecordRTC/Canvas-Recording 模块为核心系统讲解如何使用 RecordRTC 将整个网页、网页局部元素如 DIV、Canvas2D 动画、WebGL 动画、视频网页混合内容以及页面上的一切活动录制为 WebM 视频。读完本文你将掌握RecordRTC(element, { type: canvas })的高层 API 用法、CanvasRecorder独立类的底层原理帧采样 Whammy 编码、captureStream媒体流两条技术路线并能亲手搭建画布动画麦克风、画布动画MP3 音乐等音视频合成录制方案。一、CanvasWebPage 录制能做什么RecordRTC 的 Canvas 录制能力覆盖以下典型场景整页录制把document.documentElement或任意 DIV 传入RecordRTC配合 html2canvas 持续截屏即可把页面上的所有交互输入文字、拖动元素、播放视频、Canvas 动画录成视频Canvas2D 动画录制直接录制canvas元素的绘制过程支持绘制白板、图表、游戏画面等WebGL 动画录制借助canvas.captureStream()将 WebGL 渲染帧捕获为媒体流后录制视频网页混合录制页面内嵌的video播放内容与网页背景动画一并入镜音画合成在录制画布动画的同时叠加麦克风getUserMedia或本地 MP3 音乐Web Audio API音轨生成带声音的完整视频。仓库中 RecordRTC/Canvas-Recording/ 目录提供了 8 个可直接运行的示例页面覆盖上述全部场景是学习与复用的最佳起点。二、两种技术路线html2canvas 采样 与 captureStream 媒体流从源码 RecordRTC/dev/CanvasRecorder.js 可以看到Canvas 录制底层有两条完全不同的实现路线理解它们有助于你在不同浏览器与场景下做出正确选择。路线 AWhammy 逐帧编码html2canvas 采样当浏览器不支持canvas.captureStream或配置了useWhammyRecorder: true时走的是截帧-编码路线定时调用drawCanvasFrame()通过cloneCanvas()深拷贝当前 canvas 像素对非 canvas 元素则调用html2canvas渲染成画布每一帧记录duration与上一帧的时间差并推入whammy.frames数组停止时调用whammy.compile()把各帧的 WebP 图像按时间轴合成 WebM 文件。帧采样间隔由config.frameInterval控制默认 10 毫秒见 RecordRTC/dev/CanvasRecorder.js。frameInterval越小录制越流畅但帧数更多、编码时间更长、内存占用更大。路线 BMediaRecorder captureStream现代浏览器优先在 Chrome 52 等支持canvas.captureStream(25)25 为期望帧率的环境中CanvasRecorder会走captureStreamMediaStreamRecorder路线直接把 canvas 作为实时媒体流交给 Media Recorder API 编码效率更高whammy.frames仅在非流模式下使用见 RecordRTC/dev/CanvasRecorder.js。浏览器兼容性判定逻辑RecordRTC/dev/CanvasRecorder.js 中的判定逻辑可概括为检测captureStream/mozCaptureStream/webkitCaptureStream是否存在Chrome 52 以下版本强制降级为 Whammy 路线设置useWhammyRecorder: true会强制走 Whammy 路线Firefox 因 MediaRecorder 无法录制 CanvasCaptureMediaStream会输出 Canvas recording is NOT supported in Firefox. 提示旧版限制现已改善可优先使用captureStream方案验证。另外RecordRTC/dev/GetRecorderType.js 表明只要config.type canvasRecordRTC 会自动选择CanvasRecorder你也可以通过config.recorderType显式指定任意录制器RecordRTC/dev/GetRecorderType.js。三、快速上手记录整个网页 / 单个元素3.1 最小可运行示例原文档给出的核心用法如下文件路径RecordRTC/Canvas-Recording/README.mdscript srchttps://www.WebRTC-Experiment.com/RecordRTC.js/script script srchttps://www.webrtc-experiment.com/screenshot.js/script div idelement-to-record stylewidth:100%;height:100%;background:green;/div script var elementToRecord document.getElementById(element-to-record); var recorder RecordRTC(elementToRecord, { type: canvas, showMousePointer: true, useWhammyRecorder: true }); recorder.startRecording(); recorder.stopRecording(function(url) { window.open(url); }); /script要点说明RecordRTC.js是录制核心RecordRTC/RecordRTC.js 与 RecordRTC/dev/RecordRTC.js 均可用于构建本目录示例页面统一使用 CDN 引入的RecordRTC.jsscreenshot.jshtml2canvas是必要依赖CanvasRecorder源码在加载时就会检查typeof html2canvas undefined缺失时会直接抛错 Please link: https://www.webrtc-experiment.com/screenshot.js见 RecordRTC/dev/CanvasRecorder.jstype: canvas是入口配置告诉 RecordRTC 按 Canvas 模式处理传入的 HTML 元素传入的对象可以是任意 HTMLElementDIV、整个document.documentElement等源码在非 canvas 元素分支会自动走html2canvas(htmlElement, ...)渲染见 RecordRTC/dev/CanvasRecorder.js。3.2 配置参数速查表以下参数均已在上文源码与 README 中得到确认参数类型默认值说明typestring无必须为canvas用于触发 CanvasRecorder 选择逻辑showMousePointerbooleantrue是否在 html2canvas 截帧时绘制鼠标指针源码默认取真值见 RecordRTC/dev/CanvasRecorder.jsuseWhammyRecorderbooleanfalse设为true时强制使用 Whammy 逐帧编码路线不走 captureStreamdisableLogsbooleanfalse是否禁用控制台日志如 Generating WebM、帧剩余数量等frameIntervalnumber10Whammy 路线下相邻两次截帧的时间间隔毫秒mimeTypestringvideo/webmcaptureStream 路线下传给 MediaStreamRecorder 的 MIME 类型initCallbackfunction无record()启动后立即回调onEncodingCallbackfunction无每编码一帧 WebP 时回调参数为(剩余帧数, 总帧数)initCallback/onEncodingCallback的调用位置见 RecordRTC/dev/CanvasRecorder.js 与 RecordRTC/dev/CanvasRecorder.js。3.3 整页交互录制实战webpage-recordingRecordRTC/Canvas-Recording/webpage-recording.html 演示了完整流程页面内放一个可编辑区域#elementToShare包含输入框、可拖拽文本、Canvas 动画、内嵌video与本地摄像头视频录制时动态创建一个与区域同尺寸的不可见 canvascanvas2d用html2canvas(elementToShare, { grabMouse: true, onrendered })循环把 DOM 渲染到该 canvas用new RecordRTC(canvas2d, { type: canvas })录制这个 canvas见 RecordRTC/Canvas-Recording/webpage-recording.html停止后通过recorder.getBlob()取 BlobURL.createObjectURL(blob)生成播放地址并替换页面为播放器。getBlob()同样适用于 README 中stopRecording(callback)之后取用录制结果是 RecordRTC 的标准取流方式。四、Recordcanvas使用 CanvasRecorder 独立类除高层RecordRTC封装外你也可以直接实例化CanvasRecorderREADME 原样示例script srchttps://www.webrtc-experiment.com/RecordRTC/Whammy.js/script script srchttps://www.webrtc-experiment.com/RecordRTC/CanvasRecorder.js/script canvas/canvas script var canvas document.querySelector(canvas); var recorder new CanvasRecorder(window.canvasElementToBeRecorded, { disableLogs: false }); // start recording canvas drawings recorder.record(); // a few minutes later recorder.stop(function(blob) { var url URL.createObjectURL(blob); window.open(url); }); /scriptCanvasRecorder的完整方法面源码 RecordRTC/dev/CanvasRecorder.jsrecord()开始录制在 captureStream 路线下创建canvasMediaStream并交给MediaStreamRecorder在 Whammy 路线下清空帧数组并启动drawCanvasFrame循环RecordRTC/dev/CanvasRecorder.jsstop(callback)停止录制回调参数为录制好的video/webmBlobWhammy 路线先getWebPImages()把每帧转成 WebP 再whammy.compile()合成RecordRTC/dev/CanvasRecorder.jspause()/resume()暂停/恢复暂停时按 500ms 间隔轮询等待恢复后继续截帧RecordRTC/dev/CanvasRecorder.jsclearRecordedData()清空已录帧并复位状态RecordRTC/dev/CanvasRecorder.jsgetWebPImages(callback)仅适用于传入元素为canvas的场景把whammy.frames中的 Canvas 逐帧转为 WebP dataURL并可通过onEncodingCallback上报进度RecordRTC/dev/CanvasRecorder.js。注意在 captureStream 支持的环境中CanvasRecorder的构造函数要求传入HTMLCanvasElement或CanvasRenderingContext2D传其他元素会抛错见 RecordRTC/dev/CanvasRecorder.js而非 canvas 的 DOM 元素如 DIV在走 captureStream 之前会被强制要求为 canvas 类型因此录 DIV 时要么交给高层RecordRTC它会配合 html2canvas 中转要么显式用useWhammyRecorder: true。五、Canvas2D 动画录制与白板录制示例5.1 最简单的 Canvas2D 动画录制RecordRTC/Canvas-Recording/Canvas-Animation-Recording.html 用requestAnimationFrame驱动一个随机颜色贝塞尔粒子动画录制代码极为精简var canvas document.getElementById(canvas); var recorder RecordRTC(canvas, { type: canvas }); recorder.startRecording(); // ... 15 秒后 recorder.stopRecording(function() { var blob recorder.getBlob(); document.body.innerHTML video controls src URL.createObjectURL(blob) autoplay loop/video; });停止录制后把 Blob 交给video播放即可立即预览这是最常用、最直观的校验方式。该示例页面在停止后还会提示编码进度说明 Whammy 路线下停止录制后仍需要一段时间把全部帧编码为 WebM。5.2 绘图白板录制record-canvas-drawingsRecordRTC/Canvas-Recording/record-canvas-drawings.html 是一个完整的 Canvas 绘图板支持铅笔、马克笔、橡皮、文字、图片、线条、箭头、矩形、圆弧、二次/三次贝塞尔曲线、缩放、拖拽等工具并提供线宽、前景/背景色、globalAlpha、globalCompositeOperation、线帽线接等 Canvas2D 参数面板。其录制核心RecordRTC/Canvas-Recording/record-canvas-drawings.htmlrecorder new RecordRTC(window.canvasElementToBeRecorded, { type: canvas, disableLogs: false }); recorder.startRecording();页面顶部还提供FPS 输入框默认 10范围 0~1000与Add Screen 按钮后者通过getScreenId抓取屏幕流并把屏幕内容绘制到待录制的 canvas 上从而实现绘图 屏幕双内容同屏录制RecordRTC/Canvas-Recording/record-canvas-drawings.html。该页面的绘图工具由同目录 RecordRTC/Canvas-Recording/canvas-designer.js 提供可独立复用于其他项目。六、WebGL 动画录制README 中列举的 WebGL 录制示例webgl/、plotly.html均基于同一条原理WebGL 画布同样是一个canvas直接交给RecordRTC或CanvasRecorder即可。var canvas document.getElementById(webgl-canvas); var recorder RecordRTC(canvas, { type: canvas }); recorder.startRecording();需要留意的是在支持captureStream的浏览器中WebGL canvas 的流捕获效率明显高于逐帧截图建议不要设置useWhammyRecorder某些 WebGL 上下文开启了preserveDrawingBuffer: false默认帧缓冲可能在合成后被清空。若走 Whammy 逐帧截取路线出现黑帧应在创建 WebGL 上下文时设置preserveDrawingBuffer: true或优先使用 captureStream 媒体流路线plotly.html这类基于 WebGL 的图表库页面录制的是图表的旋转、缩放与数据刷新动画与上述方法完全一致。七、音画混合录制Canvas 麦克风 / MP3Canvas 录制默认只有视频轨若要成片带声音需要把音频轨合并进同一个MediaStream再录制。仓库提供了三种递进组合。7.1 Canvas2D 麦克风RecordRTC/Canvas-Recording/Canvas-Animation-Recording-Plus-Microphone.html 的实现RecordRTC/Canvas-Recording/Canvas-Animation-Recording-Plus-Microphone.htmlnavigator.mediaDevices.getUserMedia({audio: true}).then(function(audioStream) { var canvas document.getElementById(canvas); var canvasStream canvas.captureStream(); var finalStream new MediaStream(); getTracks(audioStream, audio).forEach(function(track) { finalStream.addTrack(track); }); getTracks(canvasStream, video).forEach(function(track) { finalStream.addTrack(track); }); var recorder RecordRTC(finalStream, { type: video }); recorder.startRecording(); });关键点一旦合并为多轨媒体流type就要从canvas改为videoRecordRTC 会据此选择 MediaStreamRecorder/Whammy 等视频录制器见 RecordRTC/dev/GetRecorderType.js。视频轨迹由canvas.captureStream()提供音频轨迹来自getUserMedia({audio: true})。7.2 Canvas2D MP3 音乐RecordRTC/Canvas-Recording/Canvas-Animation-Recording-Plus-Mp3.html 使用 Web Audio API 把本地 MP3 变成可录制的音频流RecordRTC/Canvas-Recording/Canvas-Animation-Recording-Plus-Mp3.htmlFileSelector选择.mp3文件FileReader读为 ArrayBufferAudioContext.decodeAudioData解码为 AudioBuffercreateBufferSource循环播放并通过createMediaStreamDestination()把声音导出为MediaStream将该音频流的audio轨迹与canvas.captureStream()的视频轨迹合并为finalStreamtype: video录制。该页面的getMp3Stream(callback)就是文件→可录制音轨的可复用工具函数gainNode.gain.value 0保证本地无声播放、不影响录制体验。7.3 Canvas2D 麦克风 MP3 三轨叠加RecordRTC/Canvas-Recording/Canvas-Animation-Recording-Plus-Microphone-Plus-Mp3.html 是前述两者的组合同时取得getUserMedia({audio: true})的麦克风音轨与 MP3 解码音轨连同 canvas 视频轨一并加入finalStream。若两条音频轨同时存在建议在 Web Audio 侧用createGain控制各自音量例如将音乐侧gain.value调低、麦克风侧保持 1避免互相压制。说明getTracks(stream, audio | video)是 RecordRTC 内置的取轨辅助函数在引入 RecordRTC/RecordRTC.js 后即可直接调用demo 页面中直接使用无需额外引入。八、从源码看配置如何驱动行为8.1 type 如何决定录制器RecordRTC/dev/GetRecorderType.js 完整呈现了决策链type: canvas→ 固定CanvasRecorderRecordRTC/dev/GetRecorderType.jstype: video且 Chrome/Opera → 默认WhammyRecorder若存在 WebAssembly 编码器则优先WebAssemblyRecorderRecordRTC/dev/GetRecorderType.jstype: gif→GifRecorder传入 MediaStream 数组 →MultiStreamRecorder显式config.recorderType优先级最高覆盖所有自动推断RecordRTC/dev/GetRecorderType.js。8.2 recorderType 与 type 的联动RecordRTC/dev/RecordRTC-Configuration.js 显示当recorderType指定为WhammyRecorder/CanvasRecorder/WebAssemblyRecorder时type会被自动补全为video指定GifRecorder则补全为gif指定StereoAudioRecorder补全为audio。因此两种写法等价// 写法一 RecordRTC(canvas, { type: canvas }); // 写法二显式指定录制器 RecordRTC(canvas, { recorderType: CanvasRecorder, type: video });九、常见问题与工程建议忘引 screenshot.js 报错CanvasRecorder构造时若找不到html2canvas直接抛异常务必同时引入RecordRTC.js与screenshot.js录制结果为空/黑屏优先确认是否走了 captureStream 路线且 canvas 尺寸正常Whammy 路线下检查frameInterval是否过大导致帧数过少停止后长时间无响应Whammy 路线停止后需逐帧转 WebP 并合成 WebM页面主线程会繁忙属正常现象可用onEncodingCallback展示进度避免用户误关页面demo 页面也会提示 Please never click kill buttonFirefox 兼容老版本不支持 canvas 录制现代版本建议直接走captureStreamMediaStreamRecorder即不设useWhammyRecorder音画合并必须用type: video多轨MediaStream不是canvas 类型继续用type: canvas会导致录制器选择错误WebGL 黑帧Whammy 路线下给 WebGL 上下文加preserveDrawingBuffer: true或改用 captureStream 路线性能取舍录制整页 DOMhtml2canvas 渲染比录制单个 canvas 昂贵得多能用 canvas 就尽量在 canvas 上做合成把 DOM 元素先绘制进离屏 canvas 再录制。十、相关资源索引模块说明与官方示例入口RecordRTC/Canvas-Recording/README.md核心实现CanvasRecorderRecordRTC/dev/CanvasRecorder.js录制器自动选择逻辑RecordRTC/dev/GetRecorderType.js配置解析与 recorderType 联动RecordRTC/dev/RecordRTC-Configuration.jsRecordRTC 主库与构建版RecordRTC/RecordRTC.js、RecordRTC/RecordRTC.min.js逐页可运行的示例整页交互录制RecordRTC/Canvas-Recording/webpage-recording.html绘图白板录制RecordRTC/Canvas-Recording/record-canvas-drawings.htmlCanvas2D 动画RecordRTC/Canvas-Recording/Canvas-Animation-Recording.htmlCanvas2D麦克风RecordRTC/Canvas-Recording/Canvas-Animation-Recording-Plus-Microphone.htmlCanvas2DMP3RecordRTC/Canvas-Recording/Canvas-Animation-Recording-Plus-Mp3.htmlCanvas2D麦克风MP3RecordRTC/Canvas-Recording/Canvas-Animation-Recording-Plus-Microphone-Plus-Mp3.html本地复现这些示例时可直接在浏览器打开上述 HTML 文件或通过仓库根目录的 server.js 启动静态服务后访问Canvas 录制与 getUserMedia 相关能力需要 HTTPS 或 localhost 环境支持。赞分享示例工程【免费下载链接】WebRTC-ExperimentWebRTC, WebRTC and WebRTC. Everything here is all about WebRTC!!项目地址https://gitcode.com/gh_mirrors/we/WebRTC-Experiment点击查看免费下载相关推荐RecordRTC 使用与源码解析基于 WebRTC 的音频、视频、屏幕与 Canvas 录制完整指南RecordRTC 使用与源码解析基于 WebRTC 的音频、视频、屏幕与 Canvas 录制完整指南 RecordRTC 是 WebRTC Experime示例工程从脚手架到生产上线Backbone-Require-Boilerplate开发最佳实践完整清单从脚手架到生产上线Backbone Require Boilerplate开发最佳实践完整清单 Backbone Require Boilerplate简称示例工程RecordRTC结合Socket.io实现音视频录制与合并技术解析RecordRTC结合Socket.io实现音视频录制与合并技术解析 项目概述 RecordRTC是一个强大的WebRTC录制库而本文要介绍的RecordRT音视频WebRTC上一篇告别代码生硬输出PHP Humanizer让数据呈现如自然语言般流畅下一篇Sniffle蓝牙5和4.xLE嗅探器的强大工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表