Presentación WebRTC y Lynckia
-
Upload
javier-cervino -
Category
Technology
-
view
7.656 -
download
0
description
Transcript of Presentación WebRTC y Lynckia
WebRTCComunicaciones en tiempo real desde tu navegador
Grupo de Internet de Nueva GeneraciónDepartamento de Ingeniería de Sistemas Telemáticos
Universidad Politécnica de Madrid
Pedro Rodriguez
[email protected]@lodoyun
Alvaro [email protected]
@larsonalonso
Joaquín Salvachú[email protected]
@jsalvachua
Nestor [email protected]
@nehko1
Javier Cerviñ[email protected]
@jcague
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Previously on GING
Isabel 1995 (o por ahi)Aplicación de escritorio
Ubuntu/Windows
P2P/Centralizado
Pasarelas SIP
Marte 2007Aplicación Flash sobre el navegador
Centralizado
Desktop
VaaS 2010Cloud Computing
Aplicación Flash sobre el navegador
Desktop y Móviles
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Índice
1. Introducción a WebRTC1. Descripción
2. Ejemplo de llamada
3. Estado actual
2. Problemas de WebRTC
3. Videoconferencia multiusuario1. Lynckia, componentes y API
2. Ejemplos
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Índice
1. Introducción a WebRTC1. Descripción
2. Ejemplo de llamada
3. Estado actual
2. Problemas de WebRTC
3. Videoconferencia multiusuario1. Lynckia, componentes y API
2. Ejemplos
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Videoconferencia en el navegador
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Navegador
JS/CSS/HTML
Navegador
JS/CSS/HTML
PROTOCOLOS PROPIETARIOSHTTP/WEBSOCKETS
TRANSMISIÓN
DE MEDIOS
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
APIs de WebRTC en JavaScript
Tres Grandes APIsgetUserMedia
Obtención de flujos locales
StreamAPIManejo de flujos multimedia
PeerConnectionConexiones entre pares
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
4
49
912
12
14
Alice Bob
1. getUserMedia()2. pc = new PeerConnection()3. onLocalSignallingMessage(sdpOffer)
5. getUserMedia()6. pc = new PeerConnection()7. pc.processSignalingMessage(sdpOffer)8. onLocalSignallingMessage(sdpAnswer)
10. pc.processSignalingMessage(sdpAnswer)11. onLocalSignallingMessage(sdpOk) 13. pc.processSignalingMessage(sdpOk)
Ejemplo de llamada
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Proyecto de código libre escrito en C++
Respaldado por Google, Mozilla y Opera entre otros.
Implementación de todo WebRTC
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Primera Fase• Librería en C++ implementando rtcweb
Segunda Fase• Inclusión de la librería en navegadores• Implica implementación del API JavaScript
Actualmente:• Primera versión disponible: iteraciones y pruebas
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Ericsson Labs
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Ericsson Labs
Bowser
Navegador Web en el móvil
Soporte WebRTC
Disponible para iOS y Android
https://labs.ericsson.com/apps/bowser
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Mozilla
Firefox 18 con soporte completo de WebRTC
GetUserMedia
StreamAPI
PeerConnection
Lanzamiento en enero de 2013
https://hacks.mozilla.org/2012/09/full-webrtc-support-is-soon-coming-to-a-web-browser-near-you/
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Internet Explorer
Soporte experimental de GetUserMedia
navigator.msGetUserMedia(options, cameraStarted);
function cameraStarted(mediaStream) {
msMediaStream = mediaStream;
document["imgPreview"].src = URL.createObjectURL(mediaStream);
}
http://blogs.msdn.com/b/ie/archive/2012/03/16/media-capture-prototype-improved-support-for-real-world-web-apps.aspx
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Opera
Soporta sólo getUserMedia
También tiene soporte en los móviles
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Índice
1. Introducción a WebRTC1. Descripción
2. Ejemplo de llamada
3. Estado actual
2. Problemas de WebRTC
3. Videoconferencia multiusuario1. Lynckia, componentes y API
2. Ejemplos
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Problemas de WebRTC
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Problemas de WebRTC
UMTSHSDPAHSPA+
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Problemas de WebRTC
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Problemas de WebRTC
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Problemas de WebRTC
MCU
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Índice
1. Introducción a WebRTC1. Descripción
2. Ejemplo de llamada
3. Estado actual
2. Problemas de WebRTC
3. Videoconferencia multiusuario1. Lynckia, componentes y API
2. Ejemplos
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Lynckia
Nuve
Erizo
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Lynckia - Salas
Una sala es una MCU
Permite publicar streams
Video, audio, datos
Permite subscribirse a ellos
Control desde el navegador
Permitirá transcodificar/grabar
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Lynckia - Nuve API
Accesible a través del Backend
Dirigido a servicios
Administración de salas
Gestiona la escalabilidad
Monitoriza
Creación de tokens
Nuve
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Lynckia - Erizo
Accesible a traves del Frontend
Contiene las MCUCada sala es una de ellas
Gestiona los streamsAudio, video y datos
Erizo
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Lynckia - Erizo
Erizo
Disponible en:
https://github.com/ging/erizo
Codigo C++
Protocolos WebRTC
Linux/Mac
Erizo API
Disponible en:
https://github.com/ging/erizoAPI
Wrapper en Node.js
Pronto a traves de NPM
Erizo
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Lynckia API
API ServidorRooms
Tokens
Users
API ClienteStreams
Rooms
Events
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
API Servidor
Comunicación con Nuve
API para gestión del ServicioSalas videoconferencia
Tokens autenticación
Usuarios
CódigoNode.js
Python
(Ruby)
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
API Servidor - Room
var N = require('./nuve');N.API.init(serviceId, serviceKey);
var roomName = 'myFirstRoom'; N.API.createRoom(roomName, function(room) { console.log('Room created with id: ', room._id);});
Propiedades Funciones
Room._id createRoom (name)
Room.name getRooms ()
getRoom (roomId)
deleteRoom (roomId)
Ejemplo
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
API Servidor - Token
String con las credenciales de autenticación
var roomId = '30121g51113e74fff3115502';var name = 'userName';var role = ''; N.API.createToken(room, name, role, function(token) { console.log('Token created: ', token);});
Funciones
createToken (roomId, name, role)
Ejemplo
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
API Servidor - User
var roomId = '30121g51113e74fff3115502'; N.API.getUsers(roomId, function(users) { console.log('This room has ', users.length, 'users'); for (var i in users) { console.log('User ', i, ':', users[i].name,
'role: ', users[i].role); }});
Propiedades Funciones
User.name getUsers (roomId)
User.role
Ejemplo
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Lynckia API
API ServidorRooms
Tokens
Users
API ClienteStreams
Rooms
Events
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
API Cliente
Comunicación con Erizo
Manejo flujos (Streams) Audio
Vídeo
Datos
Interacción salas (Rooms)Conexión
Intercambio flujos
Captura eventos (Events)En flujos
En salas
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
API Cliente - Stream (I)
var stream = Erizo.Stream({audio:false, video:true, data: true, attributes:
{name:'myStream', type: 'public'}});
Crear un Stream
stream.addEventListener('access-accepted', function(event) { console.log("Access to webcam and microphone granted");
stream.show('myVideoId');
});
stream.addEventListener('access-denied', function(event) { console.log("Access to webcam and microphone rejected");});
stream.init();
Iniciar y mostrar el Stream
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
var frame;var url;var ctx = document.getElementById('myCanvas').getContext('2d');var img = document.getElementById('myImg');
setInterval (function() {frame = stream.getVideoFrame();ctx.putImageData(frame, 0, 0);
url = stream.getVideoFrameURL();img.src = url;
}, 100);
API Cliente - Stream (II)
stream.addEventListener('stream-data', function(evt) {console.log('Received data ', evt.msg, 'from stream ', evt.stream.getID());
}
stream.sendData({text:'Hello world', timestamp:12321312});
Usando el Stream
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
API Cliente - Room (I)
var room = Erizo.Room({token:'213h8012hwduahd-321ueiwqewq'});
room.addEventListener('room-connected', function(roomEvent) {console.log('Connected! Streams in the room: ', roomEvent.streams);
}
room.connect();
Conectarse a una sala
room.addEventListener('stream-added', function(streamEvent) {if (localStream.getID() === streamEvent.stream.getID()) {
console.log('Published!');}
}
room.publish(localStream);
Publicar mi stream
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
API Cliente - Room (II)
room.addEventListener('stream-subscribed', function(streamEvent) {console.log('Subscribed to stream: ', streamEvent.stream.getID());
}
room.subscribe(stream);
Suscribirse a un Stream
room.addEventListener('stream-removed', function(streamEvent) {console.log('Removed stream: ', streamEvent.stream.getID());
}
room.unpublish(localStream);
room.unsubscribe(stream);
room.disconnect();
Y además…
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
room-connected (streams)
API Cliente - Events
Yo ERIZO Otros ClienteslocalStream.init()
access-accepted
room.connect()
room.subscribe (stream)
stream-subscribed
stream-added
room.publish (localStream)
stream-added
room.unpublish (stream)
stream-removedstream-removed
stream.sendData (msg) stream-data
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
localStream.addEventListener("access-accepted", function () {
room.connect();
localStream.show("myVideo");
});
<html><head><title>Lynckia Example</title>
<script type="text/javascript" src="http://…/erizo.js"></script>
</head>
<body>
<div id="myVideo" style="width:320px; height: 240px;”></div>
</body>
</html>
<script type="text/javascript”>
window.onload = function () {
var localStream = Erizo.Stream({audio: true, video: true, data: true});
var room = Erizo.Room({token: '213h8012hwduahd-321ueiwqewq'});
localStream.init();
};
</script>
ViaS
var subscribeToStreams = function (streams) {
for (var index in streams) {
var stream = streams[index];
if (localStream.getID() !== stream.getID())
room.subscribe(stream);
}
};
room.addEventListener("room-connected", function (roomEvent) {
room.publish(localStream);
subscribeToStreams(roomEvent.streams);
});
room.addEventListener("stream-subscribed", function(streamEvent) {var stream = streamEvent.stream;var div = document.createElement('div');div.setAttribute("style", "width: 320px; height: 240px;");div.setAttribute("id", "test" + stream.getID());document.body.appendChild(div);
stream.show("test" + stream.getID());});
room.addEventListener("stream-added", function (streamEvent) {
var streams = [];
streams.push(streamEvent.stream);
subscribeToStreams(streams);
});
room.addEventListener("stream-removed", function (streamEvent) {
var stream = streamEvent.stream;
if (stream.elementID !== undefined) {
var element = document.getElementById(stream.elementID);
document.body.removeChild(element);
}
});
Demos
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Demo: Guess Who!
http://www.youtube.com/watch?v=e3tn-uh5Wbo
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Demo: Guess Who!
myConfigStream = Erizo.Stream({audio: false, video: false, data: true, attributes: {name:
'configStream'}});room.publish(myConfigStream);
for (var cs in configStreams) {room.subscribe(configStreams[cs]);configStreams[cs].addEventListener("stream-data", function(evt) {
var msg = evt.msg; var stream = evt.stream;
});}myConfigStream.sendData({state: 'free'});
if (msg.state === 'free') { myConfigStream.sendData({state: 'selected', yourID: stream.getID()});
} else if (msg.state === 'selected' && msg.yourID === myConfigStream.getID()) {
myConfigStream.sendData({state: 'ok', yourID: stream.getID()});startPlaying(stream);
} else if (msg.state === 'ok’ && msg.yourID === myConfigStream.getID()) { startPlaying(stream); }
Basado en threede.js
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
MashMeTV
http://www.youtube.com/watch?v=3XZ-ffdPFH0
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Demo: MashMe TV
var canvas = document.createElement('canvas');canvas.id = "testing";canvas.width = "100px";canvas.height = "50px";document.body.appendChild(canvas);
var context = canvas.getContext('2d');
document.getElementById("myVideo").onclick = function() {
var frame = stream.getVideoFrame();context.putImageData(frame, 0, 0);
}
Javier Cerviño @jcague
Alvaro Alonso
@larsonalonso
Demo CSS 3D
http://www.youtube.com/watch?v=7wLTUaGJfQ0
Demo: 3D Game
room.addEventListener("stream-subscribed", function(streamEvent) {
var winDiv = document.createElement('div');winDiv.setAttribute("style", "width: 345x; height: 305px;");winDiv.setAttribute("id", "window");
world.addPlane( new PlaneVideo(winDiv, 345, 305, 30, 588, -400,90,0,0));streamEvent.stream.show('window');
}
function PlaneVideo(videodiv, w,h,x,y,z,rx,ry,rz, options) {
this.node = document.createElement("div"); this.node.appendChild(videodiv); … this.node.style.cssText +=
"-webkit-transform:" + "translate3d(" + x + "px," + y + "px," + z + "px)" + "rotateX(" + rx + "deg)" + "rotateY(" + ry + "deg)" + "rotateZ(" + rz + "deg);" + "-webkit-filter: blur(2px);";}
Muchas gracias!!Preguntas???
Javier Cerviñ[email protected]@jcague
Alvaro Alonso
[email protected]@larsonalonso