From 4812db2fadb86d1d6894f7397dc8f252ad32ad7b Mon Sep 17 00:00:00 2001 From: pabloFuente Date: Tue, 22 Aug 2017 13:27:44 +0200 Subject: [PATCH] Simple video test in the dashboard (non secure openvidu-server only) --- .../src/angular/frontend/package.json | 2 +- .../frontend/src/app/app.material.module.ts | 24 +- .../dashboard/dashboard.component.css | 195 +- .../dashboard/dashboard.component.html | 23 +- .../dashboard/dashboard.component.ts | 78 +- .../src/angular/frontend/src/index.html | 3 + .../src/angular/frontend/src/styles.css | 8 + .../src/main/resources/static/index.html | 3 + .../resources/static/inline.bundle.js.map | 2 +- .../src/main/resources/static/main.bundle.js | 1915 +++- .../main/resources/static/main.bundle.js.map | 2 +- .../main/resources/static/polyfills.bundle.js | 98 +- .../resources/static/polyfills.bundle.js.map | 2 +- .../main/resources/static/styles.bundle.js | 12 +- .../resources/static/styles.bundle.js.map | 2 +- .../main/resources/static/vendor.bundle.js | 9501 ++++++++--------- .../resources/static/vendor.bundle.js.map | 2 +- 17 files changed, 6526 insertions(+), 5346 deletions(-) diff --git a/openvidu-server/src/angular/frontend/package.json b/openvidu-server/src/angular/frontend/package.json index 1d053754..d75b373d 100644 --- a/openvidu-server/src/angular/frontend/package.json +++ b/openvidu-server/src/angular/frontend/package.json @@ -19,7 +19,7 @@ "@angular/flex-layout": "^2.0.0-beta.8", "@angular/forms": "^4.0.0", "@angular/http": "^4.0.0", - "@angular/material": "2.0.0-beta.5", + "@angular/material": "2.0.0-beta.7", "@angular/platform-browser": "^4.0.0", "@angular/platform-browser-dynamic": "^4.0.0", "@angular/router": "^4.0.0", diff --git a/openvidu-server/src/angular/frontend/src/app/app.material.module.ts b/openvidu-server/src/angular/frontend/src/app/app.material.module.ts index f3f3b192..1da1d80c 100644 --- a/openvidu-server/src/angular/frontend/src/app/app.material.module.ts +++ b/openvidu-server/src/angular/frontend/src/app/app.material.module.ts @@ -4,11 +4,29 @@ import { MdButtonModule, MdCheckboxModule, MdCardModule, - MdInputModule + MdInputModule, + MdProgressSpinnerModule, + MdTooltipModule } from '@angular/material'; @NgModule({ - imports: [BrowserAnimationsModule, MdButtonModule, MdCheckboxModule, MdCardModule, MdInputModule], - exports: [BrowserAnimationsModule, MdButtonModule, MdCheckboxModule, MdCardModule, MdInputModule], + imports: [ + BrowserAnimationsModule, + MdButtonModule, + MdCheckboxModule, + MdCardModule, + MdInputModule, + MdProgressSpinnerModule, + MdTooltipModule + ], + exports: [ + BrowserAnimationsModule, + MdButtonModule, + MdCheckboxModule, + MdCardModule, + MdInputModule, + MdProgressSpinnerModule, + MdTooltipModule + ], }) export class AppMaterialModule { } diff --git a/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.css b/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.css index 70571c96..a7a78a9f 100644 --- a/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.css +++ b/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.css @@ -3,7 +3,7 @@ } #log { - height: 100%; + height: 90%; } #log-content { @@ -17,6 +17,195 @@ ul { margin: 0; } -md-card-title a { - float: right; +button.mat-raised-button { + text-transform: uppercase; + float: right; +} + +md-card-title button.blue { + color: #ffffff; + background-color: #0088aa; +} + +md-card-title button.yellow { + color: rgba(0, 0, 0, 0.87); + background-color: #ffcc00; +} + +md-spinner { + position: absolute; + top: 55%; + left: 50%; + transform: translate(-50%, -50%); +} + +#tick-div { + width: 100px; + height: 100px; + z-index: 1; + position: absolute; + top: 55%; + left: 50%; + transform: translate(-50%, -50%); +} + +#tooltip-tick { + position: absolute; + width: 100%; + height: 100%; + z-index: 2; +} + +.circ { + opacity: 0; + stroke-dasharray: 130; + stroke-dashoffset: 130; + -webkit-transition: all 1s; + -moz-transition: all 1s; + -ms-transition: all 1s; + -o-transition: all 1s; + transition: all 1s; +} + +.tick { + stroke-dasharray: 50; + stroke-dashoffset: 50; + -webkit-transition: stroke-dashoffset 1s 0.5s ease-out; + -moz-transition: stroke-dashoffset 1s 0.5s ease-out; + -ms-transition: stroke-dashoffset 1s 0.5s ease-out; + -o-transition: stroke-dashoffset 1s 0.5s ease-out; + transition: stroke-dashoffset 1s 0.5s ease-out; +} + +.drawn+svg .path { + opacity: 1; + stroke-dashoffset: 0; +} + + +/* Pure CSS loader */ + +#loader { + width: 100px; + height: 100px; + z-index: 1; + position: absolute; + top: 55%; + left: 50%; + -webkit-transform: translate(-50%, -50%); + transform: translate(-50%, -50%); +} + +#loader * { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#loader ::after { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +#loader ::before { + -webkit-box-sizing: border-box; + box-sizing: border-box; +} + +.loader-1 { + height: 100px; + width: 100px; + -webkit-animation: loader-1-1 4.8s linear infinite; + animation: loader-1-1 4.8s linear infinite; +} + +@-webkit-keyframes loader-1-1 { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(360deg); + } +} + +@keyframes loader-1-1 { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} + +.loader-1 span { + display: block; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: auto; + height: 100px; + width: 100px; + clip: rect(0, 100px, 100px, 50px); + -webkit-animation: loader-1-2 1.2s linear infinite; + animation: loader-1-2 1.2s linear infinite; +} + +@-webkit-keyframes loader-1-2 { + 0% { + -webkit-transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(220deg); + } +} + +@keyframes loader-1-2 { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(220deg); + } +} + +.loader-1 span::after { + content: ""; + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + margin: auto; + height: 100px; + width: 100px; + clip: rect(0, 100px, 100px, 50px); + border: 8px solid #4d4d4d; + border-radius: 50%; + -webkit-animation: loader-1-3 1.2s cubic-bezier(0.770, 0.000, 0.175, 1.000) infinite; + animation: loader-1-3 1.2s cubic-bezier(0.770, 0.000, 0.175, 1.000) infinite; +} + +@-webkit-keyframes loader-1-3 { + 0% { + -webkit-transform: rotate(-140deg); + } + 50% { + -webkit-transform: rotate(-160deg); + } + 100% { + -webkit-transform: rotate(140deg); + } +} + +@keyframes loader-1-3 { + 0% { + transform: rotate(-140deg); + } + 50% { + transform: rotate(-160deg); + } + 100% { + transform: rotate(140deg); + } } \ No newline at end of file diff --git a/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.html b/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.html index e787decf..4179dc3a 100644 --- a/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.html +++ b/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.html @@ -16,10 +16,27 @@
- Test the connectionTest + Test the connection + -
-
+
+
+
+
+ +
+
+
+ + + + +
+
diff --git a/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.ts b/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.ts index c5305985..e243b2f1 100644 --- a/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.ts +++ b/openvidu-server/src/angular/frontend/src/app/components/dashboard/dashboard.component.ts @@ -1,22 +1,31 @@ -import { Component, OnInit, AfterViewChecked, ViewChild, ElementRef } from '@angular/core'; +import { Component, OnInit, AfterViewChecked, ViewChild, ElementRef, HostListener, OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; import { InfoService } from '../../services/info.service'; -import { OpenVidu } from 'openvidu-browser'; +import { OpenVidu, Session } from 'openvidu-browser'; + +declare const $; @Component({ selector: 'app-dashboard', templateUrl: './dashboard.component.html', styleUrls: ['./dashboard.component.css'], }) -export class DashboardComponent implements OnInit, AfterViewChecked { +export class DashboardComponent implements OnInit, OnDestroy, AfterViewChecked { @ViewChild('scrollMe') private myScrollContainer: ElementRef; infoSubscription: Subscription; info = []; + session: Session; + + testStatus = 'DISCONNECTED'; + testButton = 'Test'; + tickClass = 'trigger'; + showSpinner = false; + constructor(private infoService: InfoService) { // Subscription to info updated event raised by InfoService @@ -30,32 +39,81 @@ export class DashboardComponent implements OnInit, AfterViewChecked { } + @HostListener('window:beforeunload') + beforeunloadHandler() { + // On window closed leave test session + if (this.session) { + this.endTestVideo(); + } + } + + ngOnDestroy() { + // On component destroyed leave test session + if (this.session) { + this.endTestVideo(); + } + } + ngAfterViewChecked() { this.scrollToBottom(); } + toggleTestVideo() { + if (!this.session) { + this.testVideo(); + } else { + this.endTestVideo(); + } + } + testVideo() { let OV = new OpenVidu(); - let session = OV.initSession('wss://' + location.hostname + ':8443/testSession'); + this.session = OV.initSession('wss://' + location.hostname + ':8443/testSession'); - session.on('streamCreated', (event) => { - session.subscribe(event.stream, 'mirrored-video'); + this.session.on('streamCreated', (event) => { + this.session.subscribe(event.stream, 'mirrored-video'); }); - session.connect('token', (error) => { + this.testStatus = 'CONNECTING'; + this.testButton = 'Testing...'; + + this.session.connect('token', (error) => { if (!error) { - let publisher = OV.initPublisher('local-video', { + + this.testStatus = 'CONNECTED'; + + const publisherRemote = OV.initPublisher('mirrored-video', { audio: true, video: true, quality: 'MEDIUM' }); - publisher.stream.subscribeToMyRemote(); - session.publish(publisher); + publisherRemote.on('videoElementCreated', (video) => { + + this.showSpinner = true; + + video.element.addEventListener('playing', () => { + console.warn('PLAYING!!'); + this.testButton = 'End test'; + this.testStatus = 'PLAYING'; + this.showSpinner = false; + }); + }); + + publisherRemote.stream.subscribeToMyRemote(); + this.session.publish(publisherRemote); } }); } + endTestVideo() { + this.session.disconnect(); + this.session = null; + this.testStatus = 'DISCONNECTED'; + this.testButton = 'Test'; + this.showSpinner = false; + } + scrollToBottom(): void { try { this.myScrollContainer.nativeElement.scrollTop = this.myScrollContainer.nativeElement.scrollHeight; diff --git a/openvidu-server/src/angular/frontend/src/index.html b/openvidu-server/src/angular/frontend/src/index.html index 452211bf..2a1fabf7 100644 --- a/openvidu-server/src/angular/frontend/src/index.html +++ b/openvidu-server/src/angular/frontend/src/index.html @@ -9,6 +9,9 @@ + + diff --git a/openvidu-server/src/angular/frontend/src/styles.css b/openvidu-server/src/angular/frontend/src/styles.css index 55bb2ca9..c709b019 100644 --- a/openvidu-server/src/angular/frontend/src/styles.css +++ b/openvidu-server/src/angular/frontend/src/styles.css @@ -15,3 +15,11 @@ main { li { list-style: none; } + +video { + width: 100%; +} + +.mat-spinner path { + stroke: #4d4d4d; +} \ No newline at end of file diff --git a/openvidu-server/src/main/resources/static/index.html b/openvidu-server/src/main/resources/static/index.html index a456f898..00414299 100644 --- a/openvidu-server/src/main/resources/static/index.html +++ b/openvidu-server/src/main/resources/static/index.html @@ -9,6 +9,9 @@ + + diff --git a/openvidu-server/src/main/resources/static/inline.bundle.js.map b/openvidu-server/src/main/resources/static/inline.bundle.js.map index 59ceec1d..9913e2bb 100644 --- a/openvidu-server/src/main/resources/static/inline.bundle.js.map +++ b/openvidu-server/src/main/resources/static/inline.bundle.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///webpack/bootstrap 78c33da7155d58071d00"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA,kDAA0C,oBAAoB,WAAW","file":"inline.bundle.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length)\n \t\t\tresolves.shift()();\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t4: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn Promise.resolve();\n\n \t\t// an Promise means \"currently loading\".\n \t\tif(installedChunks[chunkId]) {\n \t\t\treturn installedChunks[chunkId][2];\n \t\t}\n \t\t// start chunk loading\n \t\tvar head = document.getElementsByTagName('head')[0];\n \t\tvar script = document.createElement('script');\n \t\tscript.type = 'text/javascript';\n \t\tscript.charset = 'utf-8';\n \t\tscript.async = true;\n \t\tscript.timeout = 120000;\n\n \t\tif (__webpack_require__.nc) {\n \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t}\n \t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".chunk.js\";\n \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n \t\tscript.onerror = script.onload = onScriptComplete;\n \t\tfunction onScriptComplete() {\n \t\t\t// avoid mem leaks in IE.\n \t\t\tscript.onerror = script.onload = null;\n \t\t\tclearTimeout(timeout);\n \t\t\tvar chunk = installedChunks[chunkId];\n \t\t\tif(chunk !== 0) {\n \t\t\t\tif(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n \t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t}\n \t\t};\n\n \t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\tinstalledChunks[chunkId] = [resolve, reject];\n \t\t});\n \t\tinstalledChunks[chunkId][2] = promise;\n\n \t\thead.appendChild(script);\n \t\treturn promise;\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 78c33da7155d58071d00"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap 73a01c6c88225c8a7f2f"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,YAAI;AACJ;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA,mDAA2C,cAAc;;AAEzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA,kDAA0C,oBAAoB,WAAW","file":"inline.bundle.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId])\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length)\n \t\t\tresolves.shift()();\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t4: 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tif(installedChunks[chunkId] === 0)\n \t\t\treturn Promise.resolve();\n\n \t\t// an Promise means \"currently loading\".\n \t\tif(installedChunks[chunkId]) {\n \t\t\treturn installedChunks[chunkId][2];\n \t\t}\n \t\t// start chunk loading\n \t\tvar head = document.getElementsByTagName('head')[0];\n \t\tvar script = document.createElement('script');\n \t\tscript.type = 'text/javascript';\n \t\tscript.charset = 'utf-8';\n \t\tscript.async = true;\n \t\tscript.timeout = 120000;\n\n \t\tif (__webpack_require__.nc) {\n \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t}\n \t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".chunk.js\";\n \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n \t\tscript.onerror = script.onload = onScriptComplete;\n \t\tfunction onScriptComplete() {\n \t\t\t// avoid mem leaks in IE.\n \t\t\tscript.onerror = script.onload = null;\n \t\t\tclearTimeout(timeout);\n \t\t\tvar chunk = installedChunks[chunkId];\n \t\t\tif(chunk !== 0) {\n \t\t\t\tif(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n \t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t}\n \t\t};\n\n \t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\tinstalledChunks[chunkId] = [resolve, reject];\n \t\t});\n \t\tinstalledChunks[chunkId][2] = promise;\n\n \t\thead.appendChild(script);\n \t\treturn promise;\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// identity function for calling harmony imports with the correct context\n \t__webpack_require__.i = function(value) { return value; };\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 73a01c6c88225c8a7f2f"],"sourceRoot":""} \ No newline at end of file diff --git a/openvidu-server/src/main/resources/static/main.bundle.js b/openvidu-server/src/main/resources/static/main.bundle.js index fc69d06a..2f50494c 100644 --- a/openvidu-server/src/main/resources/static/main.bundle.js +++ b/openvidu-server/src/main/resources/static/main.bundle.js @@ -1,12 +1,554 @@ webpackJsonp([1,4],{ +/***/ 104: +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +Object.defineProperty(exports, "__esModule", { value: true }); +var EventEmitter = __webpack_require__(52); +var kurentoUtils = __webpack_require__(275); +var adapter = __webpack_require__(173); +if (window) { + window["adapter"] = adapter; +} +function jq(id) { + return id.replace(/(@|:|\.|\[|\]|,)/g, "\\$1"); +} +function show(id) { + document.getElementById(jq(id)).style.display = 'block'; +} +function hide(id) { + document.getElementById(jq(id)).style.display = 'none'; +} +var Stream = (function () { + function Stream(openVidu, local, room, options) { + var _this = this; + this.openVidu = openVidu; + this.local = local; + this.room = room; + this.ee = new EventEmitter(); + this.videoElements = []; + this.elements = []; + this.showMyRemote = false; + this.localMirrored = false; + this.chanId = 0; + this.dataChannelOpened = false; + this.audioOnly = false; + this.isReady = false; + this.isVideoELementCreated = false; + this.accessIsAllowed = false; + this.accessIsDenied = false; + if (options.id) { + this.id = options.id; + } + else { + this.id = "webcam"; + } + this.connection = options.connection; + this.recvVideo = options.recvVideo; + this.recvAudio = options.recvAudio; + this.dataChannel = options.data || false; + this.sendVideo = options.video; + this.sendAudio = options.audio; + this.mediaConstraints = options.mediaConstraints; + this.audioOnly = options.audioOnly || false; + this.addEventListener('src-added', function (srcEvent) { + _this.videoSrc = srcEvent.src; + if (_this.video) + _this.video.src = srcEvent.src; + console.warn("Videosrc [" + srcEvent.src + "] added to stream [" + _this.getId() + "]"); + }); + } + Stream.prototype.emitSrcEvent = function (wrstream) { + this.ee.emitEvent('src-added', [{ + src: URL.createObjectURL(wrstream) + }]); + }; + Stream.prototype.emitStreamReadyEvent = function () { + this.ee.emitEvent('stream-ready'), [{}]; + }; + Stream.prototype.getVideoSrc = function () { + return this.videoSrc; + }; + Stream.prototype.removeVideo = function (parentElement) { + if (typeof parentElement === "string") { + document.getElementById(parentElement).removeChild(this.video); + } + else if (parentElement instanceof Element) { + parentElement.removeChild(this.video); + } + else if (!parentElement) { + if (document.getElementById(this.parentId)) { + document.getElementById(this.parentId).removeChild(this.video); + } + } + }; + Stream.prototype.getVideoElement = function () { + return this.video; + }; + Stream.prototype.setVideoElement = function (video) { + this.video = video; + }; + Stream.prototype.getRecvVideo = function () { + return this.recvVideo; + }; + Stream.prototype.getRecvAudio = function () { + return this.recvAudio; + }; + Stream.prototype.subscribeToMyRemote = function () { + this.showMyRemote = true; + }; + Stream.prototype.displayMyRemote = function () { + return this.showMyRemote; + }; + Stream.prototype.mirrorLocalStream = function (wr) { + this.showMyRemote = true; + this.localMirrored = true; + if (wr) { + this.wrStream = wr; + this.emitSrcEvent(this.wrStream); + } + }; + Stream.prototype.isLocalMirrored = function () { + return this.localMirrored; + }; + Stream.prototype.getChannelName = function () { + return this.getId() + '_' + this.chanId++; + }; + Stream.prototype.isDataChannelEnabled = function () { + return this.dataChannel; + }; + Stream.prototype.isDataChannelOpened = function () { + return this.dataChannelOpened; + }; + Stream.prototype.onDataChannelOpen = function (event) { + console.log('Data channel is opened'); + this.dataChannelOpened = true; + }; + Stream.prototype.onDataChannelClosed = function (event) { + console.log('Data channel is closed'); + this.dataChannelOpened = false; + }; + Stream.prototype.sendData = function (data) { + if (this.wp === undefined) { + throw new Error('WebRTC peer has not been created yet'); + } + if (!this.dataChannelOpened) { + throw new Error('Data channel is not opened'); + } + console.log("Sending through data channel: " + data); + this.wp.send(data); + }; + Stream.prototype.getWrStream = function () { + return this.wrStream; + }; + Stream.prototype.getWebRtcPeer = function () { + return this.wp; + }; + Stream.prototype.addEventListener = function (eventName, listener) { + this.ee.addListener(eventName, listener); + }; + Stream.prototype.addOnceEventListener = function (eventName, listener) { + this.ee.addOnceListener(eventName, listener); + }; + Stream.prototype.removeListener = function (eventName) { + this.ee.removeAllListeners(eventName); + }; + Stream.prototype.showSpinner = function (spinnerParentId) { + var progress = document.createElement('div'); + progress.id = 'progress-' + this.getId(); + progress.style.background = "center transparent url('img/spinner.gif') no-repeat"; + var spinnerParent = document.getElementById(spinnerParentId); + if (spinnerParent) { + spinnerParent.appendChild(progress); + } + }; + Stream.prototype.hideSpinner = function (spinnerId) { + spinnerId = (spinnerId === undefined) ? this.getId() : spinnerId; + hide('progress-' + spinnerId); + }; + Stream.prototype.playOnlyVideo = function (parentElement, thumbnailId) { + // TO-DO: check somehow if the stream is audio only, so the element created is