JavaScript 浏览器调用麦克风录音
在前端网页中,录音功能一般常用于语音输入,例如 Google翻译的语音输入,YouTube 的语音搜索。相比桌面客户端和手机 App 来说网页的录音用的要少一些,但现在越来越多的桌面应用程序都使用 Electron 开发,手机 App 也会用到 Webview,浏览器的录音 API 在这些地方也是可以用的。
我这里使用的是比较简单的 MediaRecorder
API,MediaRecorder
不支持 IE 系列浏览器。
点击 录音demo 可以查看最终实现效果。
录音和播放
下面实现录音和播放录音,放几个 HTML 按钮:
<button type="button" id="start-btn">开始录音</button>
<button type="button" id="stop-btn">停止录音</button>
<button type="button" id="play-btn">播放录音</button>
<a href="https://www.misterma.com">Mr. Ma's Blog misterma.com</a>
上面的 Mr. Ma's Blog 链接可以忽略。
JavaScript:
const startBtn = document.querySelector('#start-btn'); // 开始录音按钮
const stopBtn = document.querySelector('#stop-btn'); // 停止录音按钮
const playBtn = document.querySelector('#play-btn'); // 播放录音按钮
let mediaRecorder = null; // 存放 MediaRecorder
let audioData = []; // 存储录音数据块
// 开始录音按钮点击
startBtn.addEventListener('click', () => {
// 请求麦克风权限
navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
// 创建媒体记录
mediaRecorder = new MediaRecorder(stream, {mimeType: 'audio/webm'});
// 开始录制
mediaRecorder.start();
// 处理音频数据
mediaRecorder.addEventListener('dataavailable', ev => {
// 把数据块添加到数组
audioData.push(ev.data);
});
// 录音停止
mediaRecorder.addEventListener('stop', () => {
// 把音频数据块转换为 Blob
audioData = new Blob(audioData);
});
}).catch(info => {
alert('无法获取麦克风权限!错误信息:' + info);
});
});
// 停止录音按钮点击
stopBtn.addEventListener('click', () => {
mediaRecorder.stop();
});
// 播放录音按钮点击
playBtn.addEventListener('click', () => {
if (audioData === null) return false;
// 创建一个 URL 资源对象给 Audio 读取
const audio = new Audio(URL.createObjectURL(audioData));
// 播放音频
audio.play();
});
上面只是简单演示,没有做按钮重复点击判断之类的。
点击 开始录音
按钮后浏览器会弹出麦克风授权的对话框,点击 允许
就会开始录音,点击 拒绝
或点击取消就会弹出 无法获取麦克风权限!
的提示。
点击 停止录音
按钮就会停止录音,点击 播放录音
按钮就能播放刚才的录音。
详细说明
上面的录音和播放录音可分为几个步骤:
- 申请麦克风权限
- 录音
- 获取音频数据
- 转换和播放音频
申请麦克风权限
navigator.mediaDevices.getUserMedia
可以请求媒体输入许可,需要传入一个对象来设置请求媒体类型,支持的类型包括 audio
和 video
。audio
是音频输入设备,例如麦克风,video
是视频输入设备,例如摄像头,如果需要拍照就需要申请 video
,如果要拍视频就可以同时申请 video
和 audio
。
用户选择完成后会返回一个 Promise
,成功 then
会返回一个媒体流对象,失败 catch
会返回错误信息。
录制音频
有了麦克风权限就可以创建 MediaRecorder
音频录制接口,在实例化时需要传入一个媒体流对象,可以直接使用申请权限时返回的 stream
。第二个参数是配置选项,如果省略会使用浏览器的默认配置。配置选项是一个对象,包括 mimeType
MIME 类型和 audioBitsPerSecond
音频比特率,我设置的 mimeType
是 audio/webm
,也就是使用 webm 格式来录制音频,webm 是 Google 的音视频格式 Firefox 不一定支持,使用 MediaRecorder
的 isTypeSupported()
方法可以查看浏览器是否支持该 mimeType
。
调用 MediaRecorder
的 start()
方法可以开始录制,start()
方法可以传入一个 timeslice
参数,timeslice
参数可以设置一个毫秒值,录音数据可以根据设置的时长分割为多个数据区块,省略 timeslice
会生成一个完整的 Blob
数据。
处理音频数据
dataavailable
事件会在录音停止时触发,如果在 start
中传入了时长的话,时间到了也会触发,event
的 data
属性就是音频数据。
播放录音
播放录音就比较简单了,直接使用 audio
元素就可以,音频数据需要使用 URL.createObjectURL()
转换为 URL 对象传给 audio
使用,调用 Audio
的 play
方法可以播放音频。
MediaRecorder 相关
下面是我这里没有用到的一些 MediaRecorder
的事件和方法:
MediaRecorder.pause()
方法
暂停媒体录制。
MediaRecorder.resume()
方法
继续录制。
MediaRecorder.requestData()
方法
调用这个方法时,录制数据会被截断,同时也会触发 dataavailable
事件,但录制不会停止。
pause
事件
录制暂停时触发。
resume
事件
从暂停状态恢复录制时触发。
start
事件
录制开始时触发。
stop
事件
录制停止时触发。
导出录音
这里在上面的代码基础上再增加一个导出录音文件的功能,HTML 增加一个按钮:
<button type="button" id="export-btn">导出录音</button>
这里的 JS 代码需要和上面的 JS 代码结合:
const exportBtn = document.querySelector('#export-btn'); // 导出录音按钮
// 导出录音按钮点击
exportBtn.addEventListener('click', () => {
// 创建一个链接
const link = document.createElement('a');
// 把音频数据转换为 URL 资源对象传给链接的 href
link.href = URL.createObjectURL(audioData);
// 设置下载时的文件名,后缀是 webm
link.download = 'audio.webm';
// 点击链接
link.click();
});
点击导出按钮会弹出文件下载,导出的是一个 webm 格式的文件,常见的播放器可能无法正常播放,把文件拖到 Chrome 浏览器或使用 audio
元素可以正常播放。
以上就是前端浏览器录音功能的简单实现,如果要上传录音文件的话,可以把 Blob 数据添加到 FormData 上传。
类似文章:
版权声明:本文为原创文章,版权归 Mr. Ma's Blog 所有,转载请联系博主获得授权。
本文地址:https://www.misterma.com/archives/907/
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。
大佬 ,我想将音频数据块转换成文件流,或者是MP3和wav不想转换成 new Blob文件
来看主题的,不看内容 :)