Create webrtc connexion between two player

This commit is contained in:
gparant 2020-04-19 19:32:38 +02:00
parent 0f2e21e88e
commit 5b62ac39fb
13 changed files with 769 additions and 8 deletions

View file

@ -1,6 +1,7 @@
import {GameSceneInterface, GameScene} from "./GameScene";
import {ROOM} from "../../Enum/EnvironmentVariable"
import {Connexion, ConnexionInterface, ListMessageUserPositionInterface} from "../../Connexion";
import {WebRtcEventManager} from "../../WebRtc/WebRtcEventManager";
export enum StatusGameManagerEnum {
IN_PROGRESS = 1,
@ -28,6 +29,8 @@ export class GameManager implements GameManagerInterface {
return ConnexionInstance.createConnexion().then(() => {
this.configureGame();
/** TODO add loader in the page **/
//initialise cam
new WebRtcEventManager(ConnexionInstance);
}).catch((err) => {
console.error(err);
throw err;

183
front/src/WebRtc/Index.ts Normal file
View file

@ -0,0 +1,183 @@
/*import {ConnexionInterface} from "../Connexion";
const Peer = require('simple-peer');
let cinemaClose : any = null;
let cinema : any = null;
let microphoneClose : any = null;
let microphone : any = null;
let localStream : MediaStream = null;
let remoteStream : MediaStream = null;
let remoteVideo : any = null;
let myCamVideo : any = null;
let promiseGetCam : Promise<any> = null;
let peer : any = null;
let Connexion : ConnexionInterface = null;
let roomId = "test-wertc";
let gettingCamera : Promise<any> = null;
let constraintsMedia = {audio: true, video: true};
function joinRoom(){
Connexion.JoinRoomWebRtc(roomId);
Connexion.startRoomWebRtc(initialiseWebSocket)
}
function initialiseWebSocket(message : any){
console.log('initialiseWebSocket => message', message);
peer = new Peer({
initiator: message.initiator
});
peer.on('signal', (data : any) => {
//send signal
//permit to send message and initialise peer connexion
console.log('signal sended', data);
Connexion.shareSignalWebRtc({
roomId: roomId,
signal: data
});
});
//permit to receive message and initialise peer connexion
Connexion.receiveSignalWebRtc((data : any) => {
let signal = JSON.parse(data);
console.log('receiveSignalWebRtc => signal', signal);
peer.signal(signal.signal);
});
peer.on('stream', (stream : MediaStream) => {
// got remote video stream, now let's show it in a video tag
console.log("peer => stream", stream);
//set local stream in little cam
myCamVideo.srcObject = localStream;
//set remote stream in remote video
remoteStream = stream;
remoteVideo.srcObject = stream;
});
peer.on('connect', () => {
console.log('CONNECT')
peer.send('whatever' + Math.random())
});
peer.on('data', (data : any) => {
console.log('data: ' + data)
});
peer.on('close', (err : any) => console.error('close', err));
peer.on('error', (err : any) => console.error('error', err));
peer.on('track', (track : any, stream : any) => {
remoteStream = stream;
remoteVideo.srcObject = stream;
track.onended = (e : any) => remoteVideo.srcObject = remoteVideo.srcObject; // Chrome/Firefox bug
});
gettingCamera.then(() => {
addMedia();
});
}
//get camera
function getCamera() {
gettingCamera = navigator.mediaDevices.getUserMedia(constraintsMedia)
.then((stream: MediaStream) => {
localStream = stream;
remoteVideo.srcObject = stream;
}).catch((err) => {
console.error(err);
localStream = null;
throw err;
});
return gettingCamera;
}
function addMedia () {
if(peer) {
peer.addStream(localStream) // <- add streams to peer dynamically
}
}
function enabledCamera(){
cinemaClose.style.display = "none";
cinema.style.display = "block";
constraintsMedia.video = true;
}
function disabledCamera(){
cinemaClose.style.display = "block";
cinema.style.display = "none";
constraintsMedia.video = false;
}
function enabledMicrophone(){
microphoneClose.style.display = "none";
microphone.style.display = "block";
constraintsMedia.audio = true;
}
function disabledMicrophone(){
microphoneClose.style.display = "block";
microphone.style.display = "none";
constraintsMedia.audio = false;
}
function showWebRtc(){
remoteVideo = document.getElementById('activeCamVideo');
myCamVideo = document.getElementById('myCamVideo');
microphoneClose = document.getElementById('microphone-close');
microphoneClose.addEventListener('click', (e : any) => {
e.preventDefault();
enabledMicrophone();
//update tracking
});
microphone = document.getElementById('microphone');
microphone.addEventListener('click', (e : any) => {
e.preventDefault();
disabledMicrophone();
//update tracking
});
cinemaClose = document.getElementById('cinema-close');
cinemaClose.addEventListener('click', (e : any) => {
e.preventDefault();
enabledCamera();
//update tracking
});
cinema = document.getElementById('cinema');
cinema.addEventListener('click', (e : any) => {
e.preventDefault();
disabledCamera();
//update tracking
});
enabledMicrophone();
enabledCamera();
let webRtc = document.getElementById('webRtc');
webRtc.classList.add('active');
}
export const initialisation = (ConnexionInterface : ConnexionInterface) => {
Connexion = ConnexionInterface;
//show camera
showWebRtc();
//open the camera
getCamera();
//join room to create webrtc
joinRoom();
};*/

View file

@ -0,0 +1,89 @@
export class MediaManager {
localStream: MediaStream;
remoteStream: MediaStream;
remoteVideo: any;
myCamVideo: any;
cinemaClose: any = null;
cinema: any = null;
microphoneClose: any = null;
microphone: any = null;
constraintsMedia = {audio: true, video: true};
getCameraPromise : Promise<any> = null;
constructor() {
this.remoteVideo = document.getElementById('activeCamVideo');
this.myCamVideo = document.getElementById('myCamVideo');
this.microphoneClose = document.getElementById('microphone-close');
this.microphoneClose.addEventListener('click', (e: any) => {
e.preventDefault();
this.enabledMicrophone();
//update tracking
});
this.microphone = document.getElementById('microphone');
this.microphone.addEventListener('click', (e: any) => {
e.preventDefault();
this.disabledMicrophone();
//update tracking
});
this.cinemaClose = document.getElementById('cinema-close');
this.cinemaClose.addEventListener('click', (e: any) => {
e.preventDefault();
this.enabledCamera();
//update tracking
});
this.cinema = document.getElementById('cinema');
this.cinema.addEventListener('click', (e: any) => {
e.preventDefault();
this.disabledCamera();
//update tracking
});
this.enabledMicrophone();
this.enabledCamera();
let webRtc = document.getElementById('webRtc');
webRtc.classList.add('active');
this.getCamera();
}
enabledCamera() {
this.cinemaClose.style.display = "none";
this.cinema.style.display = "block";
this.constraintsMedia.video = true;
}
disabledCamera() {
this.cinemaClose.style.display = "block";
this.cinema.style.display = "none";
this.constraintsMedia.video = false;
}
enabledMicrophone() {
this.microphoneClose.style.display = "none";
this.microphone.style.display = "block";
this.constraintsMedia.audio = true;
}
disabledMicrophone() {
this.microphoneClose.style.display = "block";
this.microphone.style.display = "none";
this.constraintsMedia.audio = false;
}
//get camera
getCamera() {
this.getCameraPromise = navigator.mediaDevices.getUserMedia(this.constraintsMedia)
.then((stream: MediaStream) => {
this.localStream = stream;
this.myCamVideo.srcObject = this.localStream;
}).catch((err) => {
console.error(err);
this.localStream = null;
throw err;
});
}
}

View file

@ -0,0 +1,136 @@
import {WebRtcEventManager} from "./WebRtcEventManager";
import {MediaManager} from "./MediaManager";
const offerOptions = {
offerToReceiveAudio: 1,
offerToReceiveVideo: 1,
iceServers: [{url:'stun:stun.l.google.com:19302'}],
};
export class PeerConnexionManager {
WebRtcEventManager: WebRtcEventManager;
MediaManager : MediaManager;
peerConnection: RTCPeerConnection;
constructor(WebRtcEventManager : WebRtcEventManager) {
this.WebRtcEventManager = WebRtcEventManager;
this.MediaManager = new MediaManager();
}
createPeerConnection(data: any = null): Promise<any> {
this.peerConnection = new RTCPeerConnection();
//init all events peer connection
this.createEventPeerConnection();
this.MediaManager.getCameraPromise.then(() => {
this.MediaManager.localStream.getTracks().forEach(
(track : MediaStreamTrack) => this.peerConnection.addTrack(track, this.MediaManager.localStream)
);
});
//if no data, create offer
if (!data || !data.message) {
return this.createOffer();
}
let description = new RTCSessionDescription(data.message);
return this.peerConnection.setRemoteDescription(description).catch((err) => {
console.error("createPeerConnection => setRemoteDescription", err);
throw err;
})
}
createOffer(): Promise<any> {
console.log('pc1 createOffer start');
// @ts-ignore
return this.peerConnection.createOffer(offerOptions).then((offer: RTCSessionDescriptionInit) => {
this.peerConnection.setLocalDescription(offer).then(() => {
let message = {message: this.peerConnection.localDescription};
this.WebRtcEventManager.emitVideoOffer(message);
}).catch((err) => {
console.error("createOffer => setLocalDescription", err);
throw err;
});
}).catch((err: Error) => {
console.error("createOffer => createOffer", err);
throw err;
});
}
createAnswer(): Promise<any> {
return this.peerConnection.createAnswer().then((answer : RTCSessionDescriptionInit) => {
this.peerConnection.setLocalDescription(answer).then(() => {
//push video-answer
let messageSend = {message: this.peerConnection.localDescription};
this.WebRtcEventManager.emitVideoAnswer(messageSend);
console.info("video-answer => send", messageSend);
}).catch((err) => {
console.error("eventVideoOffer => createAnswer => setLocalDescription", err);
throw err;
})
}).catch((err) => {
console.error("eventVideoOffer => createAnswer", err);
throw err;
})
}
setRemoteDescription(data: any): Promise<any> {
let description = new RTCSessionDescription(data.message);
return this.peerConnection.setRemoteDescription(description).catch((err) => {
console.error("PeerConnexionManager => setRemoteDescription", err);
throw err;
})
}
addIceCandidate(data: any): Promise<any> {
return this.peerConnection.addIceCandidate(data.message)
.catch((err) => {
console.error("PeerConnexionManager => addIceCandidate", err);
throw err;
})
}
hangup() {
console.log('Ending call');
if (this.peerConnection) {
this.peerConnection.close();
}
this.peerConnection = null;
}
createEventPeerConnection(){
//define creator of offer
this.peerConnection.onicecandidate = (event: RTCPeerConnectionIceEvent) => {
let message = {message: event.candidate};
if (!event.candidate) {
return;
}
this.WebRtcEventManager.emitIceCandidate(message);
};
this.peerConnection.ontrack = (e:RTCTrackEvent) => {
console.info('Event:track', e);
this.MediaManager.remoteVideo.srcObject = e.streams[0];
this.MediaManager.myCamVideo.srcObject = e.streams[0];
};
this.peerConnection.onnegotiationneeded = (e : Event) => {
console.info("Event:negotiationneeded => call()", e);
this.createOffer()
};
this.peerConnection.oniceconnectionstatechange = (e) => {
console.info('ICE state change event: ', e);
};
this.peerConnection.oniceconnectionstatechange = (e:Event) => {
console.info('oniceconnectionstatechange => iceConnectionState', this.peerConnection.iceConnectionState);
};
this.peerConnection.onicegatheringstatechange = () => {
console.info('onicegatheringstatechange => iceConnectionState', this.peerConnection.iceConnectionState);
};
this.peerConnection.onsignalingstatechange = () => {
console.info('onsignalingstatechange => iceConnectionState', this.peerConnection.iceConnectionState);
};
}
}

View file

@ -0,0 +1,86 @@
import {ConnexionInterface} from "../Connexion";
import {PeerConnexionManager} from "./PeerConnexionManager";
export class WebRtcEventManager {
Connexion: ConnexionInterface;
PeerConnexionManager: PeerConnexionManager;
RoomId : string;
constructor(Connexion : ConnexionInterface, roomId : string = "test-webrtc") {
this.RoomId = roomId;
this.Connexion = Connexion;
this.PeerConnexionManager = new PeerConnexionManager(this);
this.start();
this.eventVideoOffer();
this.eventVideoAnswer();
this.eventIceCandidate();
//connect on the room to create a meet
Connexion.socket.emit('webrtc-room', JSON.stringify({roomId: roomId}));
}
/**
* server has two person connected, start the meet
*/
start(){
this.Connexion.socket.on('webrtc-start', () => {
return this.PeerConnexionManager.createPeerConnection();
});
}
/**
* Receive video offer
*/
eventVideoOffer() {
this.Connexion.socket.on("video-offer", (message : any) => {
let data = JSON.parse(message);
console.info("video-offer", data);
this.PeerConnexionManager.createPeerConnection(data).then(() => {
return this.PeerConnexionManager.createAnswer();
});
});
}
/**
* Receive video answer
*/
eventVideoAnswer() {
this.Connexion.socket.on("video-answer", (message : any) => {
let data = JSON.parse(message);
console.info("video-answer", data);
this.PeerConnexionManager.setRemoteDescription(data)
.catch((err) => {
console.error("video-answer => setRemoteDescription", err)
})
});
}
/**
* Receive ice candidate
*/
eventIceCandidate() {
this.Connexion.socket.on("ice-candidate", (message : any) => {
let data = JSON.parse(message);
console.info("ice-candidate", data);
this.PeerConnexionManager.addIceCandidate(data).then(() => {
console.log(`ICE candidate:\n${data.message ? data.message.candidate : '(null)'}`);
});
});
}
emitIceCandidate(message : any){
message.roomId = this.RoomId;
this.Connexion.socket.emit('ice-candidate', JSON.stringify(message));
}
emitVideoOffer(message : any){
message.roomId = this.RoomId;
this.Connexion.socket.emit('video-offer', JSON.stringify(message));
}
emitVideoAnswer(message : any){
message.roomId = this.RoomId;
this.Connexion.socket.emit("video-answer", JSON.stringify(message));
}
}