194 lines
5.0 KiB
JavaScript
Executable File
194 lines
5.0 KiB
JavaScript
Executable File
class Config {
|
|
static peerConnectionConfig = {
|
|
'iceServers': [
|
|
{'urls': 'stun:stun.stunprotocol.org:3478'},
|
|
{'urls': 'stun:stun.l.google.com:19302'},
|
|
]
|
|
};
|
|
|
|
static getCookie(cname) {
|
|
var name = cname + "=";
|
|
var decodedCookie = decodeURIComponent(document.cookie);
|
|
var ca = decodedCookie.split(';');
|
|
for(var i = 0; i <ca.length; i++) {
|
|
var c = ca[i];
|
|
while (c.charAt(0) == ' ') {
|
|
c = c.substring(1);
|
|
}
|
|
if (c.indexOf(name) == 0) {
|
|
return c.substring(name.length, c.length);
|
|
}
|
|
}
|
|
return "";
|
|
}
|
|
|
|
static setCookie(cname, cvalue) {
|
|
var d = new Date();
|
|
d.setTime(d.getTime() + (1*24*60*60*1000));
|
|
var expires = "expires="+ d.toUTCString();
|
|
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
|
|
}
|
|
|
|
static getUUID() {
|
|
var uuid = Config.getCookie('uuid');
|
|
if (!uuid) {
|
|
uuid = Config.createUUID();
|
|
Config.setCookie('uuid');
|
|
}
|
|
return uuid;
|
|
}
|
|
|
|
static createUUID() {
|
|
function s4() {
|
|
return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
|
|
}
|
|
|
|
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
|
|
}
|
|
}
|
|
|
|
class View {
|
|
static write(color, msg) {
|
|
document.getElementById("log").innerHTML +=
|
|
'<br><span style="color: ' + color + ';">' + msg + '</span>';
|
|
}
|
|
|
|
static info(msg) {
|
|
rconsole.info(msg);
|
|
View.write("gray", msg);
|
|
}
|
|
|
|
static warn(msg) {
|
|
rconsole.warn(msg);
|
|
View.write("orange", msg);
|
|
}
|
|
|
|
static log(msg) {
|
|
rconsole.log(msg);
|
|
View.write("black", msg);
|
|
}
|
|
|
|
static error(msg) {
|
|
rconsole.error(msg);
|
|
View.write("red", msg);
|
|
}
|
|
}
|
|
|
|
class Controller {
|
|
static serverConnection;
|
|
|
|
constructor(address) {
|
|
Controller.serverConnection = new WebSocket(address);
|
|
}
|
|
}
|
|
|
|
class Entropy {
|
|
static localVideo = null;
|
|
static localStream = null;
|
|
static remoteVideo = null;
|
|
static peerConnection = null;
|
|
|
|
static pageReady() {
|
|
Config.getUUID();
|
|
|
|
Entropy.localVideo = document.getElementById('localVideo');
|
|
Entropy.remoteVideo = document.getElementById('remoteVideo');
|
|
|
|
new Controller('wss://' + window.location.hostname + '/abc');
|
|
Controller.serverConnection.onmessage = Entropy.gotMessageFromServer;
|
|
|
|
var constraints = {
|
|
video: true,
|
|
audio: false,
|
|
};
|
|
|
|
if(navigator.mediaDevices.getUserMedia) {
|
|
navigator.mediaDevices.getUserMedia(constraints).then(Entropy.getUserMediaSuccess).catch(View.error);
|
|
} else {
|
|
alert('Your browser does not support getUserMedia API');
|
|
}
|
|
}
|
|
|
|
static getUserMediaSuccess(stream) {
|
|
Entropy.localStream = stream;
|
|
Entropy.localVideo.srcObject = stream;
|
|
}
|
|
|
|
static start(isCaller) {
|
|
Entropy.peerConnection = new RTCPeerConnection(Config.peerConnectionConfig);
|
|
Entropy.peerConnection.onicecandidate = Entropy.gotIceCandidate;
|
|
Entropy.peerConnection.ontrack = Entropy.gotRemoteStream;
|
|
Entropy.peerConnection.addStream(Entropy.localStream);
|
|
|
|
if(isCaller) {
|
|
Entropy.peerConnection
|
|
.createOffer({
|
|
'iceRestart': true,
|
|
'voiceActivityDetection': true,
|
|
})
|
|
.then(Entropy.createdDescription)
|
|
.catch(View.error);
|
|
}
|
|
}
|
|
|
|
static gotMessageFromServer(message) {
|
|
if(!Entropy.peerConnection) Entropy.start(false);
|
|
|
|
var signal = JSON.parse(message.data);
|
|
|
|
// Ignore messages from ourself
|
|
if(signal.uuid == Config.getUUID()) return;
|
|
|
|
if(signal.sdp) {
|
|
Entropy.peerConnection.setRemoteDescription(new RTCSessionDescription(signal.sdp)).then(function() {
|
|
// Only create answers in response to offers
|
|
if(signal.sdp.type == 'offer') {
|
|
Entropy.peerConnection.createAnswer().then(Entropy.createdDescription).catch(View.error);
|
|
}
|
|
}).catch(View.error);
|
|
} else if(signal.ice) {
|
|
Entropy.peerConnection.addIceCandidate(new RTCIceCandidate(signal.ice)).catch(View.error);
|
|
}
|
|
}
|
|
|
|
static gotIceCandidate(event) {
|
|
if(event.candidate != null) {
|
|
Controller.serverConnection.send(JSON.stringify({'ice': event.candidate, 'uuid': Config.getUUID()}));
|
|
}
|
|
}
|
|
|
|
static createdDescription(description) {
|
|
View.log('got description');
|
|
|
|
Entropy.peerConnection
|
|
.setLocalDescription(description)
|
|
.then(function() {
|
|
Controller.serverConnection.send(JSON.stringify({
|
|
'sdp': Entropy.peerConnection.localDescription,
|
|
'uuid': Config.getUUID(),
|
|
}));
|
|
})
|
|
.catch(View.error);
|
|
}
|
|
|
|
static gotRemoteStream(event) {
|
|
View.log('got remote stream');
|
|
Entropy.remoteVideo.srcObject = event.streams[0];
|
|
}
|
|
}
|
|
|
|
function pageReady() {
|
|
Entropy.pageReady();
|
|
}
|
|
|
|
function start(b) {
|
|
Entropy.start(b);
|
|
}
|
|
|
|
var rconsole = console;
|
|
var console = {}
|
|
for (var i in ["log", "info", "warn", "error"]) {
|
|
console[i] = View[i];
|
|
}
|
|
window.console = console;
|