From 749948a6d9bd442dd1ffeeb18e9457b7aa23192c Mon Sep 17 00:00:00 2001 From: Carlos Santos <4a.santos@gmail.com> Date: Wed, 1 Mar 2023 13:19:14 +0100 Subject: [PATCH] openvidu-components: Refactored openvidu and participant service - Moved toggle screen method to participant service --- .../components/session/session.component.ts | 7 +- .../lib/services/openvidu/openvidu.service.ts | 115 ++++-------------- .../participant/participant.service.ts | 70 +++++++++++ 3 files changed, 98 insertions(+), 94 deletions(-) diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.ts index 340899a3..63eb1407 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/components/session/session.component.ts @@ -299,9 +299,10 @@ export class SessionComponent implements OnInit, OnDestroy { private subscribeToConnectionCreatedAndDestroyed() { this.session.on('connectionCreated', async (event: ConnectionEvent) => { const connectionId = event.connection?.connectionId; - const nickname: string = this.participantService.getNicknameFromConnectionData(event.connection.data); + const newNickname: string = this.participantService.getNicknameFromConnectionData(event.connection.data); const isRemoteConnection: boolean = !this.openviduService.isMyOwnConnection(connectionId); - const isCameraConnection: boolean = !nickname?.includes(`_${VideoType.SCREEN}`); + const isCameraConnection: boolean = !newNickname?.includes(`_${VideoType.SCREEN}`); + const nickname = this.participantService.getMyNickname(); const data = event.connection?.data; if (isRemoteConnection && isCameraConnection) { @@ -309,7 +310,7 @@ export class SessionComponent implements OnInit, OnDestroy { this.participantService.addRemoteConnection(connectionId, data, null); //Sending nicnkanme signal to new participants - if (this.openviduService.needSendNicknameSignal()) { + if (this.openviduService.needSendNicknameSignal(nickname)) { const data = { clientData: this.participantService.getMyNickname() }; await this.openviduService.sendSignal(Signal.NICKNAME_CHANGED, [event.connection], data); } 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 ae1ade92..f3fddb80 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 @@ -11,8 +11,6 @@ import { Stream } from 'openvidu-browser'; -import { LoggerService } from '../logger/logger.service'; - import { BehaviorSubject, Observable } from 'rxjs'; import { CameraType } from '../../models/device.model'; import { ILogger } from '../../models/logger.model'; @@ -21,6 +19,7 @@ import { Signal } from '../../models/signal.model'; import { ScreenType, VideoType } from '../../models/video-type.model'; import { OpenViduAngularConfigService } from '../config/openvidu-angular.config.service'; import { DeviceService } from '../device/device.service'; +import { LoggerService } from '../logger/logger.service'; import { ParticipantService } from '../participant/participant.service'; import { PlatformService } from '../platform/platform.service'; @@ -215,7 +214,6 @@ export class OpenViduService { }); return this.webcamSession.connection.connectionId; - // this.participantService.setMyCameraConnectionId(this.webcamSession.connection.connectionId); } /** @@ -291,11 +289,29 @@ export class OpenViduService { /** * @internal */ - private async initPublisher(properties: PublisherProperties, targetElement?: string | HTMLElement): Promise { + private initPublisher(properties: PublisherProperties, targetElement?: string | HTMLElement): Promise { this.log.d('Initializing publisher with properties: ', properties); return this.OV.initPublisherAsync(targetElement, properties); } + /** + * @internal + * @param hasAudio + * @returns + */ + initScreenPublisher(hasAudio: boolean): Promise { + const hasAudioDevicesAvailable = this.deviceService.hasAudioDeviceAvailable(); + + const properties: PublisherProperties = { + videoSource: ScreenType.SCREEN, + audioSource: hasAudioDevicesAvailable ? this.deviceService.getMicrophoneSelected().device : false, + publishVideo: true, + publishAudio: hasAudio && hasAudioDevicesAvailable, + mirror: false + }; + return this.initPublisher(properties); + } + /** * Publishes the publisher to the webcam Session * @param publisher @@ -350,7 +366,7 @@ export class OpenViduService { */ async publishVideo(publish: boolean): Promise { const participantService = this.injector.get(ParticipantService); - participantService.publishVideo(publish); + return participantService.publishVideo(publish); } /** @@ -362,92 +378,7 @@ export class OpenViduService { */ async toggleScreenshare() { const participantService = this.injector.get(ParticipantService); - - const screenPublisher = participantService.getMyScreenPublisher(); - const cameraPublisher = participantService.getMyCameraPublisher(); - const participantNickname = participantService.getMyNickname(); - const participantId = participantService.getLocalParticipant().id; - - if (participantService.haveICameraAndScreenActive()) { - // Disabling screenShare - participantService.disableScreenStream(); - participantService.updateLocalParticipant(); - this.unpublishScreen(screenPublisher); - } else if (participantService.isOnlyMyCameraActive()) { - // I only have the camera published - const hasAudioDevicesAvailable = this.deviceService.hasAudioDeviceAvailable(); - const willWebcamBePresent = participantService.isMyCameraActive() && participantService.isMyVideoActive(); - const hasAudio = willWebcamBePresent ? false : hasAudioDevicesAvailable && participantService.isMyAudioActive(); - - const properties: PublisherProperties = { - videoSource: ScreenType.SCREEN, - audioSource: hasAudioDevicesAvailable ? this.deviceService.getMicrophoneSelected().device : false, - publishVideo: true, - publishAudio: hasAudio, - mirror: false - }; - const screenPublisher = await this.initPublisher(properties); - - screenPublisher.once('accessAllowed', async () => { - // Listen to event fired when native stop button is clicked - screenPublisher.stream - .getMediaStream() - .getVideoTracks()[0] - .addEventListener('ended', async () => { - this.log.d('Clicked native stop button. Stopping screen sharing'); - await this.toggleScreenshare(); - }); - - // Enabling screenShare - participantService.activeMyScreenShare(screenPublisher); - - if (!this.isScreenSessionConnected()) { - await this.connectScreenSession(participantId, participantNickname); - } - await this.publishScreen(screenPublisher); - if (!participantService.isMyVideoActive()) { - // Disabling webcam - participantService.disableWebcamStream(); - participantService.updateLocalParticipant(); - this.unpublishCamera(cameraPublisher); - } - }); - - screenPublisher.once('accessDenied', (error: any) => { - return Promise.reject(error); - }); - } else { - // I only have my screenshare active and I have no camera or it is muted - const hasAudio = participantService.hasScreenAudioActive(); - - // Enable webcam - if (!this.isWebcamSessionConnected()) { - await this.connectWebcamSession(participantId, participantNickname); - } - await this.publishCamera(cameraPublisher); - this.publishAudioAux(cameraPublisher, hasAudio); - participantService.enableWebcamStream(); - - // Disabling screenshare - participantService.disableScreenStream(); - participantService.updateLocalParticipant(); - this.unpublishScreen(screenPublisher); - } - } - - /** - * @internal - * @deprecated - * - * TODO: Remove this method in release 2.28.0 - */ - private publishAudioAux(publisher: Publisher, value: boolean): void { - const participantService = this.injector.get(ParticipantService); - - if (!!publisher) { - publisher.publishAudio(value); - participantService.updateLocalParticipant(); - } + return participantService.toggleScreenshare(); } /** @@ -455,6 +386,8 @@ export class OpenViduService { * Publish or unpublish the audio stream (if available). * See openvidu-browser {@link https://docs.openvidu.io/en/stable/api/openvidu-browser/classes/Publisher.html#publishAudio publishAudio}. * @deprecated This method has been moved to ParticipantService + * + * TODO: Remove this method in release 2.28.0 */ publishAudio(publish: boolean): void { const participantService = this.injector.get(ParticipantService); diff --git a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/participant/participant.service.ts b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/participant/participant.service.ts index be43dd2c..d55a6c93 100644 --- a/openvidu-components-angular/projects/openvidu-angular/src/lib/services/participant/participant.service.ts +++ b/openvidu-components-angular/projects/openvidu-angular/src/lib/services/participant/participant.service.ts @@ -117,6 +117,76 @@ export class ParticipantService { this.updateLocalParticipant(); } + /** + * Share or unshare the local participant screen. + * Hide the camera stream (while muted) when screen is sharing. + * + */ + async toggleScreenshare() { + + const screenPublisher = this.getMyScreenPublisher(); + const cameraPublisher = this.getMyCameraPublisher(); + const participantNickname = this.getMyNickname(); + const participantId = this.getLocalParticipant().id; + + if (this.haveICameraAndScreenActive()) { + // Disabling screenShare + this.disableScreenStream(); + this.updateLocalParticipant(); + this.openviduService.unpublishScreen(screenPublisher); + } else if (this.isOnlyMyCameraActive()) { + // I only have the camera published + const willWebcamBePresent = this.isMyCameraActive() && this.isMyVideoActive(); + const hasAudio = willWebcamBePresent ? false : this.isMyAudioActive(); + const screenPublisher = await this.openviduService.initScreenPublisher(hasAudio); + + screenPublisher.once('accessAllowed', async () => { + // Listen to event fired when native stop button is clicked + screenPublisher.stream + .getMediaStream() + .getVideoTracks()[0] + .addEventListener('ended', async () => { + this.log.d('Clicked native stop button. Stopping screen sharing'); + await this.toggleScreenshare(); + }); + + // Enabling screenShare + this.activeMyScreenShare(screenPublisher); + + if (!this.openviduService.isScreenSessionConnected()) { + await this.openviduService.connectScreenSession(participantId, participantNickname); + } + await this.openviduService.publishScreen(screenPublisher); + if (!this.isMyVideoActive()) { + // Disabling webcam + this.disableWebcamStream(); + this.updateLocalParticipant(); + this.openviduService.unpublishCamera(cameraPublisher); + } + }); + + screenPublisher.once('accessDenied', (error: any) => { + return Promise.reject(error); + }); + } else { + // I only have my screenshare active and I have no camera or it is muted + const hasAudio = this.hasScreenAudioActive(); + + // Enable webcam + if (!this.openviduService.isWebcamSessionConnected()) { + await this.openviduService.connectWebcamSession(participantId, participantNickname); + } + await this.openviduService.publishCamera(cameraPublisher); + this.publishAudioAux(cameraPublisher, hasAudio); + this.enableWebcamStream(); + + // Disabling screenshare + this.disableScreenStream(); + this.updateLocalParticipant(); + this.openviduService.unpublishScreen(screenPublisher); + } + } + /** * @internal */