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 相关文章推荐
仿校内登陆框,精美,给那些很厉害但是没有设计天才的程序员
Nov 24 Javascript
不要在cookie中使用特殊字符的原因分析
Jul 13 Javascript
在新窗口打开超链接的方法小结
Apr 14 Javascript
jquery ajax同步异步的执行最终解决方案
Apr 26 Javascript
JSON+HTML实现国家省市联动选择效果
May 18 Javascript
javascript查询字符串参数的方法
Jan 28 Javascript
JS实现的简洁二级导航菜单雏形效果
Oct 13 Javascript
VueJs与ReactJS和AngularJS的异同点
Dec 12 Javascript
js删除数组中的元素delete和splice的区别详解
Feb 03 Javascript
vue-star评星组件开发实例
Mar 01 Javascript
小程序实现图片预览裁剪插件
Nov 22 Javascript
详解在Vue.js编写更好的v-for循环的6种技巧
Apr 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
php中的一个中文字符串截取函数
2007/02/14 PHP
php中ftp_chdir与ftp_cdup函数用法
2014/11/18 PHP
PHP使用GETDATE获取当前日期时间作为一个关联数组的方法
2015/03/19 PHP
php 类自动载入的方法
2015/06/03 PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
2016/12/15 PHP
PHP中类与对象功能、用法实例解读
2020/03/27 PHP
div模拟滚动条效果示例代码
2013/10/16 Javascript
js HTML5 Ajax实现文件上传进度条功能
2016/02/13 Javascript
JS实现用户注册时获取短信验证码和倒计时功能
2016/10/27 Javascript
浅析BootStrap中Modal(模态框)使用心得
2016/12/24 Javascript
js中常用的Math方法总结
2017/01/12 Javascript
js实现一个猜数字游戏
2017/03/31 Javascript
JavaScrip数组删除特定元素的几种方法总结
2017/09/06 Javascript
jQuery实现输入框的放大和缩小功能示例
2018/07/21 jQuery
搭建一个nodejs脚手架的方法步骤
2019/06/28 NodeJs
layui table动态表头 改变表格头部 重新加载表格的方法
2019/09/21 Javascript
Python编程判断一个正整数是否为素数的方法
2017/04/14 Python
matplotlib subplots 设置总图的标题方法
2018/05/25 Python
python3写的简单本地文件上传服务器实例
2018/06/04 Python
python2 与 python3 实现共存的方法
2018/07/12 Python
Python企业编码生成系统之主程序模块设计详解
2019/07/26 Python
Django之使用内置函数和celery发邮件的方法示例
2019/09/16 Python
pygame实现俄罗斯方块游戏(基础篇1)
2019/10/29 Python
python turtle工具绘制四叶草的实例分享
2020/02/14 Python
django实现模型字段动态choice的操作
2020/04/01 Python
Python基于execjs运行js过程解析
2020/11/27 Python
python Scrapy框架原理解析
2021/01/04 Python
解析HTML5的存储功能和web SQL的相关操作方法
2016/02/19 HTML / CSS
Manuka Doctor美国官网:麦卢卡蜂蜜和蜂毒护肤
2016/12/25 全球购物
英国赛车、汽车改装和摩托车零件购物网站:Demon Tweeks
2018/10/29 全球购物
英国第一的市场和亚马逊替代品:OnBuy
2019/03/16 全球购物
豪华复古化妆:Besame Cosmetics
2019/09/06 全球购物
退休感言
2014/01/28 职场文书
股东授权委托书范本
2014/09/13 职场文书
劳动仲裁代理词范文
2015/05/25 职场文书
类和原型的设计模式之复制与委托差异
2022/07/07 Javascript