前端工程记录:用RecordRTC实现对<video>标签的录像功能

项目需求:后端给一个mp4视频的链接,在前端播放,同时支持用户的录制视频操作。

一、技术选择

1. 毫无关系的getUserMedia

官方介绍文档:MediaDevices.getUserMedia() - Web API 接口参考 | MDN

在网上搜索“前端如何录像”,AI非常贴心地提供了这个函数,代码也写得有模有样,仔细一看发现和目的毫不相干,浏览器提供的 navigator.mediaDecives.getUserMedia() 是用来调用摄像头和麦克风的,与其相仿的 navigator.mediaDecives.getDisplayMedia() 则能够实现共享窗口和屏幕。

起初我想利用 navigator.mediaDecives.getDisplayMedia 对页面进行录制,但是在浏览器中,被共享的内容可以是浏览器的其他页面、正在使用的其他窗口、整个屏幕,唯独没有调用此函数的界面,遂放弃此想法。

2. rrweb

官网使用文档:https://github.com/rrweb-io/rrweb/blob/master/guide.zh_CN.md

这个库也是在网上看到的,用的人很多,然而不适用本工作场景,rrweb关注整个页面以及用户在页面上的各种操作,会记录页面DOM节点的变动,适合录制网课这类的场景,用来处理单独的video元素,有种杀鸡用牛刀的感觉。

3. recordrtc - canvas用法

github地址:https://github.com/muaz-khan/RecordRTC

recordrtc是基于webRTC的实现录屏的库,支持audio, video, canvas, gif四种类型。

具体使用流程如下(以普通html文件为例):

(1)引入

<script src="https://cdn.WebRTC-Experiment.com/RecordRTC.js"></script>
<script src="https://cdn.webrtc-experiment.com/screenshot.js"></script>

(2)创建对象

let element = document.getElementById('canvas');
let recordRTC = RecordRTC(element, {type: 'canvas'
});

(3)开始录制和结束录制

function start() {recordRTC.startRecording();
}function stop() {            recordRTC.stopRecording(function(videoURL) {var a = document.createElement('a');a.href = videoURL;a.download = 'a.mp4';a.click();});
}

在结束录制函数stopRecording中,videoURL返回的是一个blob url,将其赋值给video元素的src,可以直接播放出录制的视频。本项目中需要下载录制视频,因此将videoURL赋值给新建的a标签,从而实现对录制视频的下载

(4)将video内容绘制到canvas上

let ctx = canvas.getContext('2d');
let video = document.getElementById('video');
video.addEventListener('play', function() {setInterval(() => {ctx.drawImage(content, 0, 0, 500, 300);}, 100);
}, false);

在type="canvas"的配置下,recordrtc会对canvas进行录制,而canvas不能直接包含video标签,所以为了录制视频,监听视频的播放操作,在play状态下将画面逐帧绘制到canvas上,我采用了setInterval,用requestAnimationFrame是同样的效果。

(5)html内容

<canvas id="elementToShare" width="500" height="300">
</canvas><video width="500" height="300" controls id="video" src="./test.mp4">
</video><div><button onclick="start()">开始录制</button><button onclick="stop()">结束录制</button>
</div>

以上代码能成功实现对video的录制,而且完全没有后期出现的录制视频卡顿的问题。但是,没声音。canvas只能录制画面,而我的需求是录制带声音的视频。

二、实际使用

1. 技术方案:recordrtc

在recordrtc的官方案例中,给出的是这样一个例子

let stream = await navigator.mediaDevices.getUserMedia({video: true, audio: true});
let recorder = RecordRTC(stream, {type: 'video'
});

其中,RecordRTC接收的第一个参数是来自媒体设备传来的视频流。

我起初尝试仿照canvas,直接将video节点传入,然而不行,在type为video的情况下,RecordRTC接收的第一个参数必须是流。

在网上搜了半天,找到了一个函数captureStream,在浏览器上的兼容性一般,但是能够实现将获取video流的效果。

2. 代码

<template><div v-if="isShow" :style="domStyle" ><div class="control-box><Button v-show="!isRecording" @click="startRecord">录制</Button><Button v-show="isRecording" @click="stopRecord">停止录制</Button></div><div class="video-box"><video controls ref="video"></video></div><a ref="link"></a></div>
</template><script>
import RecordRTC from 'recordrtc';
export default {data() {return {isRecording: false,recordRTC: null,};},created() {// ...},mounted() {// ...this.initRecordRTC();},methods: {// 初始化recordRTCinitRecordRTC() {this.recordRTC = null;let stream = null;const video = this.$refs.video;if (video.captureStream) { // 适用于chrome内核stream = video.captureStream();} else if (video.mozCaptureStream) { // 适用于firefox内核stream = video.mozCaptureStream();} else {this.$Message.warning('不支持captureStream,无法录制!');return;}this.recordRTC = RecordRTC(stream, {type: 'video'});},// 录制startRecord() {this.recordRTC.startRecording();this.isRecording = true;},// 停止录制stopRecord() {this.recordRTC.stopRecording((videoURL) => {let a = this.$refs.link;a.href = videoURL;a.download = 'test.mp4';a.click();});this.isRecording = false;},}
};
</script><style scoped>
.video-box {padding: 10px;
}
</style>

3. 细节问题

由于项目中的播放器支持用户改变文件路径,出现一个问题是,在修改video的src后,如果在播放视频前点击录制,项目会报一个错误,原因是在startRecording之前获取不到stream流。

解决方案是为recorder.startRecording加一个定时器,将上面的startRecord函数改成如下内容:

startRecord() {setTimeout(() => {this.recordRTC.startRecording();this.isRecording = true;}, 500);        
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/624816.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Maxwell数据同步(增量)

1. Maxwell简介 1.1 Maxwell概述 Maxwell 是由美国Zendesk公司开源&#xff0c;用Java编写的MySQL变更数据抓取软件。它会实时监控Mysql数据库的数据变更操作&#xff08;包括insert、update、delete&#xff09;&#xff0c;并将变更数据以 JSON 格式发送给 Kafka、Kinesi等流…

全链路压力测试:现代软件工程中的重要性

全链路压力测试不仅可以确保系统在高负载下的性能和稳定性&#xff0c;还能帮助企业进行有效的风险管理和性能优化。在快速发展的互联网时代&#xff0c;全链路压力测试已成为确保软件产品质量的关键步骤。 1、测试环境搭建 测试应在与生产环境尽可能相似的环境中进行&#xff…

windows使用redis-安装和配置

windows使用redis 安装和配置 下载安装方式一-使用压缩包安装解压到指定的文件Redis安装为Windows服务安装成功 方式二-MSI安装包安装完成 Redis配置远程访问1.修改配置文件redis.windows.conf2.修改完redis配置文件&#xff0c;必须重启redis 下载 先下载Redis for windows 的…

Java lambda表达式如何自定义一个toList Collector

匿名类&#xff1a; package l8;import java.util.*; import java.util.function.BiConsumer; import java.util.function.BinaryOperator; import java.util.function.Function; import java.util.function.Supplier; import java.util.stream.Collector; import java.util.s…

PyTorch中的FX图

一.FX 图介绍 FX 图是 PyTorch 中的一个主要数据结构&#xff0c;用于在 FX 中间表示&#xff08;Intermediate Representation&#xff0c;IR&#xff09;中表示程序。FX 图由一系列节点组成&#xff0c;每个节点代表调用站点&#xff08;比如运算符、方法和模块&#xff09;。…

高级编程JavaScript。Notifications消息通知

- Notifications Notifications API 用于向用户显示通知。无论从哪个角度看&#xff0c;这里的通知都很类似 alert()对话框&#xff1a; 都使用 JavaScript API 触发页面外部的浏览器行为&#xff0c;而且都允许页面处理用户与对话框或通知弹层的交 互。不过&#xff0c;通知…

React 18 中的并发性

并发性是我们在 React 18 发布后获得的重大成就之一。由于此功能是完全选择加入的&#xff0c;并且 React 18 向后兼容以前的版本&#xff0c;因此您甚至可能没有注意到新功能。那么并发性是什么、它是如何工作的以及它如何改进您的应用程序的呢&#xff1f; 什么是并发 并发…

360度评估的应用场景和评估内容

360度评估是一种多元化的评估工具&#xff0c;它从多个角度获取对个体绩效、能力和行为的全面反馈。这种评估方法不仅涵盖了传统的上级评价&#xff0c;还包括同级、下级、自我评价以及客户或外部利益相关者的反馈。 一、360度评估的应用场景 员工绩效评估&#xff1a;360度评…

【PostgreSQL内核学习(二十二)—— 执行器(ExecutePlan)】

执行器&#xff08;InitPlan&#xff09; 概述ExecutePlan 函数ExecProcNode 函数 总结 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊重他人的知识产权和学术成果&#xff0c;力求遵循合理使用原则&#xff0c;并在适用的情况下注明引用来…

超详细!4小时开发一个SpringBoot+vue前后端分离博客项目!!

超详细&#xff01;4小时开发一个SpringBootvue前后端分离博客项目&#xff01;&#xff01; 前后端分离项目 文章总体分为2大部分&#xff0c;Java后端接口和vue前端页面&#xff0c;比较长&#xff0c;因为不想分开发布&#xff0c;真正想你4小时学会&#xff0c;哈哈。 先…

【自学笔记】01Java基础-07面向对象基础-04接口与内部类详解

记录学习Java基础中有关接口类和内部类的知识。 1 接口 interface 关键字用于定义接口类&#xff0c;接口类是一系列方法的声明&#xff0c;一般只有方法的特征没有方法的实现&#xff0c;因此可以被不同的类接入实现&#xff0c;而这些实现可以具有不同的行为&#xff08;功…

Graham扫描凸包算法

凸包&#xff08;Convex Hull&#xff09;是包含给定点集合的最小凸多边形。凸包算法有多种实现方法&#xff0c;其中包括基于递增极角排序、Graham扫描、Jarvis步进法等。下面&#xff0c;我将提供一个简单的凸包算法实现&#xff0c;基于Graham扫描算法。 Graham扫描算法是一…

多级缓存架构(一)项目初始化

文章目录 一、项目克隆二、数据库准备三、项目工程准备 一、项目克隆 克隆此项目到本地 https://github.com/Xiamu-ssr/MultiCache 来到start目录下&#xff0c;分别有以下文件夹 docker&#xff1a;docker相关文件item-service&#xff1a;springboot项目 二、数据库准备 …

Ncast盈可视高清智能录播系统busiFacade RCE漏洞(CVE-2024-0305)

产品介绍 Ncast盈可视高清智能录播系统是一套新进的音视频录制和播放系统&#xff0c;旨在提供高质量&#xff0c;高清定制的录播功能。 漏洞描述 广州盈可视电子科技有限公司的高清智能录播系统存在信息泄露漏洞(CVE-2024-0305)&#xff0c;攻击者可通过该漏洞&#xff0c;…

Sectigo的DV通配符https

Sectigo是近些年发展比较快速的CA认证机构&#xff0c;为了提升审核效率&#xff0c;在全国成立了审核机构&#xff0c;亚太审核中心的成立加快了Sectigo旗下的https证书的审核速度。Sectigo的https证书可以为网站安全提供有力支持&#xff0c;从而保护网站信息安全。今天就随S…

群狼调研(长沙神秘顾客公司)开展某品牌家纺神秘顾客调研

为评估某品牌家纺的产品品质、设计、服务、价格等情况。群狼调研&#xff08;长沙娱乐场所神秘顾客调查&#xff09;受客户委托在全国1500家门店进行神秘顾客调研。本次调研神秘顾客全部由群狼调研从累计的16年资源库中筛选出的有经验的人员&#xff0c;以普通消费者的身份进店…

3、深入解析Redis Cluster集群运维与核心原理

在今天的大规模分布式系统中&#xff0c;Redis Cluster已经成为了许多企业选择的分布式缓存方案之一。了解Redis Cluster的运维及核心原理对于确保系统的高可用性和性能至关重要。本文将深入探讨Redis Cluster集群的运维细节和核心原理&#xff0c;以帮助读者更好地理解和优化R…

常见的HTTP接口超时问题出现原因及解决办法

HTTP接口超时问题是指在HTTP请求发送到服务器后&#xff0c;由于等待服务器响应的时间超过了预设的超时时间&#xff0c;导致请求被中断。以下是可能导致HTTP接口超时问题的原因和解决方法&#xff1a; 网络延迟或不稳定&#xff1a;网络延迟或不稳定可能导致请求在传输过程中…

【STM32】STM32学习笔记-MPU6050简介(32)

00. 目录 文章目录 00. 目录01. MPU6050简介02. MPU6050参数03. MPU6050硬件电路04. MPU6050框图05. MPU6050常用寄存器06. 附录 01. MPU6050简介 •MPU6050是一个6轴姿态传感器&#xff0c;可以测量芯片自身X、Y、Z轴的加速度、角速度参数&#xff0c;通过数据融合&#xff0…

网站监测工具的极与极,Site24x7 与百川云

今天我们聊聊我用 Site24x7 的感受。对于有网站监测有需求的站长们来说&#xff0c;Site24x7 确实是个很强大的应用。但是它与百川云网站监测完全不一样&#xff0c;百川云网站监测是适合用中小微企业的交互极简的saas 应用&#xff0c;Site24x7 完全是另一个极端&#xff0c;适…