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

Angular集成OpenVidu开发视频通话 切换麦克风后出现自身语音回声

你遇到的回声属于本地环路回声,不是通话传输链路产生的回声,因此设置echoCancellation参数无法解决,问题根因是本地环境意外播放了自己的麦克风输入音轨。

具体修改方案

问题根因说明

  1. 你调用getUserMedia获取新麦克风音轨后,只提取了需要的音频轨,剩余的临时流没有被销毁,浏览器会默认在后台播放这个流,导致直接听到自己的声音
  2. OpenVidu的发布者默认会将本地预览的音视频元素设置为静音,替换音轨后这个配置可能失效,没有自动继承静音设置
  3. 你只调用了OpenVidu的replaceTrack方法更新发布流,但是原本持有的currentMediaStream没有更新轨道,可能导致残留的旧轨道或者重复轨道被意外播放

修改后的完整代码

async onMicrophoneSelected(event: any) {
    var currentMediaStream: MediaStream = this.localUsersService.getWebcamPublisher().stream.getMediaStream();
    var currentAudioTrack: MediaStreamTrack;
    var currentVideoTrack: MediaStreamTrack;
    var newAudioInfo: MediaDeviceInfo | undefined;
    var newAudioTrack: MediaStreamTrack;

    // 获取当前正在使用的音轨
    currentMediaStream.getTracks().forEach((track) => {
        if (track.kind === 'audio') {
            currentAudioTrack = track;
        }
        if (track.kind === 'video') {
            currentVideoTrack = track;
        }
    });

    // 获取选中的麦克风设备信息
    const devices = await navigator.mediaDevices.enumerateDevices();
    newAudioInfo = devices.find(device => device.kind === 'audioinput' && device.deviceId === event.value);
    if (!newAudioInfo) return;

    // 获取新麦克风音轨
    const tempStream = await navigator.mediaDevices.getUserMedia({ 
        audio: { 
            deviceId: { exact: newAudioInfo.deviceId },
            echoCancellation: true,
            noiseSuppression: true,
            autoGainControl: true
        } 
    });
    newAudioTrack = tempStream.getAudioTracks()[0];
    // 销毁临时流的所有轨道,避免静默播放
    tempStream.getTracks().forEach(track => {
        if (track !== newAudioTrack) track.stop();
    });

    // 替换OpenVidu发布流的音轨
    await this.localUsersService.getWebcamPublisher().replaceTrack(newAudioTrack);
    // 停掉旧音轨
    currentAudioTrack?.stop();
    // 更新本地MediaStream的轨道
    currentMediaStream.removeTrack(currentAudioTrack);
    currentMediaStream.addTrack(newAudioTrack);
    // 强制本地预览元素静音
    const localVideoEl = this.localUsersService.getWebcamPublisher().videoElement;
    if (localVideoEl) {
        localVideoEl.muted = true;
        localVideoEl.volume = 0;
    }

    console.log(currentMediaStream.getTracks(), '<<<-- checking stream after changes');
}

额外排查点

如果修改后仍有回声,检查页面DOM中是否存在未被静音的<audio>/<video>元素在播放本地媒体流,及时移除或静音这些元素即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 16:45:06