Merge pull request #376 from thecodingmachine/windows-focus-blur-camera
Switch off camera when user is not focused on WorkAdventure windows
This commit is contained in:
commit
b0c54776b1
@ -317,7 +317,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
// Let's alter browser history
|
// Let's alter browser history
|
||||||
let path = this.room.id;
|
let path = this.room.id;
|
||||||
if (this.room.hash) {
|
if (this.room.hash) {
|
||||||
path += '#'+this.room.hash;
|
path += '#' + this.room.hash;
|
||||||
}
|
}
|
||||||
window.history.pushState({}, 'WorkAdventure', path);
|
window.history.pushState({}, 'WorkAdventure', path);
|
||||||
|
|
||||||
@ -906,6 +906,7 @@ export class GameScene extends ResizableScene implements CenterListener {
|
|||||||
* @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
* @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
||||||
*/
|
*/
|
||||||
update(time: number, delta: number) : void {
|
update(time: number, delta: number) : void {
|
||||||
|
mediaManager.setLastUpdateScene();
|
||||||
this.currentTick = time;
|
this.currentTick = time;
|
||||||
this.CurrentPlayer.moveUser(delta);
|
this.CurrentPlayer.moveUser(delta);
|
||||||
|
|
||||||
|
@ -40,6 +40,12 @@ export class MediaManager {
|
|||||||
private cinemaBtn: HTMLDivElement;
|
private cinemaBtn: HTMLDivElement;
|
||||||
private monitorBtn: HTMLDivElement;
|
private monitorBtn: HTMLDivElement;
|
||||||
|
|
||||||
|
private previousConstraint : MediaStreamConstraints;
|
||||||
|
private focused : boolean = true;
|
||||||
|
|
||||||
|
private lastUpdateScene : Date = new Date();
|
||||||
|
private setTimeOutlastUpdateScene? : NodeJS.Timeout;
|
||||||
|
|
||||||
private discussionManager: DiscussionManager;
|
private discussionManager: DiscussionManager;
|
||||||
|
|
||||||
private userInputManager?: UserInputManager;
|
private userInputManager?: UserInputManager;
|
||||||
@ -98,9 +104,35 @@ export class MediaManager {
|
|||||||
//update tracking
|
//update tracking
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia));
|
||||||
|
this.pingCameraStatus();
|
||||||
|
|
||||||
|
this.checkActiveUser();
|
||||||
|
|
||||||
this.discussionManager = new DiscussionManager(this,'');
|
this.discussionManager = new DiscussionManager(this,'');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public setLastUpdateScene(){
|
||||||
|
this.lastUpdateScene = new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
public blurCamera() {
|
||||||
|
if(!this.focused){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.focused = false;
|
||||||
|
this.previousConstraint = JSON.parse(JSON.stringify(this.constraintsMedia));
|
||||||
|
this.disableCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
public focusCamera() {
|
||||||
|
if(this.focused){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.focused = true;
|
||||||
|
this.applyPreviousConfig();
|
||||||
|
}
|
||||||
|
|
||||||
public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void {
|
public onUpdateLocalStream(callback: UpdatedLocalStreamCallback): void {
|
||||||
this.updatedLocalStreamCallBacks.add(callback);
|
this.updatedLocalStreamCallBacks.add(callback);
|
||||||
}
|
}
|
||||||
@ -146,12 +178,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enableCamera() {
|
public enableCamera() {
|
||||||
if(!this.hasCamera){
|
this.enableCameraStyle();
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.cinemaClose.style.display = "none";
|
|
||||||
this.cinemaBtn.classList.remove("disabled");
|
|
||||||
this.cinema.style.display = "block";
|
|
||||||
this.constraintsMedia.video = videoConstraint;
|
this.constraintsMedia.video = videoConstraint;
|
||||||
this.getCamera().then((stream: MediaStream) => {
|
this.getCamera().then((stream: MediaStream) => {
|
||||||
this.triggerUpdatedLocalStreamCallbacks(stream);
|
this.triggerUpdatedLocalStreamCallbacks(stream);
|
||||||
@ -159,7 +186,8 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async disableCamera() {
|
public async disableCamera() {
|
||||||
this.disabledCameraView();
|
this.disableCameraStyle();
|
||||||
|
|
||||||
if (this.constraintsMedia.audio !== false) {
|
if (this.constraintsMedia.audio !== false) {
|
||||||
const stream = await this.getCamera();
|
const stream = await this.getCamera();
|
||||||
this.triggerUpdatedLocalStreamCallbacks(stream);
|
this.triggerUpdatedLocalStreamCallbacks(stream);
|
||||||
@ -168,19 +196,8 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private disabledCameraView(){
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
public enableMicrophone() {
|
public enableMicrophone() {
|
||||||
this.microphoneClose.style.display = "none";
|
this.enableMicrophoneStyle();
|
||||||
this.microphone.style.display = "block";
|
|
||||||
this.microphoneBtn.classList.remove("disabled");
|
|
||||||
this.constraintsMedia.audio = true;
|
this.constraintsMedia.audio = true;
|
||||||
|
|
||||||
this.getCamera().then((stream) => {
|
this.getCamera().then((stream) => {
|
||||||
@ -189,10 +206,7 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async disableMicrophone() {
|
public async disableMicrophone() {
|
||||||
this.microphoneClose.style.display = "block";
|
this.disableMicrophoneStyle();
|
||||||
this.microphone.style.display = "none";
|
|
||||||
this.microphoneBtn.classList.add("disabled");
|
|
||||||
this.constraintsMedia.audio = false;
|
|
||||||
this.stopMicrophone();
|
this.stopMicrophone();
|
||||||
|
|
||||||
if (this.constraintsMedia.video !== false) {
|
if (this.constraintsMedia.video !== false) {
|
||||||
@ -203,6 +217,52 @@ export class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private applyPreviousConfig() {
|
||||||
|
this.constraintsMedia = this.previousConstraint;
|
||||||
|
if(!this.constraintsMedia.video){
|
||||||
|
this.disableCameraStyle();
|
||||||
|
}else{
|
||||||
|
this.enableCameraStyle();
|
||||||
|
}
|
||||||
|
if(!this.constraintsMedia.audio){
|
||||||
|
this.disableMicrophoneStyle()
|
||||||
|
}else{
|
||||||
|
this.enableMicrophoneStyle()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getCamera().then((stream: MediaStream) => {
|
||||||
|
this.triggerUpdatedLocalStreamCallbacks(stream);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private enableCameraStyle(){
|
||||||
|
this.cinemaClose.style.display = "none";
|
||||||
|
this.cinemaBtn.classList.remove("disabled");
|
||||||
|
this.cinema.style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
|
private disableCameraStyle(){
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private enableMicrophoneStyle(){
|
||||||
|
this.microphoneClose.style.display = "none";
|
||||||
|
this.microphone.style.display = "block";
|
||||||
|
this.microphoneBtn.classList.remove("disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
private disableMicrophoneStyle(){
|
||||||
|
this.microphoneClose.style.display = "block";
|
||||||
|
this.microphone.style.display = "none";
|
||||||
|
this.microphoneBtn.classList.add("disabled");
|
||||||
|
this.constraintsMedia.audio = false;
|
||||||
|
}
|
||||||
|
|
||||||
private enableScreenSharing() {
|
private enableScreenSharing() {
|
||||||
this.monitorClose.style.display = "none";
|
this.monitorClose.style.display = "none";
|
||||||
this.monitor.style.display = "block";
|
this.monitor.style.display = "block";
|
||||||
@ -285,7 +345,7 @@ export class MediaManager {
|
|||||||
|
|
||||||
return this.getLocalStream().catch(() => {
|
return this.getLocalStream().catch(() => {
|
||||||
console.info('Error get camera, trying with video option at null');
|
console.info('Error get camera, trying with video option at null');
|
||||||
this.disabledCameraView();
|
this.disableCameraStyle();
|
||||||
return this.getLocalStream().then((stream : MediaStream) => {
|
return this.getLocalStream().then((stream : MediaStream) => {
|
||||||
this.hasCamera = false;
|
this.hasCamera = false;
|
||||||
return stream;
|
return stream;
|
||||||
@ -594,6 +654,17 @@ export class MediaManager {
|
|||||||
public removeParticipant(userId: number|string){
|
public removeParticipant(userId: number|string){
|
||||||
this.discussionManager.removeParticipant(userId);
|
this.discussionManager.removeParticipant(userId);
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* For some reasons, the microphone muted icon or the stream is not always up to date.
|
||||||
|
* Here, every 30 seconds, we are "reseting" the streams and sending again the constraints to the other peers via the data channel again (see SimplePeer::pushVideoToRemoteUser)
|
||||||
|
**/
|
||||||
|
private pingCameraStatus(){
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('ping camera status');
|
||||||
|
this.triggerUpdatedLocalStreamCallbacks(this.localStream);
|
||||||
|
this.pingCameraStatus();
|
||||||
|
}, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
public addNewMessage(name: string, message: string, isMe: boolean = false){
|
public addNewMessage(name: string, message: string, isMe: boolean = false){
|
||||||
this.discussionManager.addMessage(name, message, isMe);
|
this.discussionManager.addMessage(name, message, isMe);
|
||||||
@ -615,6 +686,22 @@ export class MediaManager {
|
|||||||
public setUserInputManager(userInputManager : UserInputManager){
|
public setUserInputManager(userInputManager : UserInputManager){
|
||||||
this.discussionManager.setUserInputManager(userInputManager);
|
this.discussionManager.setUserInputManager(userInputManager);
|
||||||
}
|
}
|
||||||
|
//check if user is active
|
||||||
|
private checkActiveUser(){
|
||||||
|
if(this.setTimeOutlastUpdateScene){
|
||||||
|
clearTimeout(this.setTimeOutlastUpdateScene);
|
||||||
|
}
|
||||||
|
this.setTimeOutlastUpdateScene = setTimeout(() => {
|
||||||
|
const now = new Date();
|
||||||
|
//if last update is more of 10 sec
|
||||||
|
if( (now.getTime() - this.lastUpdateScene.getTime()) > 10000) {
|
||||||
|
this.blurCamera();
|
||||||
|
}else{
|
||||||
|
this.focusCamera();
|
||||||
|
}
|
||||||
|
this.checkActiveUser();
|
||||||
|
}, this.focused ? 10000 : 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const mediaManager = new MediaManager();
|
export const mediaManager = new MediaManager();
|
||||||
|
Loading…
Reference in New Issue
Block a user