Use WebRtc with SimplePeer

This commit is contained in:
gparant 2020-04-25 16:05:33 +02:00
parent a5b5072de1
commit c28108f6c9
9 changed files with 233 additions and 282 deletions

View file

@ -47,7 +47,7 @@ export class MediaManager {
let webRtc = document.getElementById('webRtc');
webRtc.classList.add('active');
this.getCamera();
//this.getCamera();
}
enabledCamera() {
@ -56,7 +56,7 @@ export class MediaManager {
this.constraintsMedia.video = true;
this.localStream = null;
this.myCamVideo.srcObject = null;
this.getCamera();
//this.getCamera();
}
disabledCamera() {
@ -74,14 +74,14 @@ export class MediaManager {
}
this.localStream = null;
this.myCamVideo.srcObject = null;
this.getCamera();
//this.getCamera();
}
enabledMicrophone() {
this.microphoneClose.style.display = "none";
this.microphone.style.display = "block";
this.constraintsMedia.audio = true;
this.getCamera();
//this.getCamera();
}
disabledMicrophone() {
@ -95,17 +95,17 @@ export class MediaManager {
}
});
}
this.getCamera();
//this.getCamera();
}
//get camera
getCamera() {
this.getCameraPromise = navigator.mediaDevices.getUserMedia(this.constraintsMedia)
return this.getCameraPromise = navigator.mediaDevices.getUserMedia(this.constraintsMedia)
.then((stream: MediaStream) => {
console.log("constraintsMedia", stream);
this.localStream = stream;
this.myCamVideo.srcObject = this.localStream;
this.myCamVideo.play();
return stream;
}).catch((err) => {
console.error(err);
this.localStream = null;

View file

@ -1,137 +0,0 @@
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> {
return this.MediaManager.getCameraPromise.then(() => {
this.peerConnection = new RTCPeerConnection();
//init all events peer connection
this.createEventPeerConnection();
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.addEventListener('icecandidate', ({candidate}) => {
let message = {message: candidate};
if (!candidate) {
return;
}
this.WebRtcEventManager.emitIceCandidate(message);
});
this.peerConnection.addEventListener('iceconnectionstatechange', (e : Event) => {
console.info('oniceconnectionstatechange => iceConnectionState', this.peerConnection.iceConnectionState);
});
this.peerConnection.addEventListener('negotiationneeded', (e : Event) => {
console.info("Event:negotiationneeded => call()", e);
this.createOffer()
});
this.peerConnection.addEventListener("track", (e:RTCTrackEvent) => {
console.info('Event:track', e);
if (this.MediaManager.remoteVideo.srcObject !== e.streams[0]) {
this.MediaManager.remoteVideo.srcObject = e.streams[0];
console.log('pc1 received remote stream');
}
});
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,106 @@
import {ConnexionInterface} from "../Connexion";
import {MediaManager} from "./MediaManager";
let Peer = require('simple-peer');
export class SimplePeer {
Connexion: ConnexionInterface;
MediaManager: MediaManager;
RoomId: string;
PeerConnexion: any;
constructor(Connexion: ConnexionInterface, roomId: string = "test-webrtc") {
this.Connexion = Connexion;
this.MediaManager = new MediaManager();
this.RoomId = roomId;
this.initialise();
}
/**
* server has two person connected, start the meet
*/
initialise() {
return this.MediaManager.getCamera().then(() => {
//send message to join a room
this.Connexion.sendWebrtcRomm(this.RoomId);
//receive message start
this.Connexion.receiveWebrtcStart((message : string) => {
this.receiveWebrtcStart(message);
});
//receive signal by gemer
this.Connexion.receiveWebrtcSignal((message : string) => {
this.receiveWebrtcSignal(message);
});
}).catch((err) => {
console.error(err);
});
}
/**
*
*/
receiveWebrtcStart(message: string) {
let data = JSON.parse(message);
//create pear connexion of user stared
this.createPeerConnexion(data.initiator);
}
/**
*
* @param userId
* @param initiator
*/
createPeerConnexion(initiator : boolean = false){
this.PeerConnexion = new Peer({initiator: initiator});
this.addMedia();
this.PeerConnexion.on('signal', (data: any) => {
this.sendWebrtcSignal(data);
});
this.PeerConnexion.on('stream', (stream: MediaStream) => {
this.stream(stream)
});
}
/**
* permit to send signal
* @param data
*/
sendWebrtcSignal(data: any) {
this.Connexion.sendWebrtcSignal(data, this.RoomId);
}
/**
*
* @param message
*/
receiveWebrtcSignal(message: string) {
let data = JSON.parse(message);
if(!this.PeerConnexion){
return;
}
this.PeerConnexion.signal(data.signal);
}
/**
* permit stream video
* @param stream
*/
stream(stream: MediaStream) {
this.MediaManager.remoteStream = stream;
this.MediaManager.remoteVideo.srcObject = this.MediaManager.remoteStream;
}
/**
* Permit to update stream
* @param stream
*/
addMedia () {
this.PeerConnexion.addStream(this.MediaManager.localStream) // <- add streams to peer dynamically
}
}

View file

@ -1,92 +0,0 @@
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();
//start to connect on event
//TODO test
this.emitWebRtcRoom();
}
/**
* 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)'}`);
});
});
}
emitWebRtcRoom(){
//connect on the room to create a meet
this.Connexion.socket.emit('webrtc-room', JSON.stringify({roomId: this.RoomId}));
}
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));
}
}