前端实现录音有两种方式,一种是使用MediaRecorder,另一种是使用WebRTC的getUserMedia结合AudioContext,MediaRecorder出现得比较早,只不过Safari/Edge等浏览器一直没有实现,所以兼容性不是很好,而WebRTC已经得到了所有主流浏览器的支持,如Safari 11起就支持了。所以我们用WebRTC的方式进行录制。
为实现录音功能,我们先从播放本地文件音乐说起,因为有些API是通用的。
1. 播放本地音频文件实现
播放音频可以使用audio标签,也可以使用AudioContext,audio标签需要一个url,它可以是一个远程的http协议的url,也可以是一个本地的blob协议的url,怎么创建一个本地的url呢?
使用以下html做为说明:
<input type="file" onchange="playMusic.call(this)" class="select-file">
<audio class="audio-node" autoplay></audio>
提供一个file input上传控件让用户选择本地的文件和一个audio标签准备来播放。当用户选择文件后会触发onchange事件,在onchange回调里面就可以拿到文件的内容,如下代码所示:
function playMusic () {
if (!this.value) {
return;
}
let fileReader = new FileReader();
let file = this.files[0];
fileReader.onload = function () {
let arrayBuffer = this.result;
console.log(arrayBuffer);
}
fileReader.readAsArrayBuffer(this.files[0]);
}
这里使用一个FileReader读取文件,读取为ArrayBuffer即原始的二进制内容,把它打印如下所示:
可以用这个ArrayBuffer实例化一个Uint8Array就能读取它里面的内容,Uint8Array数组里面的每个元素都是一个无符号整型8位数字,即0 ~ 255,相当于每1个字节的0101内容就读取为一个整数。
这个arrayBuffer可以转成一个blob,然后用这个blob生成一个url,如下代码所示:
fileReader.onload = function () {
let arrayBuffer = this.result;
// 转成一个blob
let blob = new Blob([new Int8Array(this.result)]);
// 生成一个本地的blob url
let blobUrl = URL.createObjectURL(blob);
console.log(blobUrl);
// 给audio标签的src属性
document.querySelector('.audio-node').src = blobUrl;
}
主要利用URL.createObjectURL这个API生成一个blob的url,这个url打印出来是这样的:
blob:null/c2df9f4d-a19d-4016-9fb6-b4899bac630d
然后丢给audio标签就能播放了,作用相当于一个远程的http的url.
在使用ArrayBuffer生成blob对象的时候可以指定文件类型或者叫mime类型,如下代码所示:
let blob = new Blob([new Int8Array(this.result)], {
type: 'audio/mp3' // files[0].type
});
这个mime可以通过file input的files[0].type得到,而files[0]是一个File实例,File有mime类型,而Blob也有,因为File是继承于Blob的,两者是同根的。所以在上面实现代码里面其实不需要读取为ArrayBuffer然后再封装成一个Blob,直接使用File就行了,如下代码所示:
function playMusic () {
if (!this.value) {
return;
}
// 直接使用File对象生成blob url
let blobUrl = URL.createObjectURL(this.files[0]);
document.querySelector('.audio-node').src = blobUrl;
}
而使用AudioContext需要拿到文件的内容,然后手动进行音频解码才能播放。
关注+后台私信我,领取2022最新最全学习提升资料包《Andoird音视频开发必备手册+音视频最新学习视频+大厂面试真题+