You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求基于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();
    });
});

额外优化建议

  1. 优先使用原始麦克风流:如果不需要音频处理,直接传递getUserMedia获取的原始流,避免处理流的兼容性问题:
    navigator.mediaDevices.getUserMedia({ audio: true })
      .then(stream => {
          const call = peer.call(otherId, stream);
          // 后续逻辑...
      });
    
  2. 检查权限与轨道状态:在控制台打印outgoingStream.stream.getAudioTracks(),确认音频轨道处于启用状态,同时确保页面已获取麦克风权限。
  3. 调试流完整性:接收端拿到incomingStream后,打印incomingStream.getAudioTracks(),确认轨道存在且可用。

内容的提问来源于stack exchange,提问作者MattD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 01:57:10