| 效果
| 实现思路
1.利用浏览器的navigator.mediaDevices.getUserMedia
进行录音
2.将录音数据传输给websocket广播给其他人
3.渲染录音
navigator.mediaDevices.getUserMedia
返回的是一个promise对象
| Talk is cheap. Show me the code
客户端
利用浏览器的navigator.mediaDevices.getUserMedia
进行录音
Touch开始时
if (!this.audioMediaPromise) {
const constraints = { audio: true, video: false };
this.audioMediaPromise =
navigator?.mediaDevices?.getUserMedia(constraints);
}
this.audioMediaPromise.then(stream => {
this.recorder = new MediaRecorder(stream);
this.recorder.start(); // 开始录音
const self = this;
this.recorder.ondataavailable = function (event) {
console.log(event.data, '声音数据'); // Blob
if (event.data.size === 0) return;
// 发送websocket请求
const params: any = {
msg: '语音文件',
sendId: getUserId(),
date: dayjs().format('YYYY-MM-DD HH:mm:ss'),
type: chatSendTypeEnum.World,
username: '用户' + getUserId(),
recordData: event.data, // 录音文件
duration: String(self.recorderTime)
};
SocketTest.socket.emit('sendMessage', params);
self.recorderTime = 0;
};
});
this.audioMediaPromise.catch(function (error) {
console.log(error);
});
touch结束后
/**
* 语音录制长按松开
* @returns
*/
onRecorderTouchEnd() {
console.log('录音结束');
clearInterval(this.recorderTimer);
if (!this.recorder) {
return;
}
this.recorder.stop();
}
服务端
将语音数据广播给客户端
socket.on('sendMessage', data => {
// 广播给所有用户
if (data.type === chatSendTypeEnum.World) {
io.emit('receiveMessage', data);
}
});
客户端
获取到声音数据,通过audio标签播放
SocketTest.socket.on('receiveMessage', data => {
if (data.type === chatSendTypeEnum.World) {
console.log('世界频道信息接收', data);
const blob = new Blob([data.recordData]);
const audioUrl = URL.createObjectURL(blob);
if (!this.audioElem) {
this.audioElem = document.createElement('audio');
} else {
this.audioElem.pause();
}
this.audioElem.src = audioUrl;
this.audioElem.play();
}
});
| 参考资料
# MediaDevices.getUserMedia() - Web API 接口参考| MDN
# Socket.IO