求基于AudioNodes的PeerJS音频示例及音频接收无信号排查
PeerJS音频连接无信号、无输出问题修复
问题根源
你的代码存在几个关键疏漏:
- 接收端拿到对方音频流后,仅连接到分析器,未关联扬声器节点,导致无声音输出
- 接收端未为对方音频流启动可视化实例,所以看不到信号
- 使用
createMediaStreamDestination生成的处理后流,在部分场景下可能存在轨道状态异常,导致PeerJS传输后无法正常解析
修复代码
Caller 修正版
callButton.addEventListener('click', () => { // 绑定本地音频到输出节点 const outgoingStream = audioCtx.createMediaStreamDestination(); inputSourceNode.connect(outgoingStream); // 启动本地音频可视化 const analyser = audioCtx.createAnalyser(); inputSourceNode.connect(analyser); const canvas = document.getElementById('dupeSignal'); const vu = new AudioVisualizer(canvas, analyser); vu.start(); const call = peer.call(otherId, outgoingStream.stream); call.on('error', (err) => { console.log(`Call error: ${err.message}`); }); call.on('stream', (incomingStream) => { console.log('Received peer stream'); if (peerSourceNode) { peerSourceNode.disconnect(); } peerSourceNode = audioCtx.createMediaStreamSource(incomingStream); // 同时连接分析器(可视化)和扬声器(音频输出) peerSourceNode.connect(peerAnalyser); peerSourceNode.connect(audioCtx.destination); // 启动对方音频的可视化 const peerCanvas = document.getElementById('peerSignal'); // 需提前准备对应canvas元素 const peerVu = new AudioVisualizer(peerCanvas, peerAnalyser); peerVu.start(); }); });
Callee 修正版
peer.on('call', function(call) { console.log('Incoming call'); const outgoingStream = audioCtx.createMediaStreamDestination(); inputSourceNode.connect(outgoingStream); // 启动本地音频可视化 const analyser = audioCtx.createAnalyser(); inputSourceNode.connect(analyser); const canvas = document.getElementById('dupeSignal'); const vu = new AudioVisualizer(canvas, analyser); vu.start(); call.answer(outgoingStream.stream); call.on('stream', function(incomingStream) { console.log('Received peer stream'); if (peerSourceNode) { peerSourceNode.disconnect(); } peerSourceNode = audioCtx.createMediaStreamSource(incomingStream); // 同时连接分析器和扬声器 peerSourceNode.connect(peerAnalyser); peerSourceNode.connect(audioCtx.destination); // 启动对方音频的可视化 const peerCanvas = document.getElementById('peerSignal'); // 需提前准备对应canvas元素 const peerVu = new AudioVisualizer(peerCanvas, peerAnalyser); peerVu.start(); }); });
额外优化建议
- 优先使用原始麦克风流:如果不需要音频处理,直接传递
getUserMedia获取的原始流,避免处理流的兼容性问题:navigator.mediaDevices.getUserMedia({ audio: true }) .then(stream => { const call = peer.call(otherId, stream); // 后续逻辑... }); - 检查权限与轨道状态:在控制台打印
outgoingStream.stream.getAudioTracks(),确认音频轨道处于启用状态,同时确保页面已获取麦克风权限。 - 调试流完整性:接收端拿到
incomingStream后,打印incomingStream.getAudioTracks(),确认轨道存在且可用。
内容的提问来源于stack exchange,提问作者MattD
相关产品推荐
相关产品推荐

