JavaScript实现页面中录音功能的方法


Posted in Javascript onJune 04, 2019

前言

页面中实现录音需要使用浏览器提供的 Media​Recorder API,所以前提是需要浏览器支持 MediaStream Recording 相关的功能。

以下代码默认工作在 Chrome 环境中。

准备页面

首先准备一个页面,其中内容很简单,一个录音按钮,一个用于播放的 <audio> 标签。

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <meta http-equiv="X-UA-Compatible" content="ie=edge">
 <title>audio record</title>
</head>
<body>
 <div class="app">
  <button class="record-btn">record</button>
  <audio controls class="audio-player"></audio>
 </div>
 <script src="./recorder.js"></script>
</body>
</html>

获取录音权限

因为录音需要使用设备的话筒,所以第一步应该是向用户索要录音的权限。这是通过 Media​Devices​.get​User​Media()
来完成的,其用法为:

var promise = navigator.mediaDevices.getUserMedia(constraints);

其中 constraints 为需要获取的权限列表,这里只需要指定音频 audio 即可。

其返回是个 Promise,因为用户何时进行授权是不确定的。通过在 Promise 的回调中进行授权成功或失败的处理。

在使用前需要判断浏览器是否已经支持相应的 API,此时得到如下的代码:

if (navigator.mediaDevices.getUserMedia) {
 const constraints = { audio: true };
 navigator.mediaDevices.getUserMedia(constraints).then(
 stream => {
  console.log("授权成功!");
 },
 () => {
  console.error("授权失败!");
 }
 );
} else {
 console.error("浏览器不支持 getUserMedia");
}

其中成功回调里得到的入参 stream 为 MediaStream 对象。

此时运行后可看到浏览器展示出了让用户授权使用麦克风的提示。

JavaScript实现页面中录音功能的方法

向用户索要麦克风使用权限

创建录音实例

将上一步获取到的 MediaStream 传入 Media​Recorder 的构造器创建一个录音器的实例。

var mediaRecorder = new MediaRecorder(stream);

启动录音

通过监听页面中录音按钮的点击来启动录音。

const recordBtn = document.querySelector(".record-btn");
const mediaRecorder = new MediaRecorder(stream);
recordBtn.onclick = () => {
 mediaRecorder.start();
 console.log("录音中...");
};

MediaRecorder 实例上有个 state 状态,可用来判断录音器当前的活动状态,总共有三种值:

  • inactive:处于休息状态,要么是没开始,要么是开始后已经停止。
  • recording:录音中
  • paused:已经开始,但被暂停了,不是停止也没有被恢复。

所以通过这个状态,我们可以实现再次点击按钮时,结束录音。

recordBtn.onclick = () => {
 if (mediaRecorder.state === "recording") {
  mediaRecorder.stop();
  recordBtn.textContent = "record";
  console.log("录音结束");
 } else {
  mediaRecorder.start();
  console.log("录音中...");
  recordBtn.textContent = "stop";
 }
 console.log("录音器状态:", mediaRecorder.state);
};

音频数据的获取

上面按钮处理来自用户的交互,只负责启动或停止录音。音频的数据还是从 Media​Recorder 实例上通过监听其相应的事件来完成的。

当录音开始时,会触发其 MediaRecorder.ondataavailable 事件,从该事件回调的入参为 BlobEvent,从它身上取到 event.data 便是我们需要的音频数据。因为数据是一段一段产生的,所以需要暂存到一个数组中。

const chunks = [];
mediaRecorder.ondataavailable = function(e) {
 chunks.push(e.data);
};

目前为止完成的代码应该是这样的:

 recorder.js

JavaScript实现页面中录音功能的方法

录音状态的查看

录音结束及音频的播放

通过监听 MediaRecorder.onstop 事件,将收集好的音频数据创建成Blob 对象,然后 通过 URL.createObjectURL 创建成 HTML 中 <audio> 标签可使用的资源链接。

mediaRecorder.onstop = e => {
 var blob = new Blob(chunks, { type: "audio/ogg; codecs=opus" });
 chunks = [];
 var audioURL = window.URL.createObjectURL(blob);
 audio.src = audioURL;
};

其中,在使用完收到到的音频数据后,将 chunks 置空方便下次录音时使用。

目前为止完成的代码应该是这样的:

 recorder.js

运行

完成上面步骤后,实现了一个简单的录音功能,可通过此地址在线体验。完整的代码可在仓库 wayou/audio-recorder 中获取到。

相关资源

  • Media​Recorder
  • MediaRecorder.onstop
  • URL.createObjectURL

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
给网站上的广告“加速”显示的方法
Apr 08 Javascript
javascript 静态对象和构造函数的使用和公私问题
Mar 02 Javascript
IE8下Jquery获取select选中的值post到后台报错问题
Jul 02 Javascript
jquery获取一个元素下面相同子元素的个数代码
Jul 31 Javascript
有效提高JavaScript执行效率的几点知识
Jan 31 Javascript
jquery实现textarea 高度自适应
Mar 11 Javascript
提高jQuery性能优化的技巧
Aug 03 Javascript
jQuery autoComplete插件两种使用方式及动态改变参数值的方法详解
Oct 24 Javascript
javascript 秒表计时器实现代码
Mar 09 Javascript
JS实现非首屏图片延迟加载的示例
Jan 06 Javascript
vue2.0组件之间传值、通信的多种方式(干货)
Feb 10 Javascript
Vue事件修饰符native、self示例详解
Jul 09 Javascript
vue elementUI 表单校验功能之数组多层嵌套
Jun 04 #Javascript
小程序根据手机机型设置自定义底部导航距离
Jun 04 #Javascript
js回文数的4种判断方法示例
Jun 04 #Javascript
Vue对象赋值视图不更新问题及解决方法
Jun 03 #Javascript
在 Vue 应用中使用 Netlify 表单功能的方法详解
Jun 03 #Javascript
JavaScript之数组扁平化详解
Jun 03 #Javascript
JavaScript从原型到原型链深入理解
Jun 03 #Javascript
You might like
php实现MySQL数据库备份与还原类实例
2014/12/09 PHP
PHP中使用BigMap实例
2015/03/30 PHP
通过PHP自带的服务器来查看正则匹配结果的方法
2015/12/24 PHP
php基于session锁防止阻塞请求的方法分析
2017/08/07 PHP
js实现鼠标滚轮控制图片缩放效果的方法
2015/02/20 Javascript
javascript引用类型指针的工作方式
2015/04/13 Javascript
函数window.open实现关闭所有的子窗口
2015/08/03 Javascript
JavaScript判断表单中多选框checkbox选中个数的方法
2015/08/17 Javascript
JavaScript  cookie 跨域访问之广告推广
2016/04/20 Javascript
jQuey将序列化对象在前台显示地实现代码(方法总结)
2016/12/13 Javascript
Ajax验证用户名或昵称是否已被注册
2017/04/05 Javascript
es6 symbol的实现方法示例
2019/04/02 Javascript
jQuery实现的记住帐号密码功能完整示例
2019/08/03 jQuery
layui数据表格重载实现往后台传参
2019/11/15 Javascript
python 算法 排序实现快速排序
2012/06/05 Python
Python使用MySQLdb for Python操作数据库教程
2014/10/11 Python
Python中SOAP项目的介绍及其在web开发中的应用
2015/04/14 Python
基于python3实现socket文件传输和校验
2018/07/28 Python
基于numpy中数组元素的切片复制方法
2018/11/15 Python
python 抓包保存为pcap文件并解析的实例
2019/07/23 Python
python定时任务 sched模块用法实例
2019/11/04 Python
基于Python 中函数的 收集参数 机制
2019/12/21 Python
python+OpenCV实现图像拼接
2020/03/05 Python
Python3自动生成MySQL数据字典的markdown文本的实现
2020/05/07 Python
PyTorch中model.zero_grad()和optimizer.zero_grad()用法
2020/06/24 Python
matplotlib自定义鼠标光标坐标格式的实现
2021/01/08 Python
实例教程 利用html5和css3打造一款创意404页面
2014/10/20 HTML / CSS
Skyscanner加拿大:全球旅行搜索平台
2018/11/19 全球购物
美国传奇滑手Paul Rodriguez创办的街头滑板品牌:Primitive Skateboarding
2019/10/29 全球购物
汽车电子与维修专业大学生求职信
2013/09/28 职场文书
资料员岗位职责
2013/11/17 职场文书
大学军训感言1000字
2014/02/25 职场文书
诉讼财产保全担保书
2014/05/20 职场文书
Nginx中break与last的区别详析
2021/03/31 Servers
解决SpringBoot跨域的三种方式
2021/06/26 Java/Android
virtualenv隔离Python环境的问题解析
2022/06/21 Python