如何使用Javascript/Angular录制与客户的双向在线语音对话?
如何用JavaScript/Angular实现双方在线对话的双向语音录制
当然可以实现。你之前用MediaRecorder只录到自身语音,是因为只捕获了本地麦克风的媒体流,没有把远程对话方的音频流纳入录制范围。核心思路是同时获取本地和远程的音频流,将它们合并后再用MediaRecorder录制。
核心实现步骤
1. 捕获本地音频流
首先通过浏览器API获取用户麦克风的音频流:
async function getLocalAudioStream() { try { return await navigator.mediaDevices.getUserMedia({ audio: true }); } catch (err) { console.error('无法获取本地麦克风权限:', err); throw err; } }
2. 获取远程音频流
在线对话一般基于WebRTC实现(Angular项目中可直接用原生WebRTC,或封装好的库),在建立Peer连接后,通过ontrack事件获取远程方的音频流:
// 假设已创建RTCPeerConnection实例 const peerConnection = new RTCPeerConnection(); peerConnection.ontrack = (event) => { const remoteStream = event.streams[0]; // 保存远程流,后续用于合并 window.remoteStream = remoteStream; };
如果使用第三方对话SDK,可通过其提供的API直接获取远程音频流,逻辑一致。
3. 合并本地与远程音频流
有两种方式合并流:
方式1:直接合并轨道(多轨录制)
直接将两个流的音频轨道合并成一个新的MediaStream,适合需要保留双轨的场景:
const localStream = await getLocalAudioStream(); const combinedStream = new MediaStream([ ...localStream.getAudioTracks(), ...window.remoteStream.getAudioTracks() ]);
方式2:混音为单轨(兼容性更好)
部分播放器不支持多轨音频,可使用AudioContext将两个音频流混音为单轨:
async function mixAudioStreams(localStream, remoteStream) { const audioContext = new AudioContext(); // 创建源节点 const localSource = audioContext.createMediaStreamSource(localStream); const remoteSource = audioContext.createMediaStreamSource(remoteStream); // 创建混音目标节点 const destination = audioContext.createMediaStreamDestination(); // 连接到混音节点 localSource.connect(destination); remoteSource.connect(destination); return destination.stream; } // 使用示例 const mixedStream = await mixAudioStreams(localStream, window.remoteStream);
4. 用MediaRecorder录制合并后的流
最后用MediaRecorder录制合并/混音后的流:
function startRecording(stream) { const recorder = new MediaRecorder(stream); const chunks = []; recorder.ondataavailable = (e) => chunks.push(e.data); recorder.onstop = () => { const recordingBlob = new Blob(chunks, { type: 'audio/webm' }); // 下载录制文件 const url = URL.createObjectURL(recordingBlob); const downloadLink = document.createElement('a'); downloadLink.href = url; downloadLink.download = 'conversation-recording.webm'; downloadLink.click(); URL.revokeObjectURL(url); }; recorder.start(); return recorder; } // 开始录制 const recorder = startRecording(mixedStream); // 停止录制时调用 // recorder.stop();
Angular项目中的适配
在Angular里,你可以把上述逻辑封装成一个服务(如RecordingService),通过依赖注入在组件中调用:
import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class RecordingService { async getLocalAudioStream() { // 同JS版本的getLocalAudioStream逻辑 } mixAudioStreams(localStream: MediaStream, remoteStream: MediaStream) { // 同JS版本的混音逻辑 } startRecording(stream: MediaStream) { // 同JS版本的录制逻辑 } }
注意事项
- 必须获取用户的麦克风权限,需处理权限拒绝的异常情况
- 浏览器兼容性:
MediaRecorder和WebRTC在Chrome、Firefox、Edge等现代浏览器均支持,Safari需注意版本(14.1+支持MediaRecorder) - 音频格式:推荐使用
audio/webm格式,兼容性最优;如需MP3格式,需借助第三方编码库
内容的提问来源于stack exchange,提问作者Mark Joeben Orocio
相关产品推荐
相关产品推荐

