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 相关文章推荐
checkbox全选/取消全选以及checkbox遍历jQuery实现代码
Dec 02 Javascript
文本框input聚焦失焦样式实现代码
Oct 12 Javascript
JS实现控制表格行内容垂直对齐的方法
Mar 30 Javascript
JavaScript实现下拉列表框数据增加、删除、上下排序的方法
Aug 11 Javascript
基于javascript实现窗口抖动效果
Jan 03 Javascript
jQuery中 bind的用法简单介绍
Feb 13 Javascript
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
Feb 27 Javascript
在js中做数字字符串补0(js补零)
Mar 25 Javascript
socket.io与pm2(cluster)集群搭配的解决方案
Jun 02 Javascript
Vue + Element UI图片上传控件使用详解
Aug 20 Javascript
layerui代码控制tab选项卡,添加,关闭的实例
Sep 04 Javascript
浅谈JavaScript 声明提升
Sep 14 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
英雄试炼之肉山谷—引领RPG新潮流
2020/04/20 DOTA
自己动手,丰衣足食 - 短波框形天线制作
2021/03/01 无线电
ADODB结合SMARTY使用~超级强
2006/11/25 PHP
php扩展ZF――Validate扩展
2008/01/10 PHP
php数据入库前清理 注意php intval与mysql的int取值范围不同
2010/12/12 PHP
PHP程序开发范例学习之表单 获取文本框的值
2011/08/08 PHP
PHP aes (ecb)解密后乱码问题
2015/06/22 PHP
关于firefox的ElementTraversal 接口 使用说明
2010/11/11 Javascript
setTimeout()递归调用不加引号出错的解决方法
2014/09/05 Javascript
让JavaScript和其它资源并发下载的方法
2014/10/16 Javascript
node.js中的fs.chown方法使用说明
2014/12/16 Javascript
Js与Jq 获取页面元素值的方法和差异对比
2015/04/30 Javascript
jQuery检测某个元素是否存在代码分享
2015/07/09 Javascript
Jquery中map函数的用法
2016/06/03 Javascript
JS仿百度自动下拉框模糊匹配提示
2016/07/25 Javascript
修改jquery中dialog的title属性方法(推荐)
2016/08/26 Javascript
jQuery实现手机版页面翻页效果的简单实例
2016/10/05 Javascript
JavaScript中绑定事件的三种方式及去除绑定
2016/11/05 Javascript
JS基于for语句编写的九九乘法表示例
2018/01/04 Javascript
JavaScript折半查找(二分查找)算法原理与实现方法示例
2018/08/06 Javascript
angular6.x中ngTemplateOutlet指令的使用示例
2018/08/09 Javascript
vuejs移动端实现div拖拽移动
2019/07/25 Javascript
layui实现form表单同时提交数据和文件的代码
2019/10/25 Javascript
python中requests爬去网页内容出现乱码问题解决方法介绍
2017/10/25 Python
Python打印“菱形”星号代码方法
2018/02/05 Python
python3.6中@property装饰器的使用方法示例
2019/08/17 Python
Python-split()函数实例用法讲解
2020/12/18 Python
CSS3字体效果的设置方法小结
2016/06/13 HTML / CSS
详解CSS3阴影 box-shadow的使用和技巧总结
2016/12/03 HTML / CSS
SQL里面IN比较快还是EXISTS比较快
2012/07/19 面试题
摄影实习自我鉴定
2013/09/20 职场文书
库房管理员岗位职责
2014/03/09 职场文书
感恩的演讲稿
2014/05/06 职场文书
研究生导师评语
2014/12/31 职场文书
办公经费申请报告
2015/05/15 职场文书
论文评审意见
2015/06/05 职场文书