Merge pull request #1034 from thecodingmachine/close_game_webcam_in_jitsi
Close game webcam when in Jitsi
This commit is contained in:
commit
5674b99734
@ -1475,6 +1475,8 @@ ${escapedMessage}
|
|||||||
mediaManager.addTriggerCloseJitsiFrameButton('close-jisi',() => {
|
mediaManager.addTriggerCloseJitsiFrameButton('close-jisi',() => {
|
||||||
this.stopJitsi();
|
this.stopJitsi();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.onVisibilityChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public stopJitsi(): void {
|
public stopJitsi(): void {
|
||||||
@ -1483,6 +1485,7 @@ ${escapedMessage}
|
|||||||
mediaManager.showGameOverlay();
|
mediaManager.showGameOverlay();
|
||||||
|
|
||||||
mediaManager.removeTriggerCloseJitsiFrameButton('close-jisi');
|
mediaManager.removeTriggerCloseJitsiFrameButton('close-jisi');
|
||||||
|
this.onVisibilityChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: put this into an 'orchestrator' scene (EntryScene?)
|
//todo: put this into an 'orchestrator' scene (EntryScene?)
|
||||||
@ -1519,6 +1522,12 @@ ${escapedMessage}
|
|||||||
}
|
}
|
||||||
|
|
||||||
private onVisibilityChange(): void {
|
private onVisibilityChange(): void {
|
||||||
|
// If the overlay is not displayed, we are in Jitsi. We don't need the webcam.
|
||||||
|
if (!mediaManager.isGameOverlayVisible()) {
|
||||||
|
mediaManager.blurCamera();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (document.visibilityState === 'visible') {
|
if (document.visibilityState === 'visible') {
|
||||||
mediaManager.focusCamera();
|
mediaManager.focusCamera();
|
||||||
} else {
|
} else {
|
||||||
|
@ -10,9 +10,10 @@ interface jitsiConfigInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getDefaultConfig = () : jitsiConfigInterface => {
|
const getDefaultConfig = () : jitsiConfigInterface => {
|
||||||
|
const constraints = mediaManager.getConstraintRequestedByUser();
|
||||||
return {
|
return {
|
||||||
startWithAudioMuted: !mediaManager.constraintsMedia.audio,
|
startWithAudioMuted: !constraints.audio,
|
||||||
startWithVideoMuted: mediaManager.constraintsMedia.video === false,
|
startWithVideoMuted: constraints.video === false,
|
||||||
prejoinPageEnabled: false
|
prejoinPageEnabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,7 +72,7 @@ class JitsiFactory {
|
|||||||
private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
private jitsiApi: any; // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||||
private audioCallback = this.onAudioChange.bind(this);
|
private audioCallback = this.onAudioChange.bind(this);
|
||||||
private videoCallback = this.onVideoChange.bind(this);
|
private videoCallback = this.onVideoChange.bind(this);
|
||||||
private previousConfigMeet? : jitsiConfigInterface;
|
private previousConfigMeet! : jitsiConfigInterface;
|
||||||
private jitsiScriptLoaded: boolean = false;
|
private jitsiScriptLoaded: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,32 +137,24 @@ class JitsiFactory {
|
|||||||
|
|
||||||
//restore previous config
|
//restore previous config
|
||||||
if(this.previousConfigMeet?.startWithAudioMuted){
|
if(this.previousConfigMeet?.startWithAudioMuted){
|
||||||
mediaManager.disableMicrophone();
|
await mediaManager.disableMicrophone();
|
||||||
}else{
|
}else{
|
||||||
mediaManager.enableMicrophone();
|
await mediaManager.enableMicrophone();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(this.previousConfigMeet?.startWithVideoMuted){
|
if(this.previousConfigMeet?.startWithVideoMuted){
|
||||||
mediaManager.disableCamera();
|
await mediaManager.disableCamera();
|
||||||
}else{
|
}else{
|
||||||
mediaManager.enableCamera();
|
await mediaManager.enableCamera();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private onAudioChange({muted}: {muted: boolean}): void {
|
private onAudioChange({muted}: {muted: boolean}): void {
|
||||||
if (muted && mediaManager.constraintsMedia.audio === true) {
|
this.previousConfigMeet.startWithAudioMuted = muted;
|
||||||
mediaManager.disableMicrophone();
|
|
||||||
} else if(!muted && mediaManager.constraintsMedia.audio === false) {
|
|
||||||
mediaManager.enableMicrophone();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private onVideoChange({muted}: {muted: boolean}): void {
|
private onVideoChange({muted}: {muted: boolean}): void {
|
||||||
if (muted && mediaManager.constraintsMedia.video !== false) {
|
this.previousConfigMeet.startWithVideoMuted = muted;
|
||||||
mediaManager.disableCamera();
|
|
||||||
} else if(!muted && mediaManager.constraintsMedia.video === false) {
|
|
||||||
mediaManager.enableCamera();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async loadJitsiScript(domain: string): Promise<void> {
|
private async loadJitsiScript(domain: string): Promise<void> {
|
||||||
|
@ -155,6 +155,13 @@ export class MediaManager {
|
|||||||
this.disableCamera();
|
this.disableCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the constraint that the user wants (independently of the visibility / jitsi state...)
|
||||||
|
*/
|
||||||
|
public getConstraintRequestedByUser(): MediaStreamConstraints {
|
||||||
|
return this.previousConstraint ?? this.constraintsMedia;
|
||||||
|
}
|
||||||
|
|
||||||
public focusCamera() {
|
public focusCamera() {
|
||||||
if(this.focused){
|
if(this.focused){
|
||||||
return;
|
return;
|
||||||
@ -197,7 +204,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public showGameOverlay(){
|
public showGameOverlay(): void {
|
||||||
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
||||||
gameOverlay.classList.add('active');
|
gameOverlay.classList.add('active');
|
||||||
|
|
||||||
@ -208,7 +215,7 @@ export class MediaManager {
|
|||||||
buttonCloseFrame.removeEventListener('click', functionTrigger);
|
buttonCloseFrame.removeEventListener('click', functionTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
public hideGameOverlay(){
|
public hideGameOverlay(): void {
|
||||||
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
||||||
gameOverlay.classList.remove('active');
|
gameOverlay.classList.remove('active');
|
||||||
|
|
||||||
@ -219,6 +226,11 @@ export class MediaManager {
|
|||||||
buttonCloseFrame.addEventListener('click', functionTrigger);
|
buttonCloseFrame.addEventListener('click', functionTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public isGameOverlayVisible(): boolean {
|
||||||
|
const gameOverlay = HtmlUtils.getElementByIdOrFail('game-overlay');
|
||||||
|
return gameOverlay.classList.contains('active');
|
||||||
|
}
|
||||||
|
|
||||||
public updateCameraQuality(value: number) {
|
public updateCameraQuality(value: number) {
|
||||||
this.enableCameraStyle();
|
this.enableCameraStyle();
|
||||||
const newVideoConstraint = JSON.parse(JSON.stringify(videoConstraint));
|
const newVideoConstraint = JSON.parse(JSON.stringify(videoConstraint));
|
||||||
@ -230,29 +242,32 @@ export class MediaManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public enableCamera() {
|
public async enableCamera() {
|
||||||
this.constraintsMedia.video = videoConstraint;
|
this.constraintsMedia.video = videoConstraint;
|
||||||
|
|
||||||
this.getCamera().then((stream: MediaStream) => {
|
try {
|
||||||
|
const stream = await this.getCamera()
|
||||||
//TODO show error message tooltip upper of camera button
|
//TODO show error message tooltip upper of camera button
|
||||||
//TODO message : please check camera permission of your navigator
|
//TODO message : please check camera permission of your navigator
|
||||||
if(stream.getVideoTracks().length === 0) {
|
if(stream.getVideoTracks().length === 0) {
|
||||||
throw Error('Video track is empty, please check camera permission of your navigator')
|
throw new Error('Video track is empty, please check camera permission of your navigator')
|
||||||
}
|
}
|
||||||
this.enableCameraStyle();
|
this.enableCameraStyle();
|
||||||
this.triggerUpdatedLocalStreamCallbacks(stream);
|
this.triggerUpdatedLocalStreamCallbacks(stream);
|
||||||
}).catch((err) => {
|
} catch(err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.disableCameraStyle();
|
this.disableCameraStyle();
|
||||||
|
this.stopCamera();
|
||||||
|
|
||||||
layoutManager.addInformation('warning', 'Camera access denied. Click here and check navigators permissions.', () => {
|
layoutManager.addInformation('warning', 'Camera access denied. Click here and check navigators permissions.', () => {
|
||||||
this.showHelpCameraSettingsCallBack();
|
this.showHelpCameraSettingsCallBack();
|
||||||
}, this.userInputManager);
|
}, this.userInputManager);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async disableCamera() {
|
public async disableCamera() {
|
||||||
this.disableCameraStyle();
|
this.disableCameraStyle();
|
||||||
|
this.stopCamera();
|
||||||
|
|
||||||
if (this.constraintsMedia.audio !== false) {
|
if (this.constraintsMedia.audio !== false) {
|
||||||
const stream = await this.getCamera();
|
const stream = await this.getCamera();
|
||||||
@ -262,25 +277,27 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enableMicrophone() {
|
public async enableMicrophone() {
|
||||||
this.constraintsMedia.audio = audioConstraint;
|
this.constraintsMedia.audio = audioConstraint;
|
||||||
|
|
||||||
this.getCamera().then((stream) => {
|
try {
|
||||||
|
const stream = await this.getCamera();
|
||||||
|
|
||||||
//TODO show error message tooltip upper of camera button
|
//TODO show error message tooltip upper of camera button
|
||||||
//TODO message : please check microphone permission of your navigator
|
//TODO message : please check microphone permission of your navigator
|
||||||
if(stream.getAudioTracks().length === 0) {
|
if (stream.getAudioTracks().length === 0) {
|
||||||
throw Error('Audio track is empty, please check microphone permission of your navigator')
|
throw Error('Audio track is empty, please check microphone permission of your navigator')
|
||||||
}
|
}
|
||||||
this.enableMicrophoneStyle();
|
this.enableMicrophoneStyle();
|
||||||
this.triggerUpdatedLocalStreamCallbacks(stream);
|
this.triggerUpdatedLocalStreamCallbacks(stream);
|
||||||
}).catch((err) => {
|
} catch(err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.disableMicrophoneStyle();
|
this.disableMicrophoneStyle();
|
||||||
|
|
||||||
layoutManager.addInformation('warning', 'Microphone access denied. Click here and check navigators permissions.', () => {
|
layoutManager.addInformation('warning', 'Microphone access denied. Click here and check navigators permissions.', () => {
|
||||||
this.showHelpCameraSettingsCallBack();
|
this.showHelpCameraSettingsCallBack();
|
||||||
}, this.userInputManager);
|
}, this.userInputManager);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async disableMicrophone() {
|
public async disableMicrophone() {
|
||||||
@ -325,7 +342,6 @@ export class MediaManager {
|
|||||||
this.cinemaBtn.classList.add("disabled");
|
this.cinemaBtn.classList.add("disabled");
|
||||||
this.constraintsMedia.video = false;
|
this.constraintsMedia.video = false;
|
||||||
this.myCamVideo.srcObject = null;
|
this.myCamVideo.srcObject = null;
|
||||||
this.stopCamera();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private enableMicrophoneStyle(){
|
private enableMicrophoneStyle(){
|
||||||
@ -436,6 +452,8 @@ export class MediaManager {
|
|||||||
return this.getLocalStream().catch((err) => {
|
return this.getLocalStream().catch((err) => {
|
||||||
console.info('Error get camera, trying with video option at null =>', err);
|
console.info('Error get camera, trying with video option at null =>', err);
|
||||||
this.disableCameraStyle();
|
this.disableCameraStyle();
|
||||||
|
this.stopCamera();
|
||||||
|
|
||||||
return this.getLocalStream().then((stream : MediaStream) => {
|
return this.getLocalStream().then((stream : MediaStream) => {
|
||||||
this.hasCamera = false;
|
this.hasCamera = false;
|
||||||
return stream;
|
return stream;
|
||||||
|
Loading…
Reference in New Issue
Block a user