From 3fdca94afbe178a997486a0b9b6607d4db05b007 Mon Sep 17 00:00:00 2001 From: kharhamel Date: Fri, 23 Oct 2020 16:16:30 +0200 Subject: [PATCH 1/2] refactor: move jitsi creation to a dedicated and cleaned some type in mediaManager --- front/src/Phaser/Game/GameScene.ts | 55 ++--------------------- front/src/Phaser/Player/Animation.ts | 1 - front/src/WebRtc/JitsiFactory.ts | 57 +++++++++++++++++++++++ front/src/WebRtc/MediaManager.ts | 67 +++++----------------------- 4 files changed, 73 insertions(+), 107 deletions(-) create mode 100644 front/src/WebRtc/JitsiFactory.ts diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 8119d268..bfc6402e 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -12,7 +12,6 @@ import {CurrentGamerInterface, hasMovedEventName, Player} from "../Player/Player import { DEBUG_MODE, JITSI_PRIVATE_MODE, - JITSI_URL, POSITION_DELAY, RESOLUTION, ZOOM_LEVEL @@ -23,7 +22,6 @@ import { ITiledMapLayerProperty, ITiledMapObject, ITiledTileSet } from "../Map/ITiledMap"; -import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character"; import {AddPlayerInterface} from "./AddPlayerInterface"; import {PlayerAnimationNames} from "../Player/Animation"; import {PlayerMovement} from "./PlayerMovement"; @@ -32,7 +30,7 @@ import {RemotePlayer} from "../Entity/RemotePlayer"; import {Queue} from 'queue-typescript'; import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer"; import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene"; -import {loadAllLayers, loadCustomTexture, loadObject, loadPlayerCharacters} from "../Entity/body_character"; +import {loadAllLayers, loadObject, loadPlayerCharacters} from "../Entity/body_character"; import {CenterListener, layoutManager, LayoutMode} from "../../WebRtc/LayoutManager"; import Texture = Phaser.Textures.Texture; import Sprite = Phaser.GameObjects.Sprite; @@ -55,11 +53,7 @@ import {UserMessageManager} from "../../Administration/UserMessageManager"; import {ConsoleGlobalMessageManager} from "../../Administration/ConsoleGlobalMessageManager"; import {ResizableScene} from "../Login/ResizableScene"; import {Room} from "../../Connexion/Room"; - - -export enum Textures { - Player = "male1" -} +import {jitsiFactory} from "../../WebRtc/JitsiFactory"; export interface GameSceneInitInterface { initPosition: PointInterface|null @@ -147,8 +141,6 @@ export class GameScene extends ResizableScene implements CenterListener { private outlinedItem: ActionableItem|null = null; private userInputManager!: UserInputManager; - private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any - static createFromUrl(room: Room, mapUrlFile: string, gameSceneKey: string|null = null): GameScene { // We use the map URL as a key if (gameSceneKey === null) { @@ -1231,53 +1223,14 @@ export class GameScene extends ResizableScene implements CenterListener { } public startJitsi(roomName: string, jwt?: string): void { - CoWebsiteManager.insertCoWebsite((cowebsiteDiv => { - const domain = JITSI_URL; - const options = { - roomName: roomName, - jwt: jwt, - width: "100%", - height: "100%", - parentNode: cowebsiteDiv, - configOverwrite: { - prejoinPageEnabled: false - }, - interfaceConfigOverwrite: { - SHOW_CHROME_EXTENSION_BANNER: false, - MOBILE_APP_PROMO: false, - - HIDE_INVITE_MORE_HEADER: true, - - // Note: hiding brand does not seem to work, we probably need to put this on the server side. - SHOW_BRAND_WATERMARK: false, - SHOW_JITSI_WATERMARK: false, - SHOW_POWERED_BY: false, - SHOW_PROMOTIONAL_CLOSE_PAGE: false, - SHOW_WATERMARK_FOR_GUESTS: false, - - TOOLBAR_BUTTONS: [ - 'microphone', 'camera', 'closedcaptions', 'desktop', /*'embedmeeting',*/ 'fullscreen', - 'fodeviceselection', 'hangup', 'profile', 'chat', 'recording', - 'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand', - 'videoquality', 'filmstrip', /*'invite',*/ 'feedback', 'stats', 'shortcuts', - 'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', /*'security'*/ - ], - } - }; - if (!options.jwt) { - delete options.jwt; - } - this.jitsiApi = new (window as any).JitsiMeetExternalAPI(domain, options); // eslint-disable-line @typescript-eslint/no-explicit-any - this.jitsiApi.executeCommand('displayName', gameManager.getPlayerName()); - })); + jitsiFactory.start(roomName, gameManager.getPlayerName(), jwt); this.connection.setSilent(true); mediaManager.hideGameOverlay(); } public stopJitsi(): void { this.connection.setSilent(false); - this.jitsiApi?.dispose(); - CoWebsiteManager.closeCoWebsite(); + jitsiFactory.stop(); mediaManager.showGameOverlay(); } diff --git a/front/src/Phaser/Player/Animation.ts b/front/src/Phaser/Player/Animation.ts index 8ca7d671..471f6d5f 100644 --- a/front/src/Phaser/Player/Animation.ts +++ b/front/src/Phaser/Player/Animation.ts @@ -1,4 +1,3 @@ -import {Textures} from "../Game/GameScene"; export enum PlayerAnimationNames { WalkDown = 'down', diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts new file mode 100644 index 00000000..d4c4048d --- /dev/null +++ b/front/src/WebRtc/JitsiFactory.ts @@ -0,0 +1,57 @@ +import {CoWebsiteManager} from "./CoWebsiteManager"; +import {JITSI_URL} from "../Enum/EnvironmentVariable"; +declare const window:any; // eslint-disable-line @typescript-eslint/no-explicit-any + +const interfaceConfig = { + SHOW_CHROME_EXTENSION_BANNER: false, + MOBILE_APP_PROMO: false, + + HIDE_INVITE_MORE_HEADER: true, + + // Note: hiding brand does not seem to work, we probably need to put this on the server side. + SHOW_BRAND_WATERMARK: false, + SHOW_JITSI_WATERMARK: false, + SHOW_POWERED_BY: false, + SHOW_PROMOTIONAL_CLOSE_PAGE: false, + SHOW_WATERMARK_FOR_GUESTS: false, + + TOOLBAR_BUTTONS: [ + 'microphone', 'camera', 'closedcaptions', 'desktop', /*'embedmeeting',*/ 'fullscreen', + 'fodeviceselection', 'hangup', 'profile', 'chat', 'recording', + 'livestreaming', 'etherpad', 'sharedvideo', 'settings', 'raisehand', + 'videoquality', 'filmstrip', /*'invite',*/ 'feedback', 'stats', 'shortcuts', + 'tileview', 'videobackgroundblur', 'download', 'help', 'mute-everyone', /*'security'*/ + ], +}; + +class JitsiFactory { + private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any + public start(roomName: string, playerName:string, jwt?: string): void { + CoWebsiteManager.insertCoWebsite((cowebsiteDiv => { + const domain = JITSI_URL; + const options = { + roomName: roomName, + jwt: jwt, + width: "100%", + height: "100%", + parentNode: cowebsiteDiv, + configOverwrite: { + prejoinPageEnabled: false + }, + interfaceConfigOverwrite: interfaceConfig, + }; + if (!options.jwt) { + delete options.jwt; + } + this.jitsiApi = new window.JitsiMeetExternalAPI(domain, options); + this.jitsiApi.executeCommand('displayName', playerName); + })); + } + + public stop(): void { + this.jitsiApi?.dispose(); + CoWebsiteManager.closeCoWebsite(); + } +} + +export const jitsiFactory = new JitsiFactory(); \ No newline at end of file diff --git a/front/src/WebRtc/MediaManager.ts b/front/src/WebRtc/MediaManager.ts index 0cbfe123..557f12fb 100644 --- a/front/src/WebRtc/MediaManager.ts +++ b/front/src/WebRtc/MediaManager.ts @@ -1,5 +1,6 @@ import {DivImportance, layoutManager} from "./LayoutManager"; import {HtmlUtils} from "./HtmlUtils"; +declare const navigator:any; // eslint-disable-line @typescript-eslint/no-explicit-any const videoConstraint: boolean|MediaTrackConstraints = { width: { ideal: 1280 }, @@ -245,15 +246,11 @@ export class MediaManager { } private _startScreenCapture() { - // getDisplayMedia was moved to mediaDevices in 2018. Typescript definitions are not up to date yet. - // See: https://github.com/w3c/mediacapture-screen-share/pull/86 - // https://github.com/microsoft/TypeScript/issues/31821 - if ((navigator as any).getDisplayMedia) { // eslint-disable-line @typescript-eslint/no-explicit-any - return (navigator as any).getDisplayMedia({video: true}); // eslint-disable-line @typescript-eslint/no-explicit-any - } else if ((navigator.mediaDevices as any).getDisplayMedia) { // eslint-disable-line @typescript-eslint/no-explicit-any - return (navigator.mediaDevices as any).getDisplayMedia({video: true}); // eslint-disable-line @typescript-eslint/no-explicit-any + if (navigator.getDisplayMedia) { + return navigator.getDisplayMedia({video: true}); + } else if (navigator.mediaDevices.getDisplayMedia) { + return navigator.mediaDevices.getDisplayMedia({video: true}); } else { - //return navigator.mediaDevices.getUserMedia(({video: {mediaSource: 'screen'}} as any)); return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars reject("error sharing screen"); }); @@ -336,12 +333,6 @@ export class MediaManager { return this.getCamera(); } - /** - * - * @param userId - * @param reportCallBack - * @param userName - */ addActiveVideo(userId: string, reportCallBack: ReportCallback|undefined, userName: string = ""){ this.webrtcInAudio.play(); @@ -373,13 +364,8 @@ export class MediaManager { this.remoteVideo.set(userId, this.getElementByIdOrFail(userId)); } - - /** - * - * @param userId - */ + addScreenSharingActiveVideo(userId: string, divImportance: DivImportance = DivImportance.Important){ - //this.webrtcInAudio.play(); userId = `screen-sharing-${userId}`; const html = ` @@ -392,11 +378,7 @@ export class MediaManager { this.remoteVideo.set(userId, this.getElementByIdOrFail(userId)); } - - /** - * - * @param userId - */ + disabledMicrophoneByUserId(userId: number){ const element = document.getElementById(`microphone-${userId}`); if(!element){ @@ -404,11 +386,7 @@ export class MediaManager { } element.classList.add('active') } - - /** - * - * @param userId - */ + enabledMicrophoneByUserId(userId: number){ const element = document.getElementById(`microphone-${userId}`); if(!element){ @@ -416,11 +394,7 @@ export class MediaManager { } element.classList.remove('active') } - - /** - * - * @param userId - */ + disabledVideoByUserId(userId: number) { let element = document.getElementById(`${userId}`); if (element) { @@ -431,11 +405,7 @@ export class MediaManager { element.style.display = "block"; } } - - /** - * - * @param userId - */ + enabledVideoByUserId(userId: number){ let element = document.getElementById(`${userId}`); if(element){ @@ -447,11 +417,6 @@ export class MediaManager { } } - /** - * - * @param userId - * @param stream - */ addStreamRemoteVideo(userId: string, stream : MediaStream){ const remoteVideo = this.remoteVideo.get(userId); if (remoteVideo === undefined) { @@ -468,11 +433,7 @@ export class MediaManager { this.addStreamRemoteVideo(`screen-sharing-${userId}`, stream); } - - /** - * - * @param userId - */ + removeActiveVideo(userId: string){ layoutManager.remove(userId); this.remoteVideo.delete(userId); @@ -522,11 +483,7 @@ export class MediaManager { const connnectingSpinnerDiv = element.getElementsByClassName('connecting-spinner').item(0) as HTMLDivElement|null; return connnectingSpinnerDiv; } - - /** - * - * @param str - */ + private getColorByString(str: String) : String|null { let hash = 0; if (str.length === 0) return null; From 00ad28f084e86bd8fa1a898858dbb2f9cd2f4992 Mon Sep 17 00:00:00 2001 From: kharhamel Date: Fri, 23 Oct 2020 17:00:56 +0200 Subject: [PATCH 2/2] feat: jitsi no start with audio or video muted when needed --- front/src/WebRtc/JitsiFactory.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/front/src/WebRtc/JitsiFactory.ts b/front/src/WebRtc/JitsiFactory.ts index d4c4048d..d0658218 100644 --- a/front/src/WebRtc/JitsiFactory.ts +++ b/front/src/WebRtc/JitsiFactory.ts @@ -1,5 +1,6 @@ import {CoWebsiteManager} from "./CoWebsiteManager"; import {JITSI_URL} from "../Enum/EnvironmentVariable"; +import {mediaManager} from "./MediaManager"; declare const window:any; // eslint-disable-line @typescript-eslint/no-explicit-any const interfaceConfig = { @@ -36,6 +37,8 @@ class JitsiFactory { height: "100%", parentNode: cowebsiteDiv, configOverwrite: { + startWithAudioMuted: !mediaManager.constraintsMedia.audio, + startWithVideoMuted: mediaManager.constraintsMedia.video === false, prejoinPageEnabled: false }, interfaceConfigOverwrite: interfaceConfig,