Removing listeners from MediaManager.

SimplePeer now reacts only to stores.
This commit is contained in:
David Négrier 2021-05-29 22:04:08 +02:00
parent 5295f923b5
commit b7f1461405
4 changed files with 90 additions and 150 deletions

View file

@ -15,7 +15,10 @@ import {connectionManager} from "../Connexion/ConnectionManager";
import {GameConnexionTypes} from "../Url/UrlManager";
import {blackListManager} from "./BlackListManager";
import {get} from "svelte/store";
import {localStreamStore, obtainedMediaConstraintStore} from "../Stores/MediaStore";
import {localStreamStore, LocalStreamStoreValue, obtainedMediaConstraintStore} from "../Stores/MediaStore";
import {screenSharingLocalStreamStore} from "../Stores/ScreenSharingStore";
import {DivImportance, layoutManager} from "./LayoutManager";
import {HtmlUtils} from "./HtmlUtils";
export interface UserSimplePeerInterface{
userId: number;
@ -39,9 +42,9 @@ export class SimplePeer {
private PeerScreenSharingConnectionArray: Map<number, ScreenSharingPeer> = new Map<number, ScreenSharingPeer>();
private PeerConnectionArray: Map<number, VideoPeer> = new Map<number, VideoPeer>();
private readonly sendLocalVideoStreamCallback: UpdatedLocalStreamCallback;
private readonly sendLocalScreenSharingStreamCallback: StartScreenSharingCallback;
private readonly stopLocalScreenSharingStreamCallback: StopScreenSharingCallback;
private readonly unsubscribers: (() => void)[] = [];
private readonly peerConnectionListeners: Array<PeerConnectionListener> = new Array<PeerConnectionListener>();
private readonly userId: number;
private lastWebrtcUserName: string|undefined;
@ -49,13 +52,32 @@ export class SimplePeer {
constructor(private Connection: RoomConnection, private enableReporting: boolean, private myName: string) {
// We need to go through this weird bound function pointer in order to be able to "free" this reference later.
this.sendLocalVideoStreamCallback = this.sendLocalVideoStream.bind(this);
this.sendLocalScreenSharingStreamCallback = this.sendLocalScreenSharingStream.bind(this);
this.stopLocalScreenSharingStreamCallback = this.stopLocalScreenSharingStream.bind(this);
mediaManager.onUpdateLocalStream(this.sendLocalVideoStreamCallback);
mediaManager.onStartScreenSharing(this.sendLocalScreenSharingStreamCallback);
mediaManager.onStopScreenSharing(this.stopLocalScreenSharingStreamCallback);
this.unsubscribers.push(localStreamStore.subscribe((streamResult) => {
this.sendLocalVideoStream(streamResult);
}));
let localScreenCapture: MediaStream|null = null;
this.unsubscribers.push(screenSharingLocalStreamStore.subscribe((streamResult) => {
if (streamResult.type === 'error') {
// Let's ignore screen sharing errors, we will deal with those in a different way.
return;
}
if (streamResult.stream !== null) {
localScreenCapture = streamResult.stream;
this.sendLocalScreenSharingStream(localScreenCapture);
} else {
if (localScreenCapture) {
this.stopLocalScreenSharingStream(localScreenCapture);
localScreenCapture = null;
}
}
}));
this.userId = Connection.getUserId();
this.initialise();
}
@ -155,8 +177,9 @@ export class SimplePeer {
// When a connection is established to a video stream, and if a screen sharing is taking place,
// the user sharing screen should also initiate a connection to the remote user!
peer.on('connect', () => {
if (mediaManager.localScreenCapture) {
this.sendLocalScreenSharingStreamToUser(user.userId);
const streamResult = get(screenSharingLocalStreamStore);
if (streamResult.type === 'success' && streamResult.stream !== null) {
this.sendLocalScreenSharingStreamToUser(user.userId, streamResult.stream);
}
});
@ -175,7 +198,7 @@ export class SimplePeer {
/**
* create peer connection to bind users
*/
private createPeerScreenSharingConnection(user : UserSimplePeerInterface) : ScreenSharingPeer | null{
private createPeerScreenSharingConnection(user : UserSimplePeerInterface, stream: MediaStream | null) : ScreenSharingPeer | null{
const peerConnection = this.PeerScreenSharingConnectionArray.get(user.userId);
if(peerConnection){
if(peerConnection.destroyed){
@ -204,7 +227,7 @@ export class SimplePeer {
user.webRtcPassword = this.lastWebrtcPassword;
}
const peer = new ScreenSharingPeer(user, user.initiator ? user.initiator : false, this.Connection);
const peer = new ScreenSharingPeer(user, user.initiator ? user.initiator : false, this.Connection, stream);
this.PeerScreenSharingConnectionArray.set(user.userId, peer);
for (const peerConnectionListener of this.peerConnectionListeners) {
@ -294,7 +317,9 @@ export class SimplePeer {
* Unregisters any held event handler.
*/
public unregister() {
mediaManager.removeUpdateLocalStreamEventListener(this.sendLocalVideoStreamCallback);
for (const unsubscriber of this.unsubscribers) {
unsubscriber();
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -318,18 +343,26 @@ export class SimplePeer {
private receiveWebrtcScreenSharingSignal(data: WebRtcSignalReceivedMessageInterface) {
if (blackListManager.isBlackListed(data.userId)) return;
console.log("receiveWebrtcScreenSharingSignal", data);
const streamResult = get(screenSharingLocalStreamStore);
let stream : MediaStream | null = null;
if (streamResult.type === 'success' && streamResult.stream !== null) {
stream = streamResult.stream;
}
try {
//if offer type, create peer connection
if(data.signal.type === "offer"){
this.createPeerScreenSharingConnection(data);
this.createPeerScreenSharingConnection(data, stream);
}
const peer = this.PeerScreenSharingConnectionArray.get(data.userId);
if (peer !== undefined) {
peer.signal(data.signal);
} else {
console.error('Could not find peer whose ID is "'+data.userId+'" in receiveWebrtcScreenSharingSignal');
console.info('tentative to create new peer connexion');
this.sendLocalScreenSharingStreamToUser(data.userId);
console.info('Attempt to create new peer connexion');
if (stream) {
this.sendLocalScreenSharingStreamToUser(data.userId, stream);
}
}
} catch (e) {
console.error(`receiveWebrtcSignal => ${data.userId}`, e);
@ -339,21 +372,19 @@ export class SimplePeer {
}
}
private pushVideoToRemoteUser(userId : number) {
private pushVideoToRemoteUser(userId: number, streamResult: LocalStreamStoreValue) {
try {
const PeerConnection = this.PeerConnectionArray.get(userId);
if (!PeerConnection) {
throw new Error('While adding media, cannot find user with ID ' + userId);
}
const result = get(localStreamStore);
PeerConnection.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_CONSTRAINT, ...streamResult.constraints})));
PeerConnection.write(new Buffer(JSON.stringify({type: MESSAGE_TYPE_CONSTRAINT, ...result.constraints})));
if (result.type === 'error') {
if (streamResult.type === 'error') {
return;
}
const localStream: MediaStream | null = result.stream;
const localStream: MediaStream | null = streamResult.stream;
if(!localStream){
return;
@ -370,15 +401,11 @@ export class SimplePeer {
}
}
private pushScreenSharingToRemoteUser(userId : number) {
private pushScreenSharingToRemoteUser(userId: number, localScreenCapture: MediaStream) {
const PeerConnection = this.PeerScreenSharingConnectionArray.get(userId);
if (!PeerConnection) {
throw new Error('While pushing screen sharing, cannot find user with ID ' + userId);
}
const localScreenCapture: MediaStream | null = mediaManager.localScreenCapture;
if(!localScreenCapture){
return;
}
for (const track of localScreenCapture.getTracks()) {
PeerConnection.addTrack(track, localScreenCapture);
@ -386,23 +413,18 @@ export class SimplePeer {
return;
}
public sendLocalVideoStream(){
public sendLocalVideoStream(streamResult: LocalStreamStoreValue){
for (const user of this.Users) {
this.pushVideoToRemoteUser(user.userId);
this.pushVideoToRemoteUser(user.userId, streamResult);
}
}
/**
* Triggered locally when clicking on the screen sharing button
*/
public sendLocalScreenSharingStream() {
if (!mediaManager.localScreenCapture) {
console.error('Could not find localScreenCapture to share')
return;
}
public sendLocalScreenSharingStream(localScreenCapture: MediaStream) {
for (const user of this.Users) {
this.sendLocalScreenSharingStreamToUser(user.userId);
this.sendLocalScreenSharingStreamToUser(user.userId, localScreenCapture);
}
}
@ -415,11 +437,11 @@ export class SimplePeer {
}
}
private sendLocalScreenSharingStreamToUser(userId: number): void {
private sendLocalScreenSharingStreamToUser(userId: number, localScreenCapture: MediaStream): void {
if (blackListManager.isBlackListed(userId)) return;
// If a connection already exists with user (because it is already sharing a screen with us... let's use this connection)
if (this.PeerScreenSharingConnectionArray.has(userId)) {
this.pushScreenSharingToRemoteUser(userId);
this.pushScreenSharingToRemoteUser(userId, localScreenCapture);
return;
}
@ -427,7 +449,7 @@ export class SimplePeer {
userId,
initiator: true
};
const PeerConnectionScreenSharing = this.createPeerScreenSharingConnection(screenSharingUser);
const PeerConnectionScreenSharing = this.createPeerScreenSharingConnection(screenSharingUser, localScreenCapture);
if (!PeerConnectionScreenSharing) {
return;
}