'use strict';
///////////////////////////////////////////////////////////////////////////////
//
// PeerConnection
//
// The PeerConnectionClient in the code below is coded with reference
// to the required part of the apprtc peerconnectionclient.js and
// the configuration flow and method of the PeeConnection Client.
//
///////////////////////////////////////////////////////////////////////////////
var ws = new WebSocket('wss://' + location.host + '/one2many');
var video;
var webRtcPeer;
window.onload = function() {
console = new Console();
video = document.getElementById('video');
document.getElementById('call').addEventListener('click', function() { presenter(); } );
document.getElementById('viewer').addEventListener('click', function() { viewer(); } );
document.getElementById('terminate').addEventListener('click', function() { stop(); } );
}
window.onbeforeunload = function() {
ws.close();
}
ws.onmessage = function(message) {
var parsedMessage = JSON.parse(message.data);
console.info('================ Received message: ' + message.data);
switch (parsedMessage.id) {
case 'presenterResponse':
presenterResponse(parsedMessage);
break;
case 'viewerResponse':
viewerResponse(parsedMessage);
break;
case 'stopCommunication':
dispose();
break;
case 'iceCandidate':
webRtcPeer.addIceCandidate(parsedMessage.candidate)
console.log("Dat debug ice :", parsedMessage.candidate);
break;
default:
console.error('Unrecognized message', parsedMessage);
}
}
function presenterResponse(message) {
console.log("Dat debug == presenterResponse: ", message);
if (message.response != 'accepted') {
var errorMsg = message.message ? message.message : 'Unknow error';
console.warn('Call not accepted for the following reason: ' + errorMsg);
dispose();
} else {
webRtcPeer.processAnswer(message.sdpAnswer);
//{ id: "presenterResponse", response: "accepted", sdpAnswer: "v=0..." }
}
}
function viewerResponse(message) {
console.log("Dat debug == viewerResponse: ", message);
if (message.response != 'accepted') {
var errorMsg = message.message ? message.message : 'Unknow error';
console.warn('Call not accepted for the following reason: ' + errorMsg);
dispose();
} else {
webRtcPeer.processAnswer(message.sdpAnswer);
//{ id: "presenterResponse", response: "accepted", sdpAnswer: "v=0..." }
}
}
function presenter() {
if (!webRtcPeer) {
showSpinner(video);
var options = {
localVideo: video,
onicecandidate : onIceCandidate
}
webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerSendonly(options, function(error) {
if(error) return onError(error);
this.generateOffer(onOfferPresenter);
});
}
}
function onOfferPresenter(error, offerSdp) {
if (error) return onError(error);
var message = {
id : 'presenter',
sdpOffer : offerSdp
};
sendMessage(message);
}
function viewer() {
if (!webRtcPeer) {
showSpinner(video);
var options = {
remoteVideo: video,
onicecandidate : onIceCandidate
}
webRtcPeer = kurentoUtils.WebRtcPeer.WebRtcPeerRecvonly(options, function(error) {
if(error) return onError(error);
this.generateOffer(onOfferViewer);
});
}
}
function onOfferViewer(error, offerSdp) {
if (error) return onError(error)
var message = {
id : 'viewer',
sdpOffer : offerSdp
}
sendMessage(message); //send to KMS
}
function stop() {
if (webRtcPeer) {
var message = {
id : 'stop'
}
sendMessage(message);
dispose();
}
}
function dispose() {
if (webRtcPeer) {
webRtcPeer.dispose();
webRtcPeer = null;
}
hideSpinner(video);
}
function sendMessage(message) {
var jsonMessage = JSON.stringify(message);
console.log('==================Sending message: ' + jsonMessage);
ws.send(jsonMessage);
}
///////////////////////////////////////////////////////////////////////////////////
//
// TODO:
// - need to add PC configuration params before PC creation
// - need to consider peer connection drop error handing
// - need to add new inteface to configure for rws config parameters
//
////////////////////////////////////////////////////////////////////////////////
function PeerConnectionClient(remoteVideo, doSendPeerMessage) {
// configuration for peerconnection
this.pcConfig_ = {"iceServers": [{"urls": "stun:stun.l.google.com:19302"}]};
this.pcOptions_ = { optional: [ {DtlsSrtpKeyAgreement: true} ] };
this.messageCounter_ = 0;
this.doSendPeerMessage_ = doSendPeerMessage;
this.remoteVideo_ = remoteVideo;
// PeerConnection
this.peerConnection_ = new RTCPeerConnection(this.pcConfig_, this.pcOptions_);
this.peerConnection_.onicecandidate = this.onIceCandidate_.bind(this);
this.peerConnection_.ontrack = this.onRemoteStreamAdded_.bind(this);
this.peerConnection_.onremovestream = trace.bind(null, 'Remote stream removed.');
this.peerConnection_.onsignalingstatechange = this.onSignalingStateChanged_.bind(this);
this.peerConnection_.oniceconnectionstatechange =
this.onIceConnectionStateChanged_.bind(this);
trace("Created RTCPeerConnnection with config: " + JSON.stringify(this.pcConfig_));
};
PeerConnectionClient.prototype.onIceCandidate_ = function(event) {
if (!this.peerConnection_) {
return;
}
if (event.candidate) {
var message = {
id : 'onIceCandidate',
candidate : candidate
}
trace('Sending IceCandidate : ' + JSON.stringify(message));
this.doSendPeerMessage_(JSON.stringify(message));
} else {
trace('End of candidates.');
}
};
PeerConnectionClient.prototype.onIceConnectionStateChanged_ = function() {
if (!this.peerConnection_) {
return;
}
trace('ICE connection state changed to: ' + this.peerConnection_.iceConnectionState);
if (this.peerConnection_.iceConnectionState === 'completed') {
trace('ICE complete time: ' +
(window.performance.now() - this.startTime_).toFixed(0) + 'ms.');
}
};
PeerConnectionClient.prototype.onSignalingStateChanged_ = function() {
if (!this.peerConnection_) {
return;
}
trace('Signaling state changed to: ' + this.peerConnection_.signalingState);
};
PeerConnectionClient.prototype.getPeerConnectionStates = function() {
if (!this.peerConnection_) {
return null;
}
return {
'signalingState': this.peerConnection_.signalingState,
'iceGatheringState': this.peerConnection_.iceGatheringState,
'iceConnectionState': this.peerConnection_.iceConnectionState
};
};
PeerConnectionClient.prototype.getPeerConnectionStats = function(callback) {
if (!this.peerConnection_) {
return;
}
this.peerConnection_.getStats(null)
.then(callback);
};
PeerConnectionClient.prototype.close = function() {
if (!this.peerConnection_) {
return;
}
this.peerConnection_.close();
window.dispatchEvent(new CustomEvent('peerconnectionclosed', {
detail: {
pc: this,
time: new Date(),
}
}));
this.peerConnection_ = null;
};
PeerConnectionClient.prototype.onRemoteStreamAdded_ = function (event) {
if (!this.peerConnection_) {
return;
}
if( !this.remoteVideo_ ) {
trace("Error in Remote Video Element object :" );
return;
}
trace("Remote stream added:" + event.streams );
this.remoteVideo_.srcObject = event.streams[0];
};
PeerConnectionClient.prototype.setLocalSdpAndSend_ = function(sessionDescription) {
this.peerConnection_.setLocalDescription(sessionDescription)
.then(trace.bind(null, 'Set local session description success.'))
.catch(this.onError_.bind(this, 'setLocalDescription'));
this.doSendPeerMessage_(sessionDescription) ;
};
PeerConnectionClient.prototype.onReceivePeerMessage = function (data) {
++this.messageCounter_;
var dataJson = JSON.parse(data);
trace("onReceived Message Type :" + dataJson['type'] );
if (dataJson["type"]