New fictive user screen sharing

- Create new fictive user
 - Add new fictive user in WebRtc group
 - Add screen sharing video on left side
This commit is contained in:
Gregoire Parant 2020-06-08 09:20:36 +02:00 committed by David Négrier
parent 6c1b8122ef
commit 209057e3fc
3 changed files with 79 additions and 21 deletions

View File

@ -6,7 +6,7 @@ import {SetPlayerDetailsMessage} from "./Messages/SetPlayerDetailsMessage";
const SocketIo = require('socket.io-client'); const SocketIo = require('socket.io-client');
import Socket = SocketIOClient.Socket; import Socket = SocketIOClient.Socket;
import {PlayerAnimationNames} from "./Phaser/Player/Animation"; import {PlayerAnimationNames} from "./Phaser/Player/Animation";
import {UserSimplePeer} from "./WebRtc/SimplePeer"; import {UserSimplePeerInterface} from "./WebRtc/SimplePeer";
import {SignalData} from "simple-peer"; import {SignalData} from "simple-peer";
@ -72,7 +72,7 @@ export interface GroupCreatedUpdatedMessageInterface {
export interface WebRtcStartMessageInterface { export interface WebRtcStartMessageInterface {
roomId: string, roomId: string,
clients: UserSimplePeer[] clients: UserSimplePeerInterface[]
} }
export interface WebRtcDisconnectMessageInterface { export interface WebRtcDisconnectMessageInterface {

View File

@ -1,3 +1,4 @@
import * as SimplePeerNamespace from "simple-peer";
import {DivImportance, layoutManager} from "./LayoutManager"; import {DivImportance, layoutManager} from "./LayoutManager";
const videoConstraint: boolean|MediaTrackConstraints = { const videoConstraint: boolean|MediaTrackConstraints = {
@ -30,8 +31,12 @@ export class MediaManager {
video: videoConstraint video: videoConstraint
}; };
updatedLocalStreamCallBacks : Set<UpdatedLocalStreamCallback> = new Set<UpdatedLocalStreamCallback>(); updatedLocalStreamCallBacks : Set<UpdatedLocalStreamCallback> = new Set<UpdatedLocalStreamCallback>();
// TODO: updatedScreenSharingCallBack should have same signature as updatedLocalStreamCallBacks
updatedScreenSharingCallBack : Function;
constructor(updatedScreenSharingCallBack : Function) {
this.updatedScreenSharingCallBack = updatedScreenSharingCallBack;
constructor() {
this.myCamVideo = this.getElementByIdOrFail<HTMLVideoElement>('myCamVideo'); this.myCamVideo = this.getElementByIdOrFail<HTMLVideoElement>('myCamVideo');
this.webrtcInAudio = this.getElementByIdOrFail<HTMLAudioElement>('audio-webrtc-in'); this.webrtcInAudio = this.getElementByIdOrFail<HTMLAudioElement>('audio-webrtc-in');
this.webrtcInAudio.volume = 0.2; this.webrtcInAudio.volume = 0.2;
@ -151,7 +156,7 @@ export class MediaManager {
this.monitorClose.style.display = "none"; this.monitorClose.style.display = "none";
this.monitor.style.display = "block"; this.monitor.style.display = "block";
this.getScreenMedia().then((stream) => { this.getScreenMedia().then((stream) => {
this.updatedLocalStreamCallBack(stream); this.updatedScreenSharingCallBack(stream);
}); });
} }
@ -163,7 +168,7 @@ export class MediaManager {
}); });
this.localScreenCapture = null; this.localScreenCapture = null;
this.getCamera().then((stream) => { this.getCamera().then((stream) => {
this.updatedLocalStreamCallBack(stream); this.updatedScreenSharingCallBack(stream);
}); });
} }
@ -278,6 +283,24 @@ export class MediaManager {
this.remoteVideo.set(userId, this.getElementByIdOrFail<HTMLVideoElement>(userId)); this.remoteVideo.set(userId, this.getElementByIdOrFail<HTMLVideoElement>(userId));
} }
/**
*
* @param userId
*/
addScreenSharingActiveVideo(userId : string, userName: string = ""){
this.webrtcInAudio.play();
// FIXME: switch to DisplayManager!
let elementRemoteVideo = this.getElementByIdOrFail("activeScreenSharing");
userName = userName.toUpperCase();
let color = this.getColorByString(userName);
elementRemoteVideo.insertAdjacentHTML('beforeend', `
<div id="div-${userId}" class="screen-sharing-video-container" style="border-color: ${color};">
<video id="${userId}" autoplay></video>
</div>
`);
this.remoteVideo.set(userId, document.getElementById(userId));
}
/** /**
* *
* @param userId * @param userId

View File

@ -8,7 +8,7 @@ import { mediaManager } from "./MediaManager";
import * as SimplePeerNamespace from "simple-peer"; import * as SimplePeerNamespace from "simple-peer";
const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer'); const Peer: SimplePeerNamespace.SimplePeer = require('simple-peer');
export interface UserSimplePeer{ export interface UserSimplePeerInterface{
userId: string; userId: string;
name?: string; name?: string;
initiator?: boolean; initiator?: boolean;
@ -26,10 +26,11 @@ export interface PeerConnectionListener {
export class SimplePeer { export class SimplePeer {
private Connection: Connection; private Connection: Connection;
private WebRtcRoomId: string; private WebRtcRoomId: string;
private Users: Array<UserSimplePeer> = new Array<UserSimplePeer>(); private Users: Array<UserSimplePeerInterface> = new Array<UserSimplePeerInterface>();
private PeerConnectionArray: Map<string, SimplePeerNamespace.Instance> = new Map<string, SimplePeerNamespace.Instance>(); private PeerConnectionArray: Map<string, SimplePeerNamespace.Instance> = new Map<string, SimplePeerNamespace.Instance>();
private readonly updateLocalStreamCallback: (media: MediaStream) => void; private readonly updateLocalStreamCallback: (media: MediaStream) => void;
private readonly updateScreenSharingCallback: (media: MediaStream) => void;
private readonly peerConnectionListeners: Array<PeerConnectionListener> = new Array<PeerConnectionListener>(); private readonly peerConnectionListeners: Array<PeerConnectionListener> = new Array<PeerConnectionListener>();
constructor(Connection: Connection, WebRtcRoomId: string = "test-webrtc") { constructor(Connection: Connection, WebRtcRoomId: string = "test-webrtc") {
@ -37,7 +38,9 @@ export class SimplePeer {
this.WebRtcRoomId = WebRtcRoomId; this.WebRtcRoomId = WebRtcRoomId;
// We need to go through this weird bound function pointer in order to be able to "free" this reference later. // We need to go through this weird bound function pointer in order to be able to "free" this reference later.
this.updateLocalStreamCallback = this.updatedLocalStream.bind(this); this.updateLocalStreamCallback = this.updatedLocalStream.bind(this);
this.updateScreenSharingCallback = this.updatedScreenSharing.bind(this);
mediaManager.onUpdateLocalStream(this.updateLocalStreamCallback); mediaManager.onUpdateLocalStream(this.updateLocalStreamCallback);
mediaManager.onUpdateScreenSharing(this.updateScreenSharingCallback);
this.initialise(); this.initialise();
} }
@ -93,7 +96,7 @@ export class SimplePeer {
* server has two people connected, start the meet * server has two people connected, start the meet
*/ */
private startWebRtc() { private startWebRtc() {
this.Users.forEach((user: UserSimplePeer) => { this.Users.forEach((user: UserSimplePeerInterface) => {
//if it's not an initiator, peer connection will be created when gamer will receive offer signal //if it's not an initiator, peer connection will be created when gamer will receive offer signal
if(!user.initiator){ if(!user.initiator){
return; return;
@ -105,22 +108,24 @@ export class SimplePeer {
/** /**
* create peer connection to bind users * create peer connection to bind users
*/ */
private createPeerConnection(user : UserSimplePeer) { private createPeerConnection(user : UserSimplePeerInterface) : SimplePeerNamespace.Instance | null{
if(this.PeerConnectionArray.has(user.userId)) { if(this.PeerConnectionArray.has(user.userId)) {
return; return null;
} }
//console.log("Creating connection with peer "+user.userId);
let name = user.name; let name = user.name;
if(!name){ if(!name){
const userSearch = this.Users.find((userSearch: UserSimplePeer) => userSearch.userId === user.userId); const userSearch = this.Users.find((userSearch: UserSimplePeerInterface) => userSearch.userId === user.userId);
if(userSearch) { if(userSearch) {
name = userSearch.name; name = userSearch.name;
} }
} }
mediaManager.removeActiveVideo(user.userId);
mediaManager.addActiveVideo(user.userId, name); let screenSharing : boolean = name !== undefined && name.indexOf("screenSharing") > -1;
if(!screenSharing) {
mediaManager.removeActiveVideo(user.userId);
mediaManager.addActiveVideo(user.userId, name);
}
const peer : SimplePeerNamespace.Instance = new Peer({ const peer : SimplePeerNamespace.Instance = new Peer({
initiator: user.initiator ? user.initiator : false, initiator: user.initiator ? user.initiator : false,
@ -146,6 +151,11 @@ export class SimplePeer {
}); });
peer.on('stream', (stream: MediaStream) => { peer.on('stream', (stream: MediaStream) => {
if(screenSharing){
//add stream video on
return;
}
let videoActive = false; let videoActive = false;
let microphoneActive = false; let microphoneActive = false;
stream.getTracks().forEach((track : MediaStreamTrack) => { stream.getTracks().forEach((track : MediaStreamTrack) => {
@ -199,6 +209,7 @@ export class SimplePeer {
for (const peerConnectionListener of this.peerConnectionListeners) { for (const peerConnectionListener of this.peerConnectionListeners) {
peerConnectionListener.onConnect(user); peerConnectionListener.onConnect(user);
} }
return peer;
} }
/** /**
@ -301,11 +312,10 @@ export class SimplePeer {
} }
PeerConnection.write(new Buffer(JSON.stringify(Object.assign(mediaManager.constraintsMedia, {screen: localScreenCapture !== null})))); PeerConnection.write(new Buffer(JSON.stringify(Object.assign(mediaManager.constraintsMedia, {screen: localScreenCapture !== null}))));
if (localScreenCapture !== null) { if(!localStream){
for (const track of localScreenCapture.getTracks()) { return;
PeerConnection.addTrack(track, localScreenCapture); }
} if (localStream) {
} else if (localStream) {
for (const track of localStream.getTracks()) { for (const track of localStream.getTracks()) {
PeerConnection.addTrack(track, localStream); PeerConnection.addTrack(track, localStream);
} }
@ -316,8 +326,33 @@ export class SimplePeer {
} }
updatedLocalStream(){ updatedLocalStream(){
this.Users.forEach((user: UserSimplePeer) => { this.Users.forEach((user: UserSimplePeerInterface) => {
this.addMedia(user.userId); this.addMedia(user.userId);
}) })
} }
updatedScreenSharing() {
if (this.MediaManager.localScreenCapture) {
let screenSharingUser: UserSimplePeerInterface = {
userId: `screenSharing-${this.Connection.userId}`,
initiator: true
};
let PeerConnectionScreenSharing = this.createPeerConnection(screenSharingUser);
if (!PeerConnectionScreenSharing) {
return;
}
for (const track of this.MediaManager.localScreenCapture.getTracks()) {
PeerConnectionScreenSharing.addTrack(track, this.MediaManager.localScreenCapture);
}
} else {
if (!this.PeerConnectionArray.has(`screenSharing-${this.Connection.userId}`)) {
return;
}
let PeerConnectionScreenSharing = this.PeerConnectionArray.get(`screenSharing-${this.Connection.userId}`);
if (!PeerConnectionScreenSharing) {
return;
}
PeerConnectionScreenSharing.destroy();
}
}
} }