API Version: Development
var TAG = 'IPC-VIDEO-ECHO:';
var host = 'https://pabx.hostname';
IPCortex.PBX.Auth.setHost(host);
/* Start the API's live data feed */{
IPCortex.PBX.startFeed().then(
function() {
console.log(TAG, 'Live data feed started');
/* Enable chat to allow video negotiation messages to be exchanged */
if ( IPCortex.PBX.enableChat() ) {
console.log(TAG, 'Chat enable, enabling \'av\' feature');
/* Enable the 'av' feature, passing a callback for new Av instances */
IPCortex.PBX.enableFeature(
'av',
function(av) {
/* Process and listen for update to new Av instances */
av.addListener('update', processFeed);
processFeed(av);
},
['chat']
);
}
},
function() {
console.log(TAG, 'Live data feed failed');
}
);
IPCortex.PBX.startFeed()
will run after authentication to get the API to connect to the system to receive data and be informed of new events. If startFeed()
is successful, IPCortex.PBX.enableChat()
will be called; chat has to be enabled as all 'av' (video) negotiation messages are exchanged via the chat subsystem. These negotiation messages are transparent to the user. Finally the 'av' feature is enabled with a callback for new Av instances which will have an update listener added to monitor state changes.processFeed()
var echoedStream = {};
/* Process the Av instances */
function processFeed(av) {
/* Nothing to process if remoteMedia isn't an object */
if ( typeof(av.remoteMedia) != 'object' )
return;
for ( var id in av.remoteMedia ) {
if ( av.remoteMedia[id].status == 'offered' ) {
console.log(TAG, 'Accepting offer ' + av.remoteMedia[id].cN);
/* Accept remote parties offer */
av.accept();
}
/* When the remote party has connected check the stream hasn't already been echoed */
if ( av.remoteMedia[id].status == 'connected' && ! echoedStream[id] ) {
console.log(TAG, 'Connected client, looping back video stream');
echoedStream[id] = true;
/* Clone the mediaStream and strip out the audio tracks to avoid feedback */
var stream = av.remoteMedia[id].clone();
stream.getAudioTracks().forEach(
function(track) {
stream.removeTrack(track);
}
);
/* Add the clone stream to the Av instance */
av.addStream(stream);
}
}
}
processFeed()
receives a new or updated Av instance it checks to see if it contains an 'offered' or 'connected' stream. If the request is an offer, processFeed()
calls av.accept()
and waits for the remote party to become 'connected' (which will then run the function again). If connected, it clones the remote stream, removes the audio tracks (to avoid audio feedback) and calls av.addStream(stream)
to loop the media back to the remote party.