57
IETF 96 Hackathon 17 July 2016, Berlin

Nubomedia IETF96 hackathon - The platform

Embed Size (px)

Citation preview

Page 1: Nubomedia IETF96 hackathon - The platform

IETF 96 Hackathon17 July 2016, Berlin

Page 2: Nubomedia IETF96 hackathon - The platform

Table of contents

1. Introduction2. NUBOMEDIA APIs/SDKs3. NUBOMEDIA PaaS4. Let's get to work

Page 3: Nubomedia IETF96 hackathon - The platform

Table of contents

1. Introduction− Review− What is NUBOMEDIA?− References

2. NUBOMEDIA APIs/SDKs3. NUBOMEDIA PaaS4. Let's get to work

Page 4: Nubomedia IETF96 hackathon - The platform

1. IntroductionReview− Kurento is a media server and a set of APIs

aimed to create applications with advance media capabilities

− The building blocks for applications are named media elements, chained into media pipelines

Page 5: Nubomedia IETF96 hackathon - The platform

1. IntroductionWhat is NUBOMEDIA?−NUBOMEDIA is an open source PaaS (Platform as a Service) based on Kurento−NUBOMEDIA exposes to developers the ability of deploying and leveraging applications with media capabilities:

• WebRTC, media recording, group communications, computer vision, augmented reality…

Page 6: Nubomedia IETF96 hackathon - The platform

1. IntroductionWhat is NUBOMEDIA?− NUBOMEDIA is the first WebRTC PaaS

Page 7: Nubomedia IETF96 hackathon - The platform

1. IntroductionWhat is NUBOMEDIA?−From the developer’s perspective, NUBOMEDIA capabilities are accessed through a set of APIs/SDKs−NUBOMEDIA applications can be deployed using the NUBOMEDIA PaaS Manager

We are going to see this features in detail in this presentation

Page 8: Nubomedia IETF96 hackathon - The platform

1. IntroductionReferences− Home page

http://www.nubomedia.eu/− Developers guide

http://nubomedia.readthedocs.io/− GitHub organization

https://github.com/nubomedia/− Support for developers

https://groups.google.com/forum/#!forum/nubomedia-dev

Page 9: Nubomedia IETF96 hackathon - The platform

Table of contents

1. Introduction2. NUBOMEDIA APIs/SDKs

− Development model− NUBOMEDIA APIs− NUBOMEDIA SDKs

3. NUBOMEDIA PaaS4. Let's get to work

Page 10: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsDevelopment model− The development model in NUBOMEDIA is the

same than in Kurento• Three-tier model (inspired in the Web)

Client Application Server Media Server

NUBOMEDIA PaaS

Page 11: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsDevelopment model− Like every application with media capabilities, it

is important to distinguish between the media and signaling plane

Client Application Server Media Server

NUBOMEDIA PaaS

signaling

media

Page 12: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsDevelopment model

NUBOMEDIA Big Picture

Page 13: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs

API Description

Media API Enables developers consuming the Media Server capabilities among which we can find media transport, media archiving, media processing, media transcoding, and so on

WebRtcPeer API Abstracts the client WebRTC media capabilities, exposing the media capture and communication capabilities of a browser in a seamless way

Repository API Makes possible to access an elastic scalable media repository for archiving media information and meta-information

Signaling API Provides a simple signaling mechanism based on JSON-RPCs for applications

Room API Enables application developers functionalities to create group communication applications adapted to real social interactions

Tree API Allows developers to build video broadcasting web applications

Page 14: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Media API− Media API allows to Java developers consume

the media services provided by Kurento Media Server (KMS)

− Concepts:• Media Element• Media Pipeline

Page 15: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Media API− KMS instances are provided elastically by NUBOMEDIA

• The number of available KMS instances depends on the PaaS Manager configuration (next section)

− Each KMS has a total amount of available points to create Media Pipelines and Media Elements• The total points depends on the number of VCPUs of the KMS• The type of the instance can be selected on the PaaS Manager

configuration (next section)

Instance type # VCPUs KMS pointsMedium 2 200

Large 4 400

Page 16: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Media API− Each KMS is controlled by an instance of KurentoClient

− With each media session an instance of KurentoClient should be created

− The number of available points per KMS decreases with each Media Element creation (scaling in/out)

<dependency> <groupId>org.kurento</groupId> <artifactId>kurento-client</artifactId></dependency>

<dependency> <groupId>de.fhg.fokus.nubomedia</groupId> <artifactId>nubomedia-media-client</artifactId></dependency>

Dependencies (Maven)

KurentoClient kurentoClient = KurentoClient.create();

Page 17: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Media API− Example: nubomedia-magic-mirror // One KurentoClient instance per sessionKurentoClient kurentoClient = KurentoClient.create();

// Media logic (pipeline and media elements connectivity)MediaPipeline mediaPipeline = kurentoClient.createMediaPipeline();

WebRtcEndpoint webRtcEndpoint = new WebRtcEndpoint.Builder(mediaPipeline).build();FaceOverlayFilter faceOverlayFilter = new FaceOverlayFilter.Builder(mediaPipeline).build();faceOverlayFilter.setOverlayedImage("http://files.kurento.org/img/mario-wings.png", -0.35F, -1.2F, 1.6F, 1.6F);

webRtcEndpoint.connect(faceOverlayFilter);faceOverlayFilter.connect(webRtcEndpoint);

Page 18: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Repository API− NUBOMEDIA provides access to a Kurento Repository

in order to store and recover multimedia streams (and metadata)

− The repository is controlled by an instance of RepositoryClient (Java)

<dependency> <groupId>de.fhg.fokus.nubomedia</groupId> <artifactId>nubomedia-media-client</artifactId></dependency><dependency> <groupId>de.fhg.fokus.nubomedia</groupId> <artifactId>nubomedia-repository-client</artifactId></dependency>

Dependencies (Maven)

RepositoryClient repositoryClient = RepositoryClientProvider.create();

Page 19: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Repository API− Example: nubomedia-repository-tutorial

The first step is to carry out the WebRTC loopback communication. We can see the live media while it is being recorded in the repository.

After that, we are able to reproduce the recording, reading the media stored in the repository.

Page 20: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Repository API− Example: nubomedia-repository-tutorial// KurentoClientkurentoClient = KurentoClient.create();

// Media pipelinemediaPipeline = kurentoClient.createMediaPipeline();

// Repository item (recorder)Map<String, String> metadata = Collections.emptyMap();repositoryItemRecorder = repositoryClient.createRepositoryItem(metadata);

// Media elements and connectivitywebRtcEndpoint = new WebRtcEndpoint.Builder(mediaPipeline).build();recorderEndpoint = new RecorderEndpoint.Builder(mediaPipeline, repositoryItemRecorder.getUrl()).withMediaProfile(MediaProfileSpecType.WEBM).build();webRtcEndpoint.connect(webRtcEndpoint);webRtcEndpoint.connect(recorderEndpoint);

// WebRTC negotiationString sdpAnswer = performWebRtcNegotiation(session, sdpOffer);

// Start recordingrecorderEndpoint.record();

Page 21: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Repository API− Example: nubomedia-repository-tutorial// KurentoClientkurentoClient = KurentoClient.create();

// Media pipelinemediaPipeline = kurentoClient.createMediaPipeline();

// Repository item (player)RepositoryItemPlayer repositoryItemPlayer = repositoryClient.getReadEndpoint(repositoryItemRecorder.getId());

// Media elements and connectivitywebRtcEndpoint = new WebRtcEndpoint.Builder(mediaPipeline).build();playerEndpoint = new PlayerEndpoint.Builder(mediaPipeline, repositoryItemPlayer.getUrl()) .build();

playerEndpoint.connect(webRtcEndpoint);

// WebRTC negotiationString sdpAnswer = performWebRtcNegotiation(session, sdpOffer);

// Start playingplayerEndpoint.play();

Page 22: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - WebRtcPeer API− JavaScript API that abstracts the client RTC media

(Media Capture and PeerConnection)<dependency> <groupId>org.kurento</groupId> <artifactId>kurento-utils-js</artifactId></dependency>

Maven dependency

<script src="js/kurento-utils.js"></script>

var options = { localVideo : videoInput, remoteVideo : videoOutput, onicecandidate : onIceCandidate}

webRtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv(options, function(error) { if (error) { return console.error(error); } webRtcPeer.generateOffer(onOffer); });}

JavaScript library

Example of use (send-receive)

Page 23: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Signaling API− NUBOMEDIA capabilities can be accessed through any

kind of signaling protocol (e.g. SIP, XMPP or REST)− NUBOMEDIA provides a very signaling protocol based

on JSON-RPCs over WebSockets− This API has several components

• Server signaling API• JavaScript client signaling API• Android client signaling API• iOS client signaling API

http://nubomedia.readthedocs.io/en/latest/api/signaling/

Page 24: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Room API− The Room API is a high-level communications library

that provides capabilities for managing multi-conference WebRTC sessions. It has the following components:• Room Server: a container-based implementation of the server,

uses JSON-RPC over WebSockets for communications with the clients

• Room JavaScript Client: module implementing a Room client for Web applications

• Room Client: a client library for Java web applications or Android clients

Page 25: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Room API− Example: nubomedia-room-tutorial

<dependency> <groupId>org.kurento</groupId> <artifactId>kurento-room-server</artifactId></dependency><dependency> <groupId>org.kurento</groupId> <artifactId>kurento-room-client-js</artifactId></dependency>

Dependencies (Maven)

public class SingleKmsManager extends KmsManager {

@Override public KurentoClient getKurentoClient(KurentoClientSessionInfo sessionInfo) throws RoomException { return KurentoClient.create(); }

@Override public boolean destroyWhenUnused() { return true; }

}

Server-side: KurentoClient management

Page 26: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Room API− Example: nubomedia-room-tutorial

var kurento = KurentoRoom(wsUri, function (error, kurento) { if (error) return console.log(error);

room = kurento.Room({ room: $scope.roomName, user: $scope.userName, updateSpeakerInterval: $scope.updateSpeakerInterval, thresholdSpeaker: $scope.thresholdSpeaker });

var localStream = kurento.Stream(room, {audio: true, video: true, data: true});

localStream.addEventListener("access-accepted", function () { room.addEventListener("room-connected", function (roomEvent) { var streams = roomEvent.streams; localStream.publish(); ServiceRoom.setLocalStream(localStream.getWebRtcPeer()); for (var i = 0; i < streams.length; i++) { ServiceParticipant.addParticipant(streams[i]); } });

// ...});

Client-side room management

Page 28: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA APIs - Tree API− The NUBOMEDIA Tree API allows developers to build

WebRTC broadcasting applications− This API is composed by a server and two clients:

• tree-server is a component of the API designed to be deployed and controlled by clients

• tree-client implements a tree client designed to be used in Java web applications or Android applications. The client contains an implementation of JSON-RPC WebSocket protocol implemented by Tree server

• tree-client-js implements a tree client to be used in Single Page Applications (SPA)

Page 29: Nubomedia IETF96 hackathon - The platform

2. NUBOMEDIA APIs/SDKsNUBOMEDIA SDKs

− More info on:• http://webrtcpeer-android.readthedocs.io/• http://jsonrpc-ws-android.readthedocs.io/• http://kurento-room-client-android.readthedocs.io/• http://kurento-ios.readthedocs.io/

SDK Description

Android SDK Android version of the client-side NUBOMEDIA APIs: WebRtcPeer, Signaling, Room, Tree

iOS SDK Complete SDK to provide NUBOMEDIA client capabilities to iOS devices

Page 30: Nubomedia IETF96 hackathon - The platform

Table of contents

1. Introduction2. NUBOMEDIA APIs/SDKs3. NUBOMEDIA PaaS

− Introduction− PaaS GUI

4. Let's get to work

Page 31: Nubomedia IETF96 hackathon - The platform

3. NUBOMEDIA PaaSIntroduction− The NUBOMEDIA PaaS manager is a tool aimed to

control the way in which the NUBOMEDIA applications are built and deployed inside the NUBOMEDIA PaaS

− The capabilities provided by the Paas Manager can be used by developers using the PaaS GUI:• The PaaS Manager GUI is a web application that allows to use

the NUBOMEDIA PaaS Manager

Page 32: Nubomedia IETF96 hackathon - The platform

3. NUBOMEDIA PaaSIntroduction− Internally, the NUBOMEDIA PaaS uses Docker

containers to deploy applications− Therefore it is a requirement to include a Dockerfile in

GitHub repository to be deployed on NUBOMEDIA− Example: FROM nubomedia/apps-baseimage:src

MAINTAINER Nubomedia

ADD keystore.jks /ADD . /home/nubomedia

RUN sudo chown -R nubomedia /home/nubomediaRUN cd /home/nubomedia && mvn compile

ENTRYPOINT cd /home/nubomedia && mvn exec:java

https://docs.docker.com/engine/reference/builder/

Page 33: Nubomedia IETF96 hackathon - The platform

3. NUBOMEDIA PaaSPaaS GUI− Web application to manage NUBOMEDIA applications

http://paas-manager.nubomedia.eu:8081/

Credentials needed to login

Home shows a summary of the apps currently deployed

Page 34: Nubomedia IETF96 hackathon - The platform

3. NUBOMEDIA PaaSPaaS GUI− A NUBOMEDIA application can be deployed using the

PaaS GUI− It is done providing the GitHub repository URL and a set

of configuration parameters

Page 35: Nubomedia IETF96 hackathon - The platform

3. NUBOMEDIA PaaSPaaS GUI− Most important configuration values:

− For the rest of parameters take a look to the doc:http://nubomedia.readthedocs.io/en/latest/paas/paas-gui/

Number of KMSs

KMS host type:- Medium = 2 VCPUs (200 points)- Large = 4 VCPUs (400 points)

Page 36: Nubomedia IETF96 hackathon - The platform

Table of contents

1. Introduction2. NUBOMEDIA APIs/SDKs3. NUBOMEDIA PaaS4. Let's get to work

− Introduction− Server-side− Client-side− Deployment

Page 37: Nubomedia IETF96 hackathon - The platform

4. Let's get to workIntroduction− Devil is in the details, and so, we are going to see a

complete NUBOMEDIA step by step− This applications the nubomedia-magic-mirror tutorial

https://github.com/nubomedia/nubomedia-magic-mirror/

http://nubomedia.readthedocs.io/en/latest/tutorial/nubomedia-magic-mirror/

Page 38: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-side− We recommend Spring-Boot as the base technology for

NUBOMEDIA applications• Spring-Boot embeds a Tomcat server in a simple seamless way

for developers• The application is packaged as a runnable JAR, and when this

JAR is executed, the Tomcat server is started and the web application automatically deployed

− We recommend Maven as for managing the life-cycle and managing the dependencies of our applications

Page 39: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-side− The first step is to clone GitHub repository

− We recommend use an IDE to develop applications. For example, Eclipse (importing app as Maven project)

git clone https://github.com/nubomedia/nubomedia-magic-mirror

Page 40: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-side− First step is understand the pom.xml file:

<parent> <groupId>org.kurento</groupId> <artifactId>kurento-parent-pom</artifactId> <version>6.5.0</version></parent>

<properties> <!-- Nubomedia --> <nubomedia-media-client.version>1.0.2</nubomedia-media-client.version>

<!-- Main class --> <start-class>eu.nubomedia.tutorial.magicmirror.MagicMirrorApp</start-class></properties>

Inherit from kurento-parent-pom makes simpler our pom.xml by reusing versions defined in the parent

It’s important declare the fully qualified name of the main class

Page 41: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-side

<dependencies> <!-- Spring --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> </dependency>

<!-- Kurento --> <dependency> <groupId>org.kurento</groupId> <artifactId>kurento-client</artifactId> </dependency> <dependency> <groupId>org.kurento</groupId> <artifactId>kurento-utils-js</artifactId> </dependency>

<!-- Nubomedia --> <dependency> <groupId>de.fhg.fokus.nubomedia</groupId> <artifactId>nubomedia-media-client</artifactId> <version>${nubomedia-media-client.version}</version> </dependency></dependencies>

Dependencies clause is one of the most important. Notice that our app depends on Spring, Kurento, and NUBOMEDIA

Page 42: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-side− We need to define also the way

in which signaling is going to work in our application

− For the shake of simplicity, we use a raw WebSocket between the server and client side

− We need to define the messages exchanged to carry out the communication about client and server

clientserver

start

startResponse

iceCandidate

onIceCandidate

stop

error

notEnoughResources

Starts a media session

ICE candidates (WebRTC negotiation)

Stops a media session

Error cases

Page 43: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-side− The class diagram of our application is the following:

MagicMirrorApp

MagicMirrorHandler

UserSession

Main class

Message handler (signaling)

User session (session id, media logic)

Page 44: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-side

@SpringBootApplication@EnableWebSocketpublic class MagicMirrorApp implements WebSocketConfigurer {

@Bean public MagicMirrorHandler handler() { return new MagicMirrorHandler(); }

@Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(handler(), "/magicmirror"); }

public static void main(String[] args) throws Exception { new SpringApplication(MagicMirrorApp.class).run(args); }}

MagicMirrorApp defines the Spring-Boot application and the WebSocket used for signaling ("/magicmirror", managed by MagicMirrorHandler)

Page 45: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-sidepublic class MagicMirrorHandler extends TextWebSocketHandler {

private final ConcurrentHashMap<String, UserSession> users = new ConcurrentHashMap<>();

@Override public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { JsonObject jsonMessage = new GsonBuilder().create().fromJson(message.getPayload(), JsonObject.class); switch (jsonMessage.get("id").getAsString()) { case "start": start(session, jsonMessage); break; case "stop": release(session); break; case "onIceCandidate": onIceCandidate(session, jsonMessage); break; default: error(session, "Invalid message with id " + jsonMessage.get("id").getAsString()); break; } }

MagicMirrorHandler manages signaling messages. It keeps a collection of user sessions (thread-safe map users)

Page 46: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-sidepublic class UserSession {

public String startSession(final WebSocketSession session, String sdpOffer) { // One KurentoClient instance per session kurentoClient = KurentoClient.create(); log.info("Created kurentoClient (session {})", sessionId);

// Media logic (pipeline and media elements connectivity) mediaPipeline = kurentoClient.createMediaPipeline(); log.info("Created Media Pipeline {} (session {})", mediaPipeline.getId(), sessionId);

webRtcEndpoint = new WebRtcEndpoint.Builder(mediaPipeline).build(); FaceOverlayFilter faceOverlayFilter = new FaceOverlayFilter.Builder(mediaPipeline).build(); faceOverlayFilter.setOverlayedImage("http://files.kurento.org/img/mario-wings.png", -0.35F, -1.2F, 1.6F, 1.6F); webRtcEndpoint.connect(faceOverlayFilter); faceOverlayFilter.connect(webRtcEndpoint);

// WebRTC negotiation String sdpAnswer = webRtcEndpoint.processOffer(sdpOffer); webRtcEndpoint.gatherCandidates();

return sdpAnswer; }

UserSession handles media logic (media pipeline, media elements, WebRTC negotiation…)

Page 47: Nubomedia IETF96 hackathon - The platform

4. Let's get to workServer-side− As of Chrome 47, access to user media can only be

done by secure apps (HTTPS), and so, it is needed a Java keystore

server.port: 8443server.ssl.key-store: keystore.jksserver.ssl.key-store-password: kurentoserver.ssl.keyStoreType: JKSserver.ssl.keyAlias: kurento-selfsigned

application.properties

http://doc-kurento.readthedocs.io/en/stable/mastering/securing-kurento-applications.html

Page 48: Nubomedia IETF96 hackathon - The platform

4. Let's get to workClient-side− Client-side dependencies are handled by Bower− Our bower.json file contains:

− In addition the file .bowerrc configures the target path for the JavaScript libraries

"dependencies": { "bootstrap": "~3.3.0", "ekko-lightbox": "~3.1.4", "adapter.js": "v0.2.9", "demo-console": "1.5.1" }

{ "directory" : "static/bower_components"}

Page 49: Nubomedia IETF96 hackathon - The platform

4. Let's get to workClient-side− The app has been implemented as a SPA (single page

application) which contains a single HTML<!DOCTYPE html><html><head><link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css"><link rel="stylesheet" href="bower_components/ekko-lightbox/dist/ekko-lightbox.min.css"><link rel="stylesheet" href="bower_components/demo-console/index.css"><link rel="stylesheet" href="css/styles.css">

<script src="bower_components/jquery/dist/jquery.min.js"></script><script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script><script src="bower_components/ekko-lightbox/dist/ekko-lightbox.min.js"></script><script src="bower_components/adapter.js/adapter.js"></script><script src="bower_components/demo-console/index.js"></script>

<script src="js/kurento-utils.js"></script><script src="js/index.js"></script><title>NUBOMEDIA Tutorial: WebRTC Magic Mirror</title></head>

JavaScript/CSS are linked here. Using Bootstrap to provide responsive design

Page 50: Nubomedia IETF96 hackathon - The platform

4. Let's get to workClient-side− A JavaScript file contains the client-side logic (message

handling and WebRtcPeer use)var ws = new WebSocket('wss://' + location.host + '/magicmirror');

ws.onmessage = function(message) { var parsedMessage = JSON.parse(message.data); switch (parsedMessage.id) { case 'startResponse': startResponse(parsedMessage); break; case 'error': onError("Error message from server: " + parsedMessage.message); stop(false); break; case 'iceCandidate': webRtcPeer.addIceCandidate(parsedMessage.candidate, function(error) { if (error) return console.error("Error adding candidate: " + error); }); break; // ... }}

Page 51: Nubomedia IETF96 hackathon - The platform

4. Let's get to workClient-side− A JavaScript file contains the client-side logic (message

handling and WebRtcPeer use)var webRtcPeer;

function start() { var options = { localVideo : videoInput, remoteVideo : videoOutput, onicecandidate : onIceCandidate } webRtcPeer = new kurentoUtils.WebRtcPeer.WebRtcPeerSendrecv(options, function(error) { if (error) { return console.error(error); } webRtcPeer.generateOffer(onOffer); });}

Page 52: Nubomedia IETF96 hackathon - The platform

4. Let's get to workDeployment− We need a Dockerfile to deploy our app

FROM nubomedia/apps-baseimage:src

MAINTAINER Nubomedia

ADD keystore.jks /ADD . /home/nubomedia

RUN sudo chown -R nubomedia /home/nubomediaRUN cd /home/nubomedia && mvn compile

ENTRYPOINT cd /home/nubomedia && mvn exec:java

Page 53: Nubomedia IETF96 hackathon - The platform

4. Let's get to workDeployment− Finally we can deploy our app in the NUBOMEDIA PaaS

Manager:

Page 54: Nubomedia IETF96 hackathon - The platform

4. Let's get to workDeployment− The app changes its state, from CREATED to RUNNING (it

takes a couple of minutes to finish):

Page 55: Nubomedia IETF96 hackathon - The platform

4. Let's get to workDeployment− We can trace two types of logs: build and app

I0708 12:51:02.335080 1 builder.go:41] $BUILD env var is {"kind":"Build","apiVersion":"v1","metadata":{...} I0708 12:51:02.423366 1 source.go:96] git ls-remote https://github.com/nubomedia/nubomedia-magic-mirror --headsI0708 12:51:02.423547 1 repository.go:275] Executing git ls-remote https://github.com/nubomedia/nubomedia-magic-mirror --headsI0708 12:51:04.931566 1 source.go:189] Cloning source from https://github.com/nubomedia/nubomedia-magic-mirror

...

Image already existslatest: digest: sha256:24ac51ca448edfb1582f0bffc990c95506065f0aa26d5b295d1cb32d35ce2dfe size: 49623I0708 12:54:31.392578 1 docker.go:99] Push successful

Page 56: Nubomedia IETF96 hackathon - The platform

4. Let's get to workDeployment− We can trace two types of logs: build and app[INFO] Scanning for projects...[INFO] [INFO] ----------------------------------------[INFO] Building NUBOMEDIA Java Tutorial - Magic Mirror 6.5.0[INFO] ----------------------------------------[INFO] [INFO] --- exec-maven-plugin:1.4.0:java (default-cli) @ nubomedia-magic-mirror --- `.-:////:-.` -+shmmmmmmmmmmmmmmhs/- `/ymmmmmmmmmmmmmmmmmmmmmmmms/` -smmmmmmmmyo+/:----:/+ohmmmmmmmms. -ymmmmmmy+. -+hmmmmmmy. -------` `ommmmmd+` .+dmmmmmo +oooooo- .hmmmmm+ `ommmmmh` +oooooo- .dmmmmh. ``````` +oooooo- sdddddds `dmmmmy .dhhhhhh. ```````` smmmmmmy ./+osyysymmmmy .mmmmmmm. smmmmmmy `:sdmmmmmmmmmmmmd` .mmmmmmm. -----` +yyyyyy+ `+dmmmmmmdhyyyhdmm+ .hhhhhhh. ooooo- -------- -dmmmmmy:` `:` ooooo- .----. oooooooo` -mmmmmy. .....` hmmmms oooooooo` dmmmms yhd- hmmmms oooooooo` :mmmmm` syy- /++++: :::::::: /mmmmm `mmmmm/ -ss: os` os` -s/ -ssssss+- .+syys+. -//. ://` .::///- -/////:. // .//` +mmmmm: :mdm/ hm. hm. /mo :my---/mm`:md:..:dm/ /o+o` -o+o` /o:.```` :o:``.:o+ oo `o/++ smmmmh :ms:m+ ym. hm. /mo :mh+++smo ym/ :mh /o.o: `o/:o`.oo:::::. :o- /o- oo +o`.o/ /mmmh :ms :moym. hm. /mo :my:::+mh sm+ /my /o.-o./o`/o`.oo.....` :o- +o- oo /o+//+o: `odh :ms -mmm. +my::/dm- :my///omm`.dm+::+mm- /o. +oo: /o` :o/----. :o/---/o/ oo -o:..../o. - .+: .++` ./+++:` .++++++:` `:+oo+:` .-` `-- .-` `-----. .------` -- -- `--

...2016-07-08 12:55:32.702 INFO 6 --- [irrorApp.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8443 (https)2016-07-08 12:55:32.713 INFO 6 --- [irrorApp.main()] e.n.tutorial.magicmirror.MagicMirrorApp : Started MagicMirrorApp in 10.529 seconds (JVM running for 31.135)

Page 57: Nubomedia IETF96 hackathon - The platform

4. Let's get to workDeployment− Ta da!