0

我正在构建一个 Angular 应用程序,它允许 2 个用户使用 Openvidu 呼叫解决方案互相视频通话。

在这个应用程序中,我开发了一项功能,可以更改您在通话中积极使用的摄像头或麦克风。

一旦选择了新的麦克风,之前的麦克风轨道就会停止并从流中删除,然后再添加新的麦克风。这个过程封装在下面的代码中:

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

        var newAudioInfo: MediaDeviceInfo; // type here is MediaDeviceInfo as it will be specified from enumerateDevices()
        var newAudioTrack: MediaStreamTrack;
        var newVideoTrack: MediaStreamTrack;

        // Specifying current video & audio track being used on call
        currentMediaStream.getTracks().forEach((track) => {
            if (track.kind === 'audio') {
                currentAudioTrack = track;
                currentAudioTrack.stop();  // stopping old audio track here 
            }

            if (track.kind === 'video') {
                currentVideoTrack = track;
            }
        });

        // Looping through available devices
        await navigator.mediaDevices.enumerateDevices().then((res) => {
            res.forEach((device) => {
                // Checking for: the current inactive device
                if (device.kind === 'audioinput' && device.deviceId === event.value) {
                    newAudioInfo = device;
                }
            });
        });

        // Passing constraints that contain new deviceId for audio, then using replaceTrack() to replace audio  // this also promps user for new device permissions
        await navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: newAudioInfo.deviceId } } }).then((stream) => {
            newAudioTrack = stream.getAudioTracks()[0];
        });

        // replaceTrack() used here to notify OpenVidu of new devices, where they will then be published and thus changes also seen by the other-end-user
        this.localUsersService
            .getWebcamPublisher()
            .replaceTrack(newAudioTrack)
            .then(() => {
                console.log(currentMediaStream.getTracks(), '<<<-- checking stream after changes');
            });
    }

上述代码成功运行后,最终结果应该是我在通话中主动使用的麦克风应该已经更改为我选择的那个。

情况就是这样,但是我面临的问题是,这种变化也伴随着我自己的非常响亮的回声,这意味着一旦我切换麦克风,有源麦克风就会改变,我也可以通过那个麦克风听到自己的声音。

对此的任何想法将不胜感激,感谢您的阅读。

注意:echoCancellation没有解决这个问题。

4

1 回答 1

0

因此,我在 Firefox、Safari 和 Google 浏览器上运行了此代码,因此请随意使用此代码。

我遇到回声问题的原因是因为我正在运行“initwebcamPublisher()设置ngOnInit()”组件......这个功能已经在应用程序启动时运行了一次,并且再次执行它会导致网络摄像头发布者出现某种重复。

在删除我留下的工作onMicrophoneSelect()

async onMicrophoneSelected(event: any) {
        const audioSource = event?.value;

        if (!!audioSource) {
            // Is New deviceId different than older?
            if (this.oVDevicesService.needUpdateAudioTrack(audioSource)) {
                const mirror = this.oVDevicesService.cameraNeedsMirror(this.camSelected.device);
                this.openViduWebRTCService.unpublishWebcamPublisher();
                this.openViduWebRTCService.replaceTrack(null, audioSource, mirror);
                this.openViduWebRTCService.publishWebcamPublisher();
                this.oVDevicesService.setMicSelected(audioSource);
                this.micSelected = this.oVDevicesService.getMicSelected();
            }
            // Publish microphone
            this.publishAudio(true);
            this.isAudioActive = true;

            return;
        }

        // Unpublish microhpone
        this.publishAudio(false);
        this.isAudioActive = false;
    }

因此,一旦用户选择了新的麦克风,他们当前的摄像头和麦克风就不会被发布,导致他们在其他用户面前出现大约 5 毫秒的空白,然后重新出现来自新选择的麦克风的相同视频和音频

这里最重要的 3 个部分是:

  1. 使用取消发布旧发布者unpublishWebcamPublisher()
  2. 使用replaceTrack()方法更换麦克风
  3. 重新发布新的发布者this.openViduWebRTCService.publishWebcamPublisher();

尽管如此,一个很好的改进方法是消除在相机和麦克风未发布时发生的瞬间空白屏幕,原因是this.openViduWebRTCService.publishWebcamPublisher();

于 2021-12-19T14:45:55.260 回答