diff --git a/openvidu-testapp/package.json b/openvidu-testapp/package.json index 6c6d17a3..afc781f4 100644 --- a/openvidu-testapp/package.json +++ b/openvidu-testapp/package.json @@ -16,7 +16,7 @@ "core-js": "^2.4.1", "hammerjs": "^2.0.8", "openvidu-browser": "1.9.0-beta-1", - "openvidu-node-client": "1.7.0", + "openvidu-node-client": "1.8.0", "rxjs": "^5.4.2", "zone.js": "^0.8.14" }, diff --git a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts index e613086e..188f2b62 100644 --- a/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts +++ b/openvidu-testapp/src/app/components/openvidu-instance/openvidu-instance.component.ts @@ -209,37 +209,8 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { this.sendAudioChange = this.sendAudio; this.sendVideoChange = this.sendVideo; - this.publisher = this.OV.initPublisher( - 'local-vid-' + this.session.connection.connectionId, - { - audio: this.sendAudio, - video: this.sendVideo, - audioActive: this.activeAudio, - videoActive: this.activeVideo, - quality: 'MEDIUM', - screen: this.optionsVideo === 'screen' ? true : false - }, - (err) => { - if (err) { - console.warn(err); - this.openviduError = err; - if (err.name === 'SCREEN_EXTENSION_NOT_INSTALLED') { - this.extensionDialog.open(ExtensionDialogComponent, { - data: { url: err.message }, - disableClose: true, - width: '250px' - }); - } - } - }); - - this.addPublisherEvents(this.publisher); - - if (this.subscribeToRemote) { - this.publisher.subscribeToRemote(); - } - - this.session.publish(this.publisher); + // this.asyncInitPublisher(); + this.syncInitPublisher(); } } else { @@ -439,6 +410,7 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { console.log('Message succesfully sent'); } }); + // this.initGrayVideo(); } recordPublisher(): void { @@ -533,7 +505,13 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { publishUnpublish(): void { if (this.unpublished) { - this.session.publish(this.publisher); + this.session.publish(this.publisher) + .then(() => { + console.log(this.publisher); + }) + .catch(e => { + console.error(e); + }); } else { this.session.unpublish(this.publisher); this.removeUserData(this.session.connection.connectionId); @@ -585,12 +563,13 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { this.publisher = this.OV.initPublisher( 'local-vid-' + this.session.connection.connectionId, { - audio: this.sendAudioChange, - video: this.sendVideoChange, - audioActive: (!this.publisherChanged) ? true : !this.audioMuted, - videoActive: (!this.publisherChanged) ? true : !this.videoMuted, - quality: 'MEDIUM', - screen: screenChange + audioSource: this.sendAudioChange ? undefined : false, + videoSource: this.sendVideoChange ? (screenChange ? 'screen' : undefined) : false, + publishAudio: (!this.publisherChanged) ? true : !this.audioMuted, + publishVideo: (!this.publisherChanged) ? true : !this.videoMuted, + resolution: '640x480', + frameRate: 30, + insertMode: 'APPEND' }, (err) => { if (err) { @@ -621,10 +600,35 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { document.getElementById('record-btn-' + this.session.connection.connectionId + '-' + connectionId).remove(); document.getElementById('pause-btn-' + this.session.connection.connectionId + '-' + connectionId).remove(); } else { - subscriber = this.session.subscribe(subscriber.stream, 'remote-vid-' + this.session.connection.connectionId); + + + this.session.subscribeAsync(subscriber.stream, 'remote-vid-' + this.session.connection.connectionId) + .then(sub => { + subscriber = sub; + this.subscribers[connectionId].subscriber = subscriber; + subscriber.on('videoElementCreated', (e) => { + if (!subscriber.stream.hasVideo) { + $(e.element).css({ 'background-color': '#4d4d4d' }); + $(e.element).attr('poster', 'assets/images/volume.png'); + } + this.subscribers[connectionId].videoElement = e.element; + this.updateEventList('videoElementCreated', e.element.id); + }); + subscriber.on('videoPlaying', (e) => { + this.removeUserData(connectionId); + this.appendSubscriberData(e.element, subscriber.stream.connection); + this.updateEventList('videoPlaying', e.element.id); + }); + }) + .catch(err => { + console.error(err); + }); + + + /*subscriber = this.session.subscribe(subscriber.stream, 'remote-vid-' + this.session.connection.connectionId); this.subscribers[connectionId].subscriber = subscriber; subscriber.on('videoElementCreated', (e) => { - if (!subscriber.stream.getRecvVideo()) { + if (!subscriber.stream.hasVideo) { $(e.element).css({ 'background-color': '#4d4d4d' }); $(e.element).attr('poster', 'assets/images/volume.png'); } @@ -635,7 +639,9 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { this.removeUserData(connectionId); this.appendSubscriberData(e.element, subscriber.stream.connection); this.updateEventList('videoPlaying', e.element.id); - }); + });*/ + + } this.subscribers[connectionId].subbed = !this.subscribers[connectionId].subbed; } @@ -646,30 +652,8 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { this.changeDetector.detectChanges(); if (this.subscribeTo) { - const subscriber: Subscriber = session.subscribe(event.stream, 'remote-vid-' + session.connection.connectionId); - this.subscribers[subscriber.stream.connection.connectionId] = { - 'subscriber': subscriber, - 'subbed': true, - 'recorder': undefined, - 'recording': false, - 'paused': false, - 'videoElement': undefined - }; - subscriber.on('videoElementCreated', (e) => { - if (!event.stream.getRecvVideo()) { - $(e.element).css({ 'background-color': '#4d4d4d' }); - $(e.element).attr('poster', 'assets/images/volume.png'); - } - this.subscribers[subscriber.stream.connection.connectionId].videoElement = e.element; - this.updateEventList('videoElementCreated', e.element.id); - }); - subscriber.on('videoPlaying', (e) => { - this.appendSubscriberData(e.element, subscriber.stream.connection); - this.updateEventList('videoPlaying', e.element.id); - }); - subscriber.on('videoElementDestroyed', (e) => { - this.updateEventList('videoElementDestroyed', '(Subscriber)'); - }); + // this.syncSubscribe(session, event); + this.asyncSubscribe(session, event); } this.updateEventList('streamCreated', event.stream.connection.connectionId); }); @@ -686,11 +670,23 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { }); session.on('sessionDisconnected', (event) => { this.updateEventList('sessionDisconnected', 'No data'); + if (event.reason === 'networkDisconnect') { + this.session = null; + this.OV = null; + } }); session.on('signal', (event) => { this.updateEventList('signal', event.from.connectionId + '-' + event.data); }); + session.on('recordingStarted', (event) => { + this.updateEventList('recordingStarted', event.id); + }); + + session.on('recordingStopped', (event) => { + this.updateEventList('recordingStopped', event.id); + }); + /*session.on('publisherStartSpeaking', (event) => { console.log('Publisher start speaking'); console.log(event); @@ -724,6 +720,14 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { this.updateEventList('accessDenied', ''); }); + publisher.on('accessDialogOpened', (e) => { + this.updateEventList('accessDialogOpened', ''); + }); + + publisher.on('accessDialogClosed', (e) => { + this.updateEventList('accessDialogClosed', ''); + }); + publisher.on('videoPlaying', (e) => { this.appendPublisherData(e.element); this.updateEventList('videoPlaying', e.element.id); @@ -806,4 +810,192 @@ export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy { } } + syncInitPublisher() { + this.publisher = this.OV.initPublisher( + 'local-vid-' + this.session.connection.connectionId, + { + audioSource: this.sendAudio ? undefined : false, + videoSource: this.sendVideo ? (this.optionsVideo === 'screen' ? 'screen' : undefined) : false, + publishAudio: this.activeAudio, + publishVideo: this.activeVideo, + resolution: '640x480', + frameRate: 30, + insertMode: 'APPEND' + }, + (err) => { + if (err) { + console.warn(err); + this.openviduError = err; + if (err.name === 'SCREEN_EXTENSION_NOT_INSTALLED') { + this.extensionDialog.open(ExtensionDialogComponent, { + data: { url: err.message }, + disableClose: true, + width: '250px' + }); + } + } + }); + + this.addPublisherEvents(this.publisher); + + if (this.subscribeToRemote) { + this.publisher.subscribeToRemote(); + } + + this.session.publish(this.publisher); + } + + asyncInitPublisher() { + this.OV.initPublisherAsync( + 'local-vid-' + this.session.connection.connectionId, + { + audioSource: this.sendAudio ? undefined : false, + videoSource: this.sendVideo ? (this.optionsVideo === 'screen' ? 'screen' : undefined) : false, + publishAudio: this.activeAudio, + publishVideo: this.activeVideo, + resolution: '640x480', + frameRate: 30, + insertMode: 'APPEND' + }) + .then(publisher => { + this.publisher = publisher; + this.addPublisherEvents(this.publisher); + if (this.subscribeToRemote) { + this.publisher.subscribeToRemote(); + } + this.session.publish(this.publisher) + .then(() => { + console.log(this.publisher); + }) + .catch(e => { + console.error(e); + }); + }) + .catch(err => { + if (err) { + console.error(err); + this.openviduError = err; + if (err.name === 'SCREEN_EXTENSION_NOT_INSTALLED') { + this.extensionDialog.open(ExtensionDialogComponent, { + data: { url: err.message }, + disableClose: true, + width: '250px' + }); + } + } + }); + } + + syncSubscribe(session: Session, event) { + const subscriber: Subscriber = session.subscribe(event.stream, 'remote-vid-' + session.connection.connectionId); + this.subscribers[subscriber.stream.connection.connectionId] = { + 'subscriber': subscriber, + 'subbed': true, + 'recorder': undefined, + 'recording': false, + 'paused': false, + 'videoElement': undefined + }; + subscriber.on('videoElementCreated', (e) => { + if (!event.stream.hasVideo) { + $(e.element).css({ 'background-color': '#4d4d4d' }); + $(e.element).attr('poster', 'assets/images/volume.png'); + } + this.subscribers[subscriber.stream.connection.connectionId].videoElement = e.element; + this.updateEventList('videoElementCreated', e.element.id); + }); + subscriber.on('videoPlaying', (e) => { + this.appendSubscriberData(e.element, subscriber.stream.connection); + this.updateEventList('videoPlaying', e.element.id); + }); + subscriber.on('videoElementDestroyed', (e) => { + this.updateEventList('videoElementDestroyed', '(Subscriber)'); + }); + } + + asyncSubscribe(session: Session, event) { + session.subscribeAsync(event.stream, 'remote-vid-' + session.connection.connectionId) + .then(subscriber => { + this.subscribers[subscriber.stream.connection.connectionId] = { + 'subscriber': subscriber, + 'subbed': true, + 'recorder': undefined, + 'recording': false, + 'paused': false, + 'videoElement': undefined + }; + subscriber.on('videoElementCreated', (e) => { + if (!event.stream.hasVideo) { + $(e.element).css({ 'background-color': '#4d4d4d' }); + $(e.element).attr('poster', 'assets/images/volume.png'); + } + this.subscribers[subscriber.stream.connection.connectionId].videoElement = e.element; + this.updateEventList('videoElementCreated', e.element.id); + }); + subscriber.on('videoPlaying', (e) => { + this.appendSubscriberData(e.element, subscriber.stream.connection); + this.updateEventList('videoPlaying', e.element.id); + }); + subscriber.on('videoElementDestroyed', (e) => { + this.updateEventList('videoElementDestroyed', '(Subscriber)'); + }); + }) + .catch(err => { + console.error(err); + }); + } + + enableSpeakingEvents() { + this.session.on('publisherStartSpeaking', (event) => { + }); + + this.session.on('publisherStopSpeaking', (event) => { + }); + } + + disableSpeakingEvents() { + this.session.off('publisherStartSpeaking'); + this.session.off('publisherStopSpeaking'); + } + + initGrayVideo(): void { + this.OV.getUserMedia( + { + videoSource: undefined, + resolution: '1280x720', + frameRate: 10, + } + ) + .then((mediaStream: MediaStream) => { + const videoStreamTrack = mediaStream.getVideoTracks()[0]; + const video = document.createElement('video'); + video.srcObject = new MediaStream([videoStreamTrack]); + video.play(); + const canvas = document.createElement('canvas') as any; + const ctx = canvas.getContext('2d'); + ctx.filter = 'grayscale(100%)'; + + video.addEventListener('play', () => { + const loop = () => { + if (!video.paused && !video.ended) { + ctx.drawImage(video, 0, 0, 300, 170); + setTimeout(loop, 100); // Drawing at 10fps + } + }; + loop(); + }); + const grayVideoTrack = canvas.captureStream(30).getVideoTracks()[0]; + this.OV.initPublisher( + document.body, + { + audioSource: false, + videoSource: grayVideoTrack, + insertMode: 'APPEND' + }); + }) + .catch(error => { + console.error(error); + }); + } + } diff --git a/openvidu-testapp/src/app/components/test-apirest/test-apirest.component.html b/openvidu-testapp/src/app/components/test-apirest/test-apirest.component.html index 247b3592..f968fa5b 100644 --- a/openvidu-testapp/src/app/components/test-apirest/test-apirest.component.html +++ b/openvidu-testapp/src/app/components/test-apirest/test-apirest.component.html @@ -11,15 +11,54 @@ +
+

Session Properties

+ + + + + + + + + + + +
Archive ModeArchive LayoutMedia Mode
+ + + {{ archiveMode }} + + + + + + {{ archiveLayout }} + + + + + + {{ mediaMode }} + + +
+
+ +
+
- - - + + + + @@ -28,9 +67,6 @@

{{token}}

-
sessionIdstokensSessionSelectionSession IDsTokens
+ + {{sid[0]}} - -
@@ -57,4 +93,4 @@
- \ No newline at end of file + diff --git a/openvidu-testapp/src/app/components/test-apirest/test-apirest.component.ts b/openvidu-testapp/src/app/components/test-apirest/test-apirest.component.ts index e7465080..ad578d39 100644 --- a/openvidu-testapp/src/app/components/test-apirest/test-apirest.component.ts +++ b/openvidu-testapp/src/app/components/test-apirest/test-apirest.component.ts @@ -2,6 +2,7 @@ import { Component, Input, OnInit, OnDestroy } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; import { OpenviduRestService } from '../../services/openvidu-rest.service'; import { OpenviduParamsService } from '../../services/openvidu-params.service'; +import { SessionProperties, ArchiveMode, ArchiveLayout, MediaMode } from 'openvidu-node-client'; import * as colormap from 'colormap'; const numColors = 64; @@ -21,8 +22,19 @@ export class TestApirestComponent implements OnInit, OnDestroy { // API REST params serverData = 'data_test'; selectedRadioIndex = 0; - selectedRole = 'PUBLISHER'; + openViduRoles = ['SUBSCRIBER', 'PUBLISHER', 'MODERATOR']; + selectedRole = 'PUBLISHER'; + + archiveModes = ['ALWAYS', 'MANUAL']; + selectedArchiveMode = 'MANUAL'; + + archiveLayouts = ['BEST_FIT']; + selectedArchiveLayout = 'BEST_FIT'; + + mediaModes = ['ROUTED']; + selectedMediaMode = 'ROUTED'; + // API REST data collected data = []; @@ -57,7 +69,12 @@ export class TestApirestComponent implements OnInit, OnDestroy { } private getSessionId() { - this.openviduRestService.getSessionId(this.openviduUrl, this.openviduSecret) + this.openviduRestService.getSessionId(this.openviduUrl, this.openviduSecret, + new SessionProperties.Builder() + .archiveMode(ArchiveMode[this.selectedArchiveMode]) + .archiveLayout(ArchiveLayout[this.selectedArchiveLayout]) + .mediaMode(MediaMode[this.selectedMediaMode]) + .build()) .then((sessionId) => { this.updateData(); }) diff --git a/openvidu-testapp/src/app/services/openvidu-rest.service.ts b/openvidu-testapp/src/app/services/openvidu-rest.service.ts index 9e42ae95..ac16f37a 100644 --- a/openvidu-testapp/src/app/services/openvidu-rest.service.ts +++ b/openvidu-testapp/src/app/services/openvidu-rest.service.ts @@ -3,7 +3,8 @@ import { OpenVidu as OpenViduAPI, Session as SessionAPI, TokenOptions as TokenOptionsAPI, - OpenViduRole as OpenViduRoleAPI + OpenViduRole as OpenViduRoleAPI, + SessionProperties as SessionPropertiesAPI } from 'openvidu-node-client'; import { environment } from '../../environments/environment'; @@ -15,9 +16,9 @@ export class OpenviduRestService { constructor() { } - getSessionId(openviduURL: string, openviduSecret: string): Promise { + getSessionId(openviduURL: string, openviduSecret: string, sessionProperties: SessionPropertiesAPI): Promise { const OV = new OpenViduAPI(openviduURL, openviduSecret); - const session = OV.createSession(); + const session = OV.createSession(sessionProperties); return new Promise(resolve => { session.getSessionId((sessionId) => {