From c739037bc4206c2421440669e8c6f8466b455878 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 31 Aug 2020 14:54:52 +0200 Subject: [PATCH 1/2] Camera was not properly closed in EnableCameraScene --- front/src/Phaser/Login/EnableCameraScene.ts | 3 ++ front/src/WebRtc/MediaManager.ts | 36 ++++++++++++++------- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/front/src/Phaser/Login/EnableCameraScene.ts b/front/src/Phaser/Login/EnableCameraScene.ts index 7e631b6b..6fc1cd54 100644 --- a/front/src/Phaser/Login/EnableCameraScene.ts +++ b/front/src/Phaser/Login/EnableCameraScene.ts @@ -266,6 +266,9 @@ export class EnableCameraScene extends Phaser.Scene { this.soundMeter.stop(); window.removeEventListener('resize', this.repositionCallback); + mediaManager.stopCamera(); + mediaManager.stopMicrophone(); + // Do we have a start URL in the address bar? If so, let's redirect to this address const instanceAndMapUrl = this.findMapUrl(); if (instanceAndMapUrl !== null) { diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index a043e51e..ebd2a585 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -127,7 +127,7 @@ export class MediaManager { } } - showGameOverlay(){ + public showGameOverlay(){ const gameOverlay = this.getElementByIdOrFail('game-overlay'); gameOverlay.classList.add('active'); } @@ -148,11 +148,7 @@ export class MediaManager { this.cinemaBtn.classList.add("disabled"); this.constraintsMedia.video = false; this.myCamVideo.srcObject = null; - if (this.localStream) { - this.localStream.getVideoTracks().forEach((MediaStreamTrack: MediaStreamTrack) => { - MediaStreamTrack.stop(); - }); - } + this.stopCamera(); this.getCamera().then((stream) => { this.triggerUpdatedLocalStreamCallbacks(stream); }); @@ -173,11 +169,7 @@ export class MediaManager { this.microphone.style.display = "none"; this.microphoneBtn.classList.add("disabled"); this.constraintsMedia.audio = false; - if(this.localStream) { - this.localStream.getAudioTracks().forEach((MediaStreamTrack: MediaStreamTrack) => { - MediaStreamTrack.stop(); - }); - } + this.stopMicrophone(); this.getCamera().then((stream) => { this.triggerUpdatedLocalStreamCallbacks(stream); }); @@ -287,6 +279,28 @@ export class MediaManager { } } + /** + * Stops the camera from filming + */ + public stopCamera(): void { + if (this.localStream) { + for (const track of this.localStream.getVideoTracks()) { + track.stop(); + } + } + } + + /** + * Stops the microphone from listening + */ + public stopMicrophone(): void { + if (this.localStream) { + for (const track of this.localStream.getAudioTracks()) { + track.stop(); + } + } + } + setCamera(id: string): Promise { let video = this.constraintsMedia.video; if (typeof(video) === 'boolean' || video === undefined) { From 634eecd42a7d1d03528a5f703bdb4b6d79e34288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20N=C3=A9grier?= Date: Mon, 31 Aug 2020 15:21:05 +0200 Subject: [PATCH 2/2] Fixing issue when both mic and cam are stopped --- front/src/WebRtc/MediaManager.ts | 29 ++++++++++++++++++--------- front/src/WebRtc/ScreenSharingPeer.ts | 6 +++--- front/src/WebRtc/SimplePeer.ts | 17 ++++++++++------ front/src/WebRtc/VideoPeer.ts | 2 +- 4 files changed, 34 insertions(+), 20 deletions(-) diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index ebd2a585..e8cb080d 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -7,9 +7,9 @@ const videoConstraint: boolean|MediaTrackConstraints = { facingMode: "user" }; -type UpdatedLocalStreamCallback = (media: MediaStream) => void; -type StartScreenSharingCallback = (media: MediaStream) => void; -type StopScreenSharingCallback = (media: MediaStream) => void; +export type UpdatedLocalStreamCallback = (media: MediaStream|null) => void; +export type StartScreenSharingCallback = (media: MediaStream) => void; +export type StopScreenSharingCallback = (media: MediaStream) => void; // TODO: Split MediaManager in 2 classes: MediaManagerUI (in charge of HTML) and MediaManager (singleton in charge of the camera only) // TODO: verify that microphone event listeners are not triggered plenty of time NOW (since MediaManager is created many times!!!!) @@ -109,7 +109,7 @@ export class MediaManager { this.updatedLocalStreamCallBacks.delete(callback); } - private triggerUpdatedLocalStreamCallbacks(stream: MediaStream): void { + private triggerUpdatedLocalStreamCallbacks(stream: MediaStream|null): void { for (const callback of this.updatedLocalStreamCallBacks) { callback(stream); } @@ -142,16 +142,20 @@ export class MediaManager { }); } - private disableCamera() { + private async disableCamera() { this.cinemaClose.style.display = "block"; this.cinema.style.display = "none"; this.cinemaBtn.classList.add("disabled"); this.constraintsMedia.video = false; this.myCamVideo.srcObject = null; this.stopCamera(); - this.getCamera().then((stream) => { + + if (this.constraintsMedia.audio !== false) { + const stream = await this.getCamera(); this.triggerUpdatedLocalStreamCallbacks(stream); - }); + } else { + this.triggerUpdatedLocalStreamCallbacks(null); + } } private enableMicrophone() { @@ -159,20 +163,25 @@ export class MediaManager { this.microphone.style.display = "block"; this.microphoneBtn.classList.remove("disabled"); this.constraintsMedia.audio = true; + this.getCamera().then((stream) => { this.triggerUpdatedLocalStreamCallbacks(stream); }); } - private disableMicrophone() { + private async disableMicrophone() { this.microphoneClose.style.display = "block"; this.microphone.style.display = "none"; this.microphoneBtn.classList.add("disabled"); this.constraintsMedia.audio = false; this.stopMicrophone(); - this.getCamera().then((stream) => { + + if (this.constraintsMedia.video !== false) { + const stream = await this.getCamera(); this.triggerUpdatedLocalStreamCallbacks(stream); - }); + } else { + this.triggerUpdatedLocalStreamCallbacks(null); + } } private enableScreenSharing() { diff --git a/front/src/WebRtc/ScreenSharingPeer.ts b/front/src/WebRtc/ScreenSharingPeer.ts index 35f43201..3f43a70f 100644 --- a/front/src/WebRtc/ScreenSharingPeer.ts +++ b/front/src/WebRtc/ScreenSharingPeer.ts @@ -70,7 +70,7 @@ export class ScreenSharingPeer extends Peer { } private sendWebrtcScreenSharingSignal(data: unknown) { - console.log("sendWebrtcScreenSharingSignal", data); + //console.log("sendWebrtcScreenSharingSignal", data); try { this.connection.sendWebrtcScreenSharingSignal(data, this.userId); }catch (e) { @@ -82,8 +82,8 @@ export class ScreenSharingPeer extends Peer { * Sends received stream to screen. */ private stream(stream?: MediaStream) { - console.log(`ScreenSharingPeer::stream => ${this.userId}`, stream); - console.log(`stream => ${this.userId} => `, stream); + //console.log(`ScreenSharingPeer::stream => ${this.userId}`, stream); + //console.log(`stream => ${this.userId} => `, stream); if(!stream){ mediaManager.removeActiveScreenSharingVideo(this.userId); this.isReceivingStream = false; diff --git a/front/src/WebRtc/SimplePeer.ts b/front/src/WebRtc/SimplePeer.ts index 3acd65c5..f388b2ec 100644 --- a/front/src/WebRtc/SimplePeer.ts +++ b/front/src/WebRtc/SimplePeer.ts @@ -4,7 +4,12 @@ import { WebRtcSignalReceivedMessageInterface, WebRtcStartMessageInterface } from "../Connection"; -import { mediaManager } from "./MediaManager"; +import { + mediaManager, + StartScreenSharingCallback, + StopScreenSharingCallback, + UpdatedLocalStreamCallback +} from "./MediaManager"; import * as SimplePeerNamespace from "simple-peer"; import {ScreenSharingPeer} from "./ScreenSharingPeer"; import {VideoPeer} from "./VideoPeer"; @@ -32,9 +37,9 @@ export class SimplePeer { private PeerScreenSharingConnectionArray: Map = new Map(); private PeerConnectionArray: Map = new Map(); - private readonly sendLocalVideoStreamCallback: (media: MediaStream) => void; - private readonly sendLocalScreenSharingStreamCallback: (media: MediaStream) => void; - private readonly stopLocalScreenSharingStreamCallback: (media: MediaStream) => void; + private readonly sendLocalVideoStreamCallback: UpdatedLocalStreamCallback; + private readonly sendLocalScreenSharingStreamCallback: StartScreenSharingCallback; + private readonly stopLocalScreenSharingStreamCallback: StopScreenSharingCallback; private readonly peerConnectionListeners: Array = new Array(); constructor(Connection: Connection, WebRtcRoomId: string = "test-webrtc") { @@ -326,9 +331,9 @@ export class SimplePeer { } public sendLocalVideoStream(){ - this.Users.forEach((user: UserSimplePeerInterface) => { + for (const user of this.Users) { this.pushVideoToRemoteUser(user.userId); - }) + } } /** diff --git a/front/src/WebRtc/VideoPeer.ts b/front/src/WebRtc/VideoPeer.ts index ec7f2576..3ffe33e7 100644 --- a/front/src/WebRtc/VideoPeer.ts +++ b/front/src/WebRtc/VideoPeer.ts @@ -85,7 +85,7 @@ export class VideoPeer extends Peer { * Sends received stream to screen. */ private stream(stream?: MediaStream) { - console.log(`VideoPeer::stream => ${this.userId}`, stream); + //console.log(`VideoPeer::stream => ${this.userId}`, stream); if(!stream){ mediaManager.disabledVideoByUserId(this.userId); mediaManager.disabledMicrophoneByUserId(this.userId);