[Fiware-creatifi-coaching] [CreatiFI] Kurento support needed from CreatiFI FIWARE Accelerator program winner

Andrea Maestrini amaestrini at create-net.org
Mon Mar 2 08:25:37 CET 2015


Dear,
this is the reply of the CreatiFI winner with the info you requested, with
also attachments
Thanks.

****************************************************
Hi,

in attach you can find the log you have requested.

For the second issue, we have already read the guidance and we have a
running environment with an example p2p WebRTC using STUN and TURN. The
problem raises using Kurento for mediating the video communication.
In the peer webrtc mini-prototype we figured out the architecture, but we
do not understand how this has to change using Kurento.

I think we all can save time if we can arrange a short CC to discuss the
integration of Kurento in the use case.

Let me know.

Thanks Stefano
****************************************************


On Thu, Feb 26, 2015 at 2:00 PM, Andrea Maestrini <amaestrini at create-net.org
> wrote:

> Dear FIWARE coach,
> as you suggested we collect more info from the CreatiFI winner (moreover
> they attached configuration files) and we forward you the support
> request, we
> are not able to solve.
> Please let us know if you need direct contact with the submitter.
> Thanks.
>
> **************************************************************
>
> We are trying to develop an application with Kurento GE as part of
> CREATIFI project.
> The application is quite simple for now, but we are facing some technical
> issues.
>
> The application uses SignalMaster as signaling server, and Kurento for
> mediating the video communication.
> We started with a peer webrtc mini-prototype, and now we are integrating
> Kurento …
>
> Our environment is:
> Linux Ubuntu 14.10
> SignalMaster https://github.com/andyet/signalmaster
> Kurento Media Server (5.1.0)
> Kurento Client Nodejs 5.1.0
>
> The code I have so far does …
>
> - allows two clients to register to a ‘room’
> - when the second enters the room, SDP offers are exchanged (using signal
> master functionalities)
> - then I try to integrate Kurento in the process to have the media
> exchange handled by Kurento but unfortunately, the whole process does not
> fulfill because even in a loopback case (clients and servers all running in
> same machine)I cannot see the videostream to appear.
>
> In attachment you find the code excerpts.
> I think in this stage of the project it would be great for us to get your
> inputs.
>
> A second design problem which is not clear to us - but we are not yet
> there - is the role / configuration of STUN / TURN servers.
> In the peer webrtc mini-prototype we figured out the architecture, but we
> do not understand how this has to change using Kurento.
>
> Can you help and help us go in the right direction ?
>
> best regards
>
> **************************************************************
>
>
>
> On Wed, Feb 18, 2015 at 1:45 PM, Andrea Maestrini <
> amaestrini at create-net.org> wrote:
>
>> Dear FIWARE coach,
>> we forward you a support request received from a CreatiFI Call1 winner, we
>> are not able to solve.
>> Please let us know if you need direct contact with the submitter.
>> Thanks.
>>
>> ****************************************************************
>> General Support #65: Kurento support needed
>> <http://techsupport.creatifi.eu/issues/65>
>>
>>    - Author: Stefano Scotton
>>    - Status: New
>>    - Priority: High
>>    - Assignee: Trento Tech Support (Italy&Belgium)
>>    - Category: Trento Hub (Italy)
>>    - Support Type: FIWARE Generic Enablers
>>
>> Hi all,
>> we are experiencing the features of Kurento GE but we have trouble
>> understanding the documentation aspects of application integration.
>> We need the availability of support for discussing of some architectural
>> aspects of Kurento GE.
>>
>> can you provide us a technical reference to talk to these issues?
>>
>> Thank You
>>
>> Stefano
>>
>> ****************************************************************
>>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.fiware.org/private/fiware-creatifi-coaching/attachments/20150302/6869a1ae/attachment.html>
-------------- next part --------------
/* global console */
var yetify = require('yetify'),
    config = require('getconfig'),
    uuid = require('node-uuid'),
    crypto = require('crypto'),
    port = parseInt(process.env.PORT || config.server.port, 10),
    io = require('socket.io').listen(port);

var kurento = require('kurento-client');

/* Kurento */

var kurentoClient = null;
var pipelines = {};
var offers = {};

const ws_uri = config.kurentoms.url;

// recover kurentoClient for the first time

function getKurentoClient(callback) {

	if (kurentoClient !== null) {
		return callback(null, kurentoClient);
	}

    kurento(ws_uri, function(error, _kurentoClient) {
		if (error) {
			var message = 'Coult not find media server at address ' + ws_uri;
			console.error(message);
			return callback(message + ". Exiting with error " + error);
		}
		kurentoClient = _kurentoClient;
		callback(null, kurentoClient);
	});

}

//Represents a B2B active call
function CallMediaPipeline() {
	this._pipeline = null;
	this._callerWebRtcEndpoint = null;
	this._calleeWebRtcEndpoint = null;
}

CallMediaPipeline.prototype.createPipeline = function(callback) {
	var self = this;
	getKurentoClient(function(error, kurentoClient){
		if(error){
			return callback(error);
		}
		
		kurentoClient.create('MediaPipeline', function(error, pipeline) {
			if (error) {
				return callback(error);
			}
			
			pipeline.create('WebRtcEndpoint', function(error, callerWebRtcEndpoint) {
				if (error) {
					pipeline.release();
					return callback(error);
				}
				
				pipeline.create('WebRtcEndpoint', function(error, calleeWebRtcEndpoint) {
					if (error) {
						pipeline.release();
						return callback(error);
					}
					
					callerWebRtcEndpoint.connect(calleeWebRtcEndpoint, function(error) {
						if (error) {
							pipeline.release();
							return callback(error);
						}
						
						calleeWebRtcEndpoint.connect(callerWebRtcEndpoint, function(error) {
							if (error) {
								pipeline.release();
								return callback(error);
							}
						});
						
						self._pipeline = pipeline;
						self._callerWebRtcEndpoint = callerWebRtcEndpoint;
						self._calleeWebRtcEndpoint = calleeWebRtcEndpoint;
						
						callback(null);
					});
				});
			});
		});
	});
}

CallMediaPipeline.prototype.generateSdpAnswerForCaller = function(sdpOffer, callback) {
	this._callerWebRtcEndpoint.processOffer(sdpOffer, callback);
}

CallMediaPipeline.prototype.generateSdpAnswerForCallee = function(sdpOffer, callback) {
	this._calleeWebRtcEndpoint.processOffer(sdpOffer, callback);
}

CallMediaPipeline.prototype.release = function() {
	if(this._pipeline) this._pipeline.release();
	this._pipeline = null;
}

/* SignalMaster */

if (config.logLevel) {
    // https://github.com/Automattic/socket.io/wiki/Configuring-Socket.IO
    io.set('log level', config.logLevel);
}

function describeRoom(name) {
    var clients = io.sockets.clients(name);
    var result = {
        clients: {}
    };
    clients.forEach(function (client) {
        result.clients[client.id] = client.resources;
    });
    return result;
}

function safeCb(cb) {
    if (typeof cb === 'function') {
        return cb;
    } else {
        return function () {};
    }
}

io.sockets.on('connection', function (client) {
    
    client.resources = {
        screen: false,
        video: true,
        audio: false
    };
    
//    // pass a message to another id
//    client.on('message', function (details) {
//        
////        console.info('message ~ ' + JSON.stringify(details));
//        
//        if (!details) return;
//        
//        if (details.type === 'offer') {
////            console.info(client);
////            console.info(describeRoom(client.room));
//            client.resources.details = details;
//            console.info('RES > ' + JSON.stringify(client.resources));
//        }
//        
//        var otherClient = io.sockets.sockets[details.to];
//        console.info('RES > ' + JSON.stringify(otherClient.resources));
//        
//        if (!otherClient) return;
//        
//        if (details.type === 'answer') {
//            
//            var pipeline = new CallMediaPipeline();
//            
//            pipeline.createPipeline(function(error) {
//                if (error) {
////                    return onError(error, error);
//                    console.error(error);
//                    return ;
//                }
//                
//                if (otherClient.resources.details.payload.sdp) {
//                    pipeline.generateSdpAnswerForCaller(otherClient.resources.details.payload.sdp, function(error, callerSdpAnswer) {
//                        if (error) {
////                            return onError(error, error);
//                            console.error(error);
//                            return ;
//                        }
//                        pipeline.generateSdpAnswerForCallee(details.payload.sdp, function(error, calleeSdpAnswer) {
//                            if (error) {
////                                return onError(error, error);
//                                console.error(error);
//                                return ;
//                            }
//                            
//                            pipelines[client.id] = pipeline;
//                            pipelines[details.to] = pipeline;
//                            
//                            client.emit('message', otherClient.resources.details);
//                            
//                            details.from = client.id;
//                            otherClient.emit('message', details);
//                        });
//                    });
//                }
//            });
//
//        } else {
//            details.from = client.id;
//            otherClient.emit('message', details);
//        }
//    });
    
    client.on('message', function(message) {
        
        if (!message) {
            return ; // do nothing
        }
        
        var other = io.sockets.sockets[message.to];
        
        if (!other) {
            return ; // do nothing
        }
        
        if (message.type === 'offer') {
            
//            console.info('sending offer: ' + JSON.stringify(message));
            
            offers[client.id] = message.payload.sdp;
            
            message.from = client.id;
            other.emit('message', message);
            
        } else if (message.type === 'answer') {
            
//            console.info('sending answer: ' + JSON.stringify(message));
            
            var pipeline = new CallMediaPipeline();
            
            pipeline.createPipeline(function(error) {
                
                if (error) {
                    console.error(error);
                    return ; // do nothing
                }
                
                var offer = offers[message.to];
                
                pipeline.generateSdpAnswerForCaller(offer, function(error, callerSdpAnswer) {
                    
                    if (error) {
                        console.error(error);
                        return ; // do nothing
                    }
                    
                    pipeline.generateSdpAnswerForCallee(message.payload.sdp, function(error, calleeSdpAnswer) {
                        
                        if (error) {
                            console.error(error);
                            return ; // do nothing
                        }
                        
                        var answer = {
                            'to': message.to,
                            'sid': message.sid,
                            'roomType': message.roomType,
                            'type': 'offer',
                            'payload': {
                                'type': 'offer',
                                'sdp': callerSdpAnswer
                            },
                            'prefix': message.prefix,
                            'from': client.id
                        };
                        
                        console.info('Kurento generated SDP answer for caller (2nd user): ' + JSON.stringify(answer));
                        
                        other.emit('message', answer);
                        
                        answer = {
                            'to': client.id,
                            'sid': message.sid,
                            'roomType': message.roomType,
                            'type': 'answer',
                            'payload': {
                                'type': 'answer',
                                'sdp': calleeSdpAnswer
                            },
                            'prefix': message.prefix,
                            'from': message.to
                        };
                        
                        console.info('Kurento generated SDP answer for callee (1st user): ' + JSON.stringify(answer));
                        
                        client.emit('message', answer);
                        
                    });
                    
                });
                
            });
            
        } else {
            
            message.from = client.id;
            other.emit('message', message);
            
        }
        
    });
    
    client.on('shareScreen', function () {
        client.resources.screen = true;
    });
    
    client.on('unshareScreen', function (type) {
        client.resources.screen = false;
        removeFeed('screen');
    });
    
    client.on('join', join);
    
    function removeFeed(type) {
        if (client.room) {
            io.sockets.in(client.room).emit('remove', {
                id: client.id,
                type: type
            });
            if (!type) {
                client.leave(client.room);
                client.room = undefined;
            }
        }
    }
    
    function join(name, cb) {
//        console.info('join ~ ' + name + ' ~ ' + cb);
        // sanity check
        if (typeof name !== 'string') return;
//        console.info(describeRoom(name));
        // leave any existing rooms
        removeFeed();
        safeCb(cb)(null, describeRoom(name));
        client.join(name);
        client.room = name;
    }
    
    // we don't want to pass "leave" directly because the
    // event type string of "socket end" gets passed too.
    client.on('disconnect', function () {
        removeFeed();
    });
    client.on('leave', function () {
        removeFeed();
    });
    
    client.on('create', function (name, cb) { // never called...?
//        console.info('create ~ ' + name + ' ~ ' + cb);
        if (arguments.length == 2) {
            cb = (typeof cb == 'function') ? cb : function () {};
            name = name || uuid();
        } else {
            cb = name;
            name = uuid();
        }
        // check if exists
        if (io.sockets.clients(name).length) {
            safeCb(cb)('taken');
        } else {
            join(name);
            safeCb(cb)(null, name);
        }
    });
    
    // tell client about stun and turn servers and generate nonces
    client.emit('stunservers', config.stunservers || []);
    
    // create shared secret nonces for TURN authentication
    // the process is described in draft-uberti-behave-turn-rest
    var credentials = [];
    config.turnservers.forEach(function (server) {
        var hmac = crypto.createHmac('sha1', server.secret);
        // default to 86400 seconds timeout unless specified
        var username = Math.floor(new Date().getTime() / 1000) + (server.expiry || 86400) + "";
        hmac.update(username);
        credentials.push({
            username: username,
            credential: hmac.digest('base64'),
            url: server.url
        });
    });
    client.emit('turnservers', credentials);
});

if (config.uid) process.setuid(config.uid);
console.info(yetify.logo() + ' -- signal master is running at: http://localhost:' + port);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: media-server.log
Type: application/octet-stream
Size: 23801 bytes
Desc: not available
URL: <https://lists.fiware.org/private/fiware-creatifi-coaching/attachments/20150302/6869a1ae/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signalmaster.log
Type: application/octet-stream
Size: 29625 bytes
Desc: not available
URL: <https://lists.fiware.org/private/fiware-creatifi-coaching/attachments/20150302/6869a1ae/attachment-0001.obj>


More information about the Fiware-creatifi-coaching mailing list

You can get more information about our cookies and privacy policies clicking on the following links: Privacy policy   Cookies policy