From 4dc98e327282c1e417841e94cf5aac54f32ffb9f Mon Sep 17 00:00:00 2001 From: Carlos Santos <4a.santos@gmail.com> Date: Thu, 4 May 2023 16:14:19 +0200 Subject: [PATCH] openvidu-components: Fixed switch camera on Android devices --- .../src/lib/services/device/device.service.ts | 12 ++--- .../lib/services/openvidu/openvidu.service.ts | 45 ++++++++++++------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/device/device.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/device/device.service.ts index aadc7028..e733569a 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/device/device.service.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/device/device.service.ts @@ -20,8 +20,8 @@ export class DeviceService { private devices: Device[]; private cameras: CustomDevice[] = []; private microphones: CustomDevice[] = []; - private cameraSelected: CustomDevice | null; - private microphoneSelected: CustomDevice | null; + private cameraSelected: CustomDevice | undefined; + private microphoneSelected: CustomDevice | undefined; private log: ILogger; private videoDevicesEnabled: boolean = true; private audioDevicesEnabled: boolean = true; @@ -169,11 +169,11 @@ export class DeviceService { return this.hasAudioDeviceAvailable() && this._isAudioMuted; } - getCameraSelected(): CustomDevice | null { + getCameraSelected(): CustomDevice | undefined { return this.cameraSelected; } - getMicrophoneSelected(): CustomDevice | null { + getMicrophoneSelected(): CustomDevice | undefined { return this.microphoneSelected; } @@ -228,8 +228,8 @@ export class DeviceService { this.devices = []; this.cameras = []; this.microphones = []; - this.cameraSelected = null; - this.microphoneSelected = null; + this.cameraSelected = undefined; + this.microphoneSelected = undefined; this.videoDevicesEnabled = true; this.audioDevicesEnabled = true; } diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/openvidu/openvidu.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/openvidu/openvidu.service.ts index 06cfe82b..ff4745b3 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/openvidu/openvidu.service.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/openvidu/openvidu.service.ts @@ -582,29 +582,29 @@ export class OpenViduService { } private async createMediaStream(pp: PublisherProperties): Promise { - let mediaStream: MediaStream; - const isFirefoxPlatform = this.platformService.isFirefox(); - const isReplacingAudio = !!pp.audioSource; - const isReplacingVideo = !!pp.videoSource; + const currentCameraSelected = this.deviceService.getCameraSelected(); + const currentMicSelected = this.deviceService.getMicrophoneSelected(); + const isReplacingAudio = Boolean(pp.audioSource); + const isReplacingVideo = Boolean(pp.videoSource); try { - mediaStream = await this.OV.getUserMedia(pp); + const trackType = isReplacingAudio ? 'audio' : 'video'; + this.forceStopMediaTracks(this.participantService.getMyCameraPublisher().stream.getMediaStream(), trackType); + return this.OV.getUserMedia(pp); } catch (error) { + console.warn('Error creating MediaStream', error); if ((error).name === OpenViduErrorName.DEVICE_ACCESS_DENIED) { - if (isFirefoxPlatform) { - this.log.w('The device requested is not available. Restoring the older one'); - // The track requested is not available so we are getting the old tracks ids for recovering the track - if (isReplacingVideo) { - pp.videoSource = this.deviceService.getCameraSelected().device; - } else if (isReplacingAudio) { - pp.audioSource = this.deviceService.getMicrophoneSelected().device; - } - mediaStream = await this.OV.getUserMedia(pp); - // TODO show error alert informing that the new device is not available + this.log.w('The device requested is not available. Restoring the older one'); + // The track requested is not available so we are getting the old tracks ids for recovering the track + if (isReplacingVideo) { + pp.videoSource = currentCameraSelected?.device; + } else if (isReplacingAudio) { + pp.audioSource = currentMicSelected?.device; } + // TODO show error alert informing that the new device is not available + return this.OV.getUserMedia(pp); } - } finally { - return mediaStream; + throw error; } } @@ -663,4 +663,15 @@ export class OpenViduService { private cleanConnectionData(data: string): string { return data.split('%/%')[0]; } + + private forceStopMediaTracks(stream: MediaStream, type: 'video' | 'audio'): void { + if (stream) { + stream.getTracks().forEach((track) => { + if (track.kind === type) { + track.stop(); + track.enabled = false; + } + }); + } + } }