mirror of https://github.com/movim/movim
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
360 lines
11 KiB
360 lines
11 KiB
function logError(error) {
|
|
console.log(error.name + ': ' + error.message);
|
|
console.log(error);
|
|
}
|
|
|
|
var Visio = {
|
|
pc: null,
|
|
constraints: null,
|
|
audioContext: null,
|
|
max_level_L: 0,
|
|
old_level_L: 0,
|
|
from: null,
|
|
type: null,
|
|
|
|
localCreated: false,
|
|
|
|
setFrom: function(from) {
|
|
Visio.from = from;
|
|
},
|
|
|
|
/*
|
|
* Jingle and WebRTC
|
|
*/
|
|
handleSuccess: function(stream) {
|
|
if (Visio.pc.addTrack) {
|
|
stream.getTracks().forEach(track => Visio.pc.addTrack(track, stream));
|
|
} else {
|
|
Visio.pc.addStream(stream);
|
|
}
|
|
|
|
Visio.toggleMainButton();
|
|
|
|
document.getElementById('video').srcObject = stream;
|
|
|
|
// Audio
|
|
var microphone = Visio.audioContext.createMediaStreamSource(stream);
|
|
var javascriptNode = Visio.audioContext.createScriptProcessor(2048, 1, 1);
|
|
|
|
var cnvs = document.querySelector('#visio .level');
|
|
var cnvs_cntxt = cnvs.getContext("2d");
|
|
|
|
microphone.connect(javascriptNode);
|
|
javascriptNode.connect(Visio.audioContext.destination);
|
|
javascriptNode.onaudioprocess = function(event){
|
|
var inpt_L = event.inputBuffer.getChannelData(0);
|
|
var instant_L = 0.0;
|
|
|
|
var sum_L = 0.0;
|
|
|
|
for(var i = 0; i < inpt_L.length; ++i) {
|
|
sum_L += inpt_L[i] * inpt_L[i];
|
|
}
|
|
|
|
instant_L = Math.sqrt(sum_L / inpt_L.length);
|
|
Visio.max_level_L = Math.max(Visio.max_level_L, instant_L);
|
|
instant_L = Math.max( instant_L, Visio.old_level_L -0.008 );
|
|
Visio.old_level_L = instant_L;
|
|
|
|
cnvs_cntxt.clearRect(0, 0, cnvs.width, cnvs.height);
|
|
cnvs_cntxt.fillStyle = 'white';
|
|
cnvs_cntxt.fillRect(0, 0,(cnvs.width)*(instant_L/Visio.max_level_L),(cnvs.height)); // x,y,w,h
|
|
}
|
|
|
|
// if we received an offer, we need to answer
|
|
if (Visio.pc.remoteDescription
|
|
&& Visio.pc.remoteDescription.type == 'offer') {
|
|
Visio.pc.createAnswer(Visio.localDescCreated, logError);
|
|
}
|
|
},
|
|
|
|
onSDP: function(sdp, type) {
|
|
Visio.type = type;
|
|
|
|
console.log('SDP');
|
|
console.log(sdp);
|
|
|
|
return Visio.pc.setRemoteDescription(
|
|
new RTCSessionDescription({'sdp': sdp + "\n", 'type': type}),
|
|
function () { Visio_ajaxGetCandidates(); },
|
|
logError
|
|
);
|
|
},
|
|
|
|
localDescCreated: function(desc) {
|
|
Visio.localCreated = true;
|
|
Visio.pc.setLocalDescription(desc, Visio.toggleMainButton, logError);
|
|
},
|
|
|
|
onCandidate: function(candidate, mid, mlineindex) {
|
|
console.log('candidate');
|
|
console.log(candidate);
|
|
|
|
Visio_ajaxGetCandidates();
|
|
|
|
if (mid == '') mlineindex = 1;
|
|
|
|
if (Visio.pc.remoteDescription == null) return;
|
|
|
|
candidate = new RTCIceCandidate({
|
|
'candidate': candidate,
|
|
'sdpMid': mid,
|
|
'sdpMLineIndex' : mlineindex
|
|
});
|
|
|
|
Visio.pc.addIceCandidate(candidate);
|
|
},
|
|
|
|
onTerminate: function() {
|
|
console.log('terminate');
|
|
Visio.pc.getRemoteStreams().forEach(function(stream) {
|
|
stream.getTracks().forEach(function(track) {
|
|
track.stop();
|
|
});
|
|
});
|
|
|
|
document.getElementById('video').srcObject = null;
|
|
document.getElementById('remote_video').srcObject = null;
|
|
|
|
Visio.pc.close();
|
|
|
|
if (window.opener) {
|
|
window.close();
|
|
}
|
|
},
|
|
|
|
init: function(sdp, type) {
|
|
Visio.toggleMainButton();
|
|
|
|
Visio.setFrom(MovimUtils.urlParts().params.join('/'));
|
|
|
|
var configuration = {
|
|
'iceServers': [
|
|
{urls: ['stun:stun01.sipphone.com',
|
|
'stun:stun.ekiga.net',
|
|
'stun:stun.fwdnet.net',
|
|
'stun:stun.ideasip.com',
|
|
'stun:stun.iptel.org',
|
|
'stun:stun.rixtelecom.se',
|
|
'stun:stun.schlund.de',
|
|
'stun:stun.l.google.com:19302',
|
|
'stun:stun1.l.google.com:19302',
|
|
'stun:stun2.l.google.com:19302',
|
|
'stun:stun3.l.google.com:19302',
|
|
'stun:stun4.l.google.com:19302',
|
|
'stun:stunserver.org',
|
|
'stun:stun.softjoys.com',
|
|
'stun:stun.voiparound.com',
|
|
'stun:stun.voipbuster.com',
|
|
'stun:stun.voipstunt.com',
|
|
'stun:stun.voxgratia.org',
|
|
'stun:stun.xten.com']}
|
|
]
|
|
};
|
|
|
|
// WebRTC
|
|
Visio.pc = new RTCPeerConnection(configuration);
|
|
|
|
Visio.pc.onicecandidate = function (evt) {
|
|
Visio.toggleMainButton();
|
|
|
|
if (evt.candidate) {
|
|
Visio_ajaxCandidate(evt.candidate, Visio.from);
|
|
}
|
|
};
|
|
|
|
Visio.pc.oniceconnectionstatechange = function () {
|
|
Visio.toggleMainButton();
|
|
};
|
|
|
|
Visio.pc.onicegatheringstatechange = function () {
|
|
Visio.toggleMainButton();
|
|
};
|
|
|
|
/*Visio.pc.ontrack = function(evt) {
|
|
document.getElementById('remote_video').srcObject = evt.streams[0];
|
|
};*/
|
|
|
|
Visio.audioContext = new AudioContext();
|
|
|
|
Visio.constraints = window.constraints = {
|
|
audio: true,
|
|
video: true
|
|
};
|
|
|
|
Visio.toggleMainButton();
|
|
|
|
if (sdp && type) {
|
|
Visio.onSDP(sdp, type);
|
|
}
|
|
|
|
if (typeof navigator.webkitGetUserMedia == 'function') {
|
|
navigator.webkitGetUserMedia(constraints, Visio.handleSuccess, logError);
|
|
} else {
|
|
navigator.mediaDevices.getUserMedia(constraints)
|
|
.then(Visio.handleSuccess)
|
|
.catch(logError);
|
|
}
|
|
},
|
|
|
|
/*
|
|
* Actions
|
|
*/
|
|
hello: function() {
|
|
Visio.pc.createOffer(function (desc) {
|
|
Visio.pc.setLocalDescription(desc, function () {
|
|
Visio_ajaxInitiate(Visio.pc.localDescription, Visio.from);
|
|
}, logError);
|
|
}, logError);
|
|
},
|
|
|
|
answer: function() {
|
|
Visio.localCreated = false;
|
|
Visio_ajaxAccept(Visio.pc.localDescription, Visio.from);
|
|
},
|
|
|
|
goodbye: function() {
|
|
Visio.onTerminate();
|
|
Visio_ajaxTerminate(Visio.from);
|
|
},
|
|
|
|
/*
|
|
* UI Status
|
|
*/
|
|
toggleMainButton: function() {
|
|
button = document.getElementById('main');
|
|
state = document.querySelector('p.state');
|
|
|
|
i = button.querySelector('i');
|
|
|
|
button.classList.remove('red', 'green', 'gray', 'orange', 'ring', 'blue');
|
|
button.classList.add('disabled');
|
|
|
|
if (Visio.pc) {
|
|
if (Visio.localCreated) Visio.answer();
|
|
|
|
let length = Visio.pc.getSenders
|
|
? Visio.pc.getSenders().length
|
|
: Visio.pc.getLocalStreams().length;
|
|
|
|
if (Visio.pc.iceConnectionState != 'closed'
|
|
&& length > 0) {
|
|
button.classList.remove('disabled');
|
|
}
|
|
|
|
button.onclick = function() {};
|
|
|
|
if (length == 0) {
|
|
button.classList.add('gray');
|
|
i.innerText = 'more_horiz';
|
|
} else if (Visio.pc.iceConnectionState == 'new') {
|
|
if (Visio.pc.iceGatheringState == 'gathering'
|
|
|| Visio.pc.iceGatheringState == 'complete') {
|
|
button.classList.add('orange');
|
|
i.className = 'material-icons ring';
|
|
i.innerText = 'call';
|
|
state.innerHTML = Visio.states.ringing;
|
|
|
|
button.onclick = function() { Visio.goodbye(); };
|
|
} else {
|
|
button.classList.add('green');
|
|
i.innerText = 'call';
|
|
|
|
button.onclick = function() { Visio.hello(); };
|
|
}
|
|
} else if (Visio.pc.iceConnectionState == 'checking') {
|
|
button.classList.add('blue');
|
|
i.className = 'material-icons disabled';
|
|
i.innerText = 'more_horiz';
|
|
state.innerHTML = Visio.states.connecting;
|
|
|
|
} else if (Visio.pc.iceConnectionState == 'closed') {
|
|
button.classList.add('gray');
|
|
i.innerText = 'call_end';
|
|
|
|
button.onclick = function() { MovimUtils.reloadThis(); };
|
|
} else if (Visio.pc.iceConnectionState == 'connected'
|
|
|| Visio.pc.iceConnectionState == 'complete'
|
|
|| Visio.pc.iceConnectionState == 'failed') {
|
|
button.classList.add('red');
|
|
i.innerText = 'call_end';
|
|
|
|
if (Visio.pc.iceConnectionState == 'failed') {
|
|
state.innerHTML = Visio.states.failed;
|
|
} else {
|
|
// Visio.pc.ontrack seems buggy for now
|
|
document.getElementById('remote_video').srcObject = Visio.pc.getRemoteStreams()[0];
|
|
state.innerHTML = Visio.states.in_call;
|
|
}
|
|
|
|
button.onclick = function() { Visio.goodbye(); };
|
|
}
|
|
}
|
|
},
|
|
|
|
toggleFullScreen: function() {
|
|
var button = document.querySelector('#toggle_fullscreen i');
|
|
|
|
if (!document.fullscreenElement
|
|
&& !document.msFullscreenElement
|
|
&& !document.mozFullScreenElement
|
|
&& !document.webkitFullscreenElement) {
|
|
if (document.body.requestFullscreen) {
|
|
document.body.requestFullscreen();
|
|
} else if (document.body.msRequestFullscreen) {
|
|
document.body.msRequestFullscreen();
|
|
} else if (document.body.mozRequestFullScreen) {
|
|
document.body.mozRequestFullScreen();
|
|
} else if (document.body.webkitRequestFullscreen) {
|
|
document.body.webkitRequestFullscreen();
|
|
}
|
|
|
|
button.innerText = 'fullscreen_exit';
|
|
} else {
|
|
if (document.exitFullscreen) {
|
|
document.exitFullscreen();
|
|
} else if (document.msExitFullscreen) {
|
|
document.msExitFullscreen();
|
|
} else if (document.mozCancelFullScreen) {
|
|
document.mozCancelFullScreen();
|
|
} else if (document.webkitCancelFullScreen) {
|
|
document.webkitCancelFullScreen();
|
|
}
|
|
|
|
button.innerText = 'fullscreen';
|
|
}
|
|
},
|
|
|
|
toggleAudio: function() {
|
|
var button = document.querySelector('#toggle_audio i');
|
|
|
|
if (Visio.pc.getLocalStreams()[0].getAudioTracks()[0].enabled) {
|
|
Visio.pc.getLocalStreams()[0].getAudioTracks()[0].enabled = 0;
|
|
button.innerText = 'mic_off';
|
|
} else {
|
|
Visio.pc.getLocalStreams()[0].getAudioTracks()[0].enabled = 1;
|
|
button.innerText = 'mic';
|
|
}
|
|
},
|
|
|
|
toggleVideo: function() {
|
|
var button = document.querySelector('#toggle_video i');
|
|
|
|
if (Visio.pc.getLocalStreams()[0].getVideoTracks()[0].enabled) {
|
|
Visio.pc.getLocalStreams()[0].getVideoTracks()[0].enabled = 0;
|
|
button.innerText = 'videocam-off';
|
|
} else {
|
|
Visio.pc.getLocalStreams()[0].getVideoTracks()[0].enabled = 1;
|
|
button.innerText = 'videocam';
|
|
}
|
|
},
|
|
}
|
|
|
|
MovimWebsocket.attach(function() {
|
|
Visio_ajaxAskInit();
|
|
});
|
|
|
|
window.onbeforeunload = function() {
|
|
Visio.goodbye();
|
|
}
|
|
|