video/comms/webRTC-over-websockets/js/webrtc.js

211 lines
7.0 KiB
JavaScript

var webrtc = function(options) {
var my = {};
var commChannel = options.commChannel,
stunServer = options.stunServer,
sourcevid = options.sourcevid,
remoteCallback = options.onremote;
var localStream;
var peerConn = {};
var mediaConstraints = {'mandatory': {'OfferToReceiveAudio':true, 'OfferToReceiveVideo':true }};
if(options.constrains === 'dynamic'){
BANDWITDH.init(function(bandwitdh){
console.log('calculate bandwitdh');
if(!isNaN(bandwitdh) && bandwitdh < 0.5){
mediaConstraints = {'mandatory': {
'OfferToReceiveAudio':true,
'OfferToReceiveVideo':false }};
}
console.log('bandwitdh is ' + bandwitdh + ' [Mbps]');
});
}
//callback to start p2p connection between two parties
commChannel.addCallback('s-answer', call);
commChannel.addCallback('offer', processSignalingMessage);
commChannel.addCallback('answer', processSignalingMessage);
commChannel.addCallback('candidate', processSignalingMessage);
commChannel.addCallback('bye', processSignalingMessage);
function RTCPeer(pc_config, name) {
this.from = name;
this.rtc = new RTCPeerConnection(pc_config);
that = this;
this.rtc.onaddstream = function(event){
logg("Added remote stream");
remoteCallback(that.from, true, event.stream);
};
this.rtc.onremovestream = function(event) {
logg("Remove remote stream");
remoteCallback(that.from, false);
};
this.rtc.onicecandidate = function(event) {
logg("send on Icecandidate");
if (event.candidate) {
commChannel.sendMessage({type: 'candidate',
label: event.candidate.sdpMLineIndex,
id: event.candidate.sdpMid,
candidate: event.candidate.candidate}, that.from);
} else {
logg("End of candidates.");
}
};
}
function setLocalDescriptionAndMessage(sessionDescription){
logg("setLocalDescriptionAndMessage");
this.rtc.setLocalDescription(sessionDescription);
commChannel.sendMessage(sessionDescription, this.from);
}
RTCPeer.prototype.createOffer = function(callback){
logg("createOffer to " + this.from);
that = this;
this.rtc.createOffer(function(sessionDescription){
callback.call(that, sessionDescription);
}, null, mediaConstraints);
}
RTCPeer.prototype.createAnswer = function(callback){
logg("createAnswer to " + this.from);
that = this;
this.rtc.createAnswer(function(sessionDescription){
callback.call(that, sessionDescription);
}, null, mediaConstraints);
}
RTCPeer.prototype.getRTC = function(){
return this.rtc;
}
RTCPeer.prototype.getFrom = function(){
return this.from;
}
var logg = function(s) { console.log(s); };
my.startVideo = function() {
try {
getUserMedia({audio: true, video: true}, successCallback, errorCallback);
} catch (e) {
getUserMedia("video,audio", successCallback, errorCallback);
}
function successCallback(stream) {
attachMediaStream(sourcevid, stream);
localStream = stream;
logg('local stream started');
}
function errorCallback(error) {
logg('An error occurred: [CODE ' + error.code + ']');
}
}
my.stopVideo = function() {
sourcevid.src = "";
}
my.onHangUp = function() {
logg("Hang up.");
closeSession();
}
// start the connection upon user request
function call(msg) {
if(msg.answer !== 'accept') {
console.log('call not accepted');
return;
}
if (peerConn[msg.from] === undefined && localStream) {
logg("Creating PeerConnection with "+ msg.from);
createPeerConnection(msg.from);
} else if (!localStream){
alert("Please start the video first");
logg("localStream not started");
return;
} else {
logg("peer SDP offer already made");
}
logg("create offer");
peerConn[msg.from].createOffer(setLocalDescriptionAndMessage);
}
function createPeerConnection(from) {
try {
logg("Creating peer connection with " + from);
var servers = [];
servers.push({'url':'stun:' + stunServer});
var pc_config = {'iceServers':servers};
peerConn[from] = new RTCPeer(pc_config, from);
logg("Connected using stun server "+ stunServer);
} catch (e) {
alert("Failed to create PeerConnection, exception: " + e.message);
return;
}
logg('Adding local stream...');
peerConn[from].getRTC().addStream(localStream);
}
function processSignalingMessage(msg) {
logg("processSignalingMessage type(" + msg.type + ")= " + msg);
if (msg.type === 'offer') {
if(peerConn[msg.from] === undefined && localStream) {
createPeerConnection(msg.from);
//set remote description
peerConn[msg.from].getRTC().setRemoteDescription(new RTCSessionDescription(msg));
//create answer
logg("Sending answer to peer.");
peerConn[msg.from].createAnswer(setLocalDescriptionAndMessage);
} else {
logg('peerConnection has already been started');
}
} else if (msg.type === 'answer' && peerConn[msg.from] !== undefined) {
logg("setRemoteDescription...");
peerConn[msg.from].getRTC().setRemoteDescription(new RTCSessionDescription(msg));
} else if (msg.type === 'candidate' && peerConn[msg.from] !== undefined) {
var candidate = new RTCIceCandidate({sdpMLineIndex:msg.label, candidate:msg.candidate});
peerConn[msg.from].getRTC().addIceCandidate(candidate);
} else if (msg.type === 'bye' && peerConn[msg.from] !== undefined) {
onRemoteHangUp(msg.from);
} else {
logg("message unknown:" + msg);
}
}
function onRemoteHangUp(from) {
logg("Remote(" + from + ") Hang up ");
remoteCallback(from, false);
peerConn[from].getRTC().close();
delete peerConn[from];
}
function closeSession() {
for(var index in peerConn){
remoteCallback(peerConn[index].getFrom(), false);
peerConn[index].getRTC().close();
delete peerConn[index];
}
commChannel.sendMessage({type: 'bye'});
}
window.onbeforeunload = function() {
if (Object.keys(peerConn).length > 0) {
closeSession();
}
}
return my;
};