2017-09-30 13:48:40 +02:00
|
|
|
import {
|
2018-06-15 14:45:47 +02:00
|
|
|
Component, Input, HostListener, ChangeDetectorRef, SimpleChanges,
|
2017-09-30 13:48:40 +02:00
|
|
|
OnInit, OnDestroy, OnChanges
|
|
|
|
} from '@angular/core';
|
2018-03-01 11:25:25 +01:00
|
|
|
|
2018-04-27 11:08:03 +02:00
|
|
|
import {
|
2019-02-06 15:04:49 +01:00
|
|
|
OpenVidu, Session, Subscriber, Publisher, Event, VideoInsertMode, StreamEvent, ConnectionEvent,
|
2018-06-15 14:45:47 +02:00
|
|
|
SessionDisconnectedEvent, SignalEvent, RecordingEvent,
|
2018-12-07 11:42:02 +01:00
|
|
|
PublisherSpeakingEvent, PublisherProperties, StreamPropertyChangedEvent, OpenViduError
|
2018-04-27 11:08:03 +02:00
|
|
|
} from 'openvidu-browser';
|
2018-05-18 12:46:41 +02:00
|
|
|
import {
|
|
|
|
OpenVidu as OpenViduAPI,
|
2018-07-13 13:47:06 +02:00
|
|
|
Session as SessionAPI,
|
2018-05-18 12:46:41 +02:00
|
|
|
SessionProperties as SessionPropertiesAPI,
|
|
|
|
MediaMode,
|
|
|
|
RecordingMode,
|
2018-07-09 16:29:21 +02:00
|
|
|
RecordingLayout,
|
2018-08-01 15:12:34 +02:00
|
|
|
TokenOptions,
|
2019-01-21 18:46:40 +01:00
|
|
|
OpenViduRole,
|
|
|
|
RecordingProperties,
|
|
|
|
Recording
|
2018-05-18 12:46:41 +02:00
|
|
|
} from 'openvidu-node-client';
|
2018-06-15 14:45:47 +02:00
|
|
|
import { MatDialog, MAT_CHECKBOX_CLICK_ACTION } from '@angular/material';
|
|
|
|
import { ExtensionDialogComponent } from '../dialogs/extension-dialog/extension-dialog.component';
|
2017-10-09 18:48:05 +02:00
|
|
|
import { TestFeedService } from '../../services/test-feed.service';
|
2018-06-15 14:45:47 +02:00
|
|
|
import { EventsDialogComponent } from '../dialogs/events-dialog/events-dialog.component';
|
|
|
|
import { SessionPropertiesDialogComponent } from '../dialogs/session-properties-dialog/session-properties-dialog.component';
|
|
|
|
import { SessionApiDialogComponent } from '../dialogs/session-api-dialog/session-api-dialog.component';
|
|
|
|
import { PublisherPropertiesDialogComponent } from '../dialogs/publisher-properties-dialog/publisher-properties-dialog.component';
|
2017-09-28 19:13:29 +02:00
|
|
|
|
|
|
|
|
2017-10-02 15:18:28 +02:00
|
|
|
export interface SessionConf {
|
|
|
|
subscribeTo: boolean;
|
|
|
|
publishTo: boolean;
|
|
|
|
startSession: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface OpenViduEvent {
|
2019-02-06 15:04:49 +01:00
|
|
|
eventName: string;
|
|
|
|
eventContent: string;
|
|
|
|
event: Event;
|
2017-10-02 15:18:28 +02:00
|
|
|
}
|
|
|
|
|
2017-09-28 19:13:29 +02:00
|
|
|
@Component({
|
|
|
|
selector: 'app-openvidu-instance',
|
|
|
|
templateUrl: './openvidu-instance.component.html',
|
2018-05-31 13:08:34 +02:00
|
|
|
styleUrls: ['./openvidu-instance.component.css'],
|
|
|
|
providers: [
|
|
|
|
{ provide: MAT_CHECKBOX_CLICK_ACTION, useValue: 'noop' }
|
|
|
|
]
|
2017-09-28 19:13:29 +02:00
|
|
|
})
|
2017-09-30 13:48:40 +02:00
|
|
|
export class OpenviduInstanceComponent implements OnInit, OnChanges, OnDestroy {
|
2017-09-28 19:13:29 +02:00
|
|
|
|
|
|
|
@Input()
|
2017-09-30 13:48:40 +02:00
|
|
|
openviduUrl: string;
|
2017-09-28 19:13:29 +02:00
|
|
|
|
|
|
|
@Input()
|
|
|
|
openviduSecret: string;
|
|
|
|
|
2017-10-02 15:18:28 +02:00
|
|
|
@Input()
|
|
|
|
sessionConf: SessionConf;
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
@Input()
|
|
|
|
index: number;
|
|
|
|
|
2017-09-29 16:19:23 +02:00
|
|
|
// Session join data
|
|
|
|
clientData: string;
|
|
|
|
sessionName: string;
|
|
|
|
|
|
|
|
// Session options
|
2017-10-02 15:18:28 +02:00
|
|
|
subscribeTo;
|
|
|
|
publishTo;
|
2017-09-28 19:13:29 +02:00
|
|
|
sendVideoRadio = true;
|
2017-09-29 13:54:22 +02:00
|
|
|
subscribeToRemote = false;
|
2017-09-29 16:19:23 +02:00
|
|
|
optionsVideo = 'video';
|
|
|
|
|
2019-01-21 18:46:40 +01:00
|
|
|
// Recording options
|
|
|
|
recordingProperties: RecordingProperties;
|
|
|
|
|
2018-05-18 12:46:41 +02:00
|
|
|
// OpenVidu Browser objects
|
2017-09-28 19:13:29 +02:00
|
|
|
OV: OpenVidu;
|
|
|
|
session: Session;
|
2017-09-29 13:54:22 +02:00
|
|
|
publisher: Publisher;
|
2018-05-29 18:32:49 +02:00
|
|
|
subscribers: Subscriber[] = [];
|
2017-09-29 13:54:22 +02:00
|
|
|
|
2018-05-18 12:46:41 +02:00
|
|
|
// OpenVidu Node Client objects
|
2018-07-23 00:36:45 +02:00
|
|
|
OV_NodeClient: OpenViduAPI;
|
2018-07-13 13:47:06 +02:00
|
|
|
sessionAPI: SessionAPI;
|
2018-05-18 12:46:41 +02:00
|
|
|
sessionProperties: SessionPropertiesAPI = {
|
|
|
|
mediaMode: MediaMode.ROUTED,
|
|
|
|
recordingMode: RecordingMode.MANUAL,
|
2019-01-29 18:18:53 +01:00
|
|
|
defaultOutputMode: Recording.OutputMode.COMPOSED,
|
2018-05-18 12:46:41 +02:00
|
|
|
defaultRecordingLayout: RecordingLayout.BEST_FIT,
|
|
|
|
defaultCustomLayout: '',
|
|
|
|
customSessionId: ''
|
|
|
|
};
|
|
|
|
|
2018-05-31 13:08:34 +02:00
|
|
|
publisherProperties: PublisherProperties = {
|
|
|
|
audioSource: undefined,
|
|
|
|
videoSource: undefined,
|
|
|
|
frameRate: 30,
|
|
|
|
resolution: '640x480',
|
|
|
|
mirror: true,
|
|
|
|
publishAudio: true,
|
|
|
|
publishVideo: true
|
|
|
|
};
|
|
|
|
|
|
|
|
publisherPropertiesAux: PublisherProperties;
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
sessionEvents = {
|
|
|
|
connectionCreated: true,
|
|
|
|
connectionDestroyed: true,
|
|
|
|
sessionDisconnected: true,
|
|
|
|
streamCreated: true,
|
|
|
|
streamDestroyed: true,
|
2018-07-03 15:48:21 +02:00
|
|
|
streamPropertyChanged: true,
|
2018-05-29 18:32:49 +02:00
|
|
|
recordingStarted: true,
|
|
|
|
recordingStopped: true,
|
|
|
|
signal: true,
|
|
|
|
publisherStartSpeaking: false,
|
2020-02-17 22:00:51 +01:00
|
|
|
publisherStopSpeaking: false,
|
|
|
|
reconnecting: true,
|
|
|
|
reconnected: true
|
2018-05-29 18:32:49 +02:00
|
|
|
};
|
2018-01-18 16:09:39 +01:00
|
|
|
|
2018-08-01 15:12:34 +02:00
|
|
|
// Session properties dialog
|
2018-06-08 11:07:38 +02:00
|
|
|
turnConf = 'auto';
|
|
|
|
manualTurnConf: RTCIceServer = { urls: [] };
|
2018-07-23 18:20:01 +02:00
|
|
|
customToken: string;
|
2018-08-01 15:12:34 +02:00
|
|
|
tokenOptions: TokenOptions = {
|
|
|
|
role: OpenViduRole.PUBLISHER,
|
|
|
|
kurentoOptions: {
|
2018-09-24 17:40:24 +02:00
|
|
|
videoMaxRecvBandwidth: 1000,
|
2018-08-01 15:12:34 +02:00
|
|
|
videoMinRecvBandwidth: 300,
|
2018-09-24 17:40:24 +02:00
|
|
|
videoMaxSendBandwidth: 1000,
|
2018-08-01 15:12:34 +02:00
|
|
|
videoMinSendBandwidth: 300,
|
2018-08-02 14:11:51 +02:00
|
|
|
allowedFilters: []
|
2018-08-01 15:12:34 +02:00
|
|
|
}
|
|
|
|
};
|
2018-06-08 11:07:38 +02:00
|
|
|
|
2017-10-02 15:18:28 +02:00
|
|
|
events: OpenViduEvent[] = [];
|
2017-09-30 13:48:40 +02:00
|
|
|
|
2017-10-04 10:30:15 +02:00
|
|
|
openviduError: any;
|
|
|
|
|
2018-01-11 11:13:50 +01:00
|
|
|
constructor(
|
|
|
|
private changeDetector: ChangeDetectorRef,
|
2018-05-18 12:46:41 +02:00
|
|
|
private dialog: MatDialog,
|
2018-05-29 18:32:49 +02:00
|
|
|
private testFeedService: TestFeedService
|
2018-01-11 11:13:50 +01:00
|
|
|
) {
|
2017-09-28 19:13:29 +02:00
|
|
|
this.generateSessionInfo();
|
|
|
|
}
|
|
|
|
|
2017-10-02 15:18:28 +02:00
|
|
|
ngOnInit() {
|
|
|
|
this.subscribeTo = this.sessionConf.subscribeTo;
|
|
|
|
this.publishTo = this.sessionConf.publishTo;
|
2018-05-31 13:08:34 +02:00
|
|
|
this.publisherPropertiesAux = Object.assign({}, this.publisherProperties);
|
2017-10-02 15:18:28 +02:00
|
|
|
if (!this.publishTo) {
|
|
|
|
this.publishTo = !this.publishTo;
|
|
|
|
this.togglePublishTo();
|
|
|
|
}
|
|
|
|
if (this.sessionConf.startSession) {
|
|
|
|
this.joinSession();
|
|
|
|
}
|
|
|
|
}
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2017-09-30 13:48:40 +02:00
|
|
|
ngOnChanges(changes: SimpleChanges) {
|
|
|
|
if (changes.openviduSecret) {
|
|
|
|
this.openviduSecret = changes.openviduSecret.currentValue;
|
|
|
|
}
|
|
|
|
if (changes.openviduUrl) {
|
|
|
|
this.openviduUrl = changes.openviduUrl.currentValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-28 19:13:29 +02:00
|
|
|
ngOnDestroy() {
|
|
|
|
this.leaveSession();
|
|
|
|
}
|
|
|
|
|
|
|
|
@HostListener('window:beforeunload')
|
|
|
|
beforeunloadHandler() {
|
|
|
|
this.leaveSession();
|
|
|
|
}
|
|
|
|
|
|
|
|
private generateSessionInfo(): void {
|
|
|
|
this.sessionName = 'TestSession';
|
|
|
|
this.clientData = 'TestClient';
|
|
|
|
}
|
|
|
|
|
2018-06-04 14:27:37 +02:00
|
|
|
joinSession(): void {
|
2017-09-28 19:13:29 +02:00
|
|
|
|
|
|
|
if (this.session) {
|
|
|
|
this.leaveSession();
|
|
|
|
}
|
|
|
|
|
2018-07-23 18:20:01 +02:00
|
|
|
if (!!this.customToken) {
|
|
|
|
this.joinSessionShared(this.customToken);
|
|
|
|
} else {
|
|
|
|
this.getToken().then(token => {
|
|
|
|
this.joinSessionShared(token);
|
|
|
|
});
|
|
|
|
}
|
2017-10-16 15:49:23 +02:00
|
|
|
}
|
|
|
|
|
2018-05-03 11:48:57 +02:00
|
|
|
private joinSessionShared(token): void {
|
2017-10-16 15:49:23 +02:00
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
this.OV = new OpenVidu();
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2018-06-08 11:07:38 +02:00
|
|
|
if (this.turnConf === 'freeice') {
|
|
|
|
this.OV.setAdvancedConfiguration({ iceServers: 'freeice' });
|
|
|
|
} else if (this.turnConf === 'manual') {
|
|
|
|
this.OV.setAdvancedConfiguration({ iceServers: [this.manualTurnConf] });
|
|
|
|
}
|
|
|
|
|
2018-05-03 11:48:57 +02:00
|
|
|
this.session = this.OV.initSession();
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
this.updateSessionEvents({
|
|
|
|
connectionCreated: false,
|
|
|
|
connectionDestroyed: false,
|
|
|
|
sessionDisconnected: false,
|
|
|
|
streamCreated: false,
|
|
|
|
streamDestroyed: false,
|
2018-07-03 15:48:21 +02:00
|
|
|
streamPropertyChanged: false,
|
2018-05-29 18:32:49 +02:00
|
|
|
recordingStarted: false,
|
|
|
|
recordingStopped: false,
|
|
|
|
signal: false,
|
|
|
|
publisherStartSpeaking: true,
|
2020-02-17 22:00:51 +01:00
|
|
|
publisherStopSpeaking: true,
|
|
|
|
reconnecting: true,
|
|
|
|
reconnected: true
|
2018-05-29 18:32:49 +02:00
|
|
|
}, true);
|
2017-12-12 14:36:43 +01:00
|
|
|
|
2018-04-27 11:43:21 +02:00
|
|
|
this.session.connect(token, this.clientData)
|
|
|
|
.then(() => {
|
2018-04-05 20:06:48 +02:00
|
|
|
this.changeDetector.detectChanges();
|
|
|
|
|
2019-02-08 11:08:08 +01:00
|
|
|
if (this.publishTo && this.session.capabilities.publish) {
|
2018-04-17 15:08:02 +02:00
|
|
|
// this.asyncInitPublisher();
|
|
|
|
this.syncInitPublisher();
|
2017-09-29 13:54:22 +02:00
|
|
|
}
|
2018-04-27 11:43:21 +02:00
|
|
|
})
|
|
|
|
.catch(error => {
|
2017-09-28 19:13:29 +02:00
|
|
|
console.log('There was an error connecting to the session:', error.code, error.message);
|
2018-11-21 14:32:59 +01:00
|
|
|
alert('Error connecting to the session: ' + error.message);
|
2018-04-27 11:43:21 +02:00
|
|
|
});
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private leaveSession(): void {
|
|
|
|
if (this.session) {
|
|
|
|
this.session.disconnect();
|
|
|
|
}
|
2018-05-29 18:32:49 +02:00
|
|
|
delete this.session;
|
|
|
|
delete this.OV;
|
|
|
|
delete this.publisher;
|
|
|
|
this.subscribers = [];
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
2019-02-06 15:04:49 +01:00
|
|
|
updateEventList(eventName: string, eventContent: string, event: Event) {
|
|
|
|
const eventInterface: OpenViduEvent = { eventName, eventContent, event };
|
|
|
|
this.events.push(eventInterface);
|
|
|
|
this.testFeedService.pushNewEvent(this.sessionName, this.session.connection.connectionId, event);
|
2017-09-30 13:48:40 +02:00
|
|
|
}
|
|
|
|
|
2017-09-29 16:19:23 +02:00
|
|
|
toggleSubscribeTo(): void {
|
|
|
|
this.subscribeTo = !this.subscribeTo;
|
|
|
|
}
|
|
|
|
|
|
|
|
togglePublishTo(): void {
|
|
|
|
this.publishTo = !this.publishTo;
|
2018-05-31 13:08:34 +02:00
|
|
|
if (this.publishTo) {
|
|
|
|
this.publisherProperties = this.publisherPropertiesAux;
|
|
|
|
} else {
|
|
|
|
this.publisherPropertiesAux = Object.assign({}, this.publisherProperties);
|
|
|
|
this.publisherProperties.publishAudio = false;
|
|
|
|
this.publisherProperties.publishVideo = false;
|
|
|
|
this.publisherProperties.audioSource = false;
|
|
|
|
this.publisherProperties.videoSource = false;
|
|
|
|
}
|
2017-09-29 16:19:23 +02:00
|
|
|
|
|
|
|
if (this.publishTo) {
|
|
|
|
this.optionsVideo = 'video';
|
|
|
|
} else {
|
|
|
|
this.optionsVideo = '';
|
2017-09-29 13:54:22 +02:00
|
|
|
}
|
2017-09-29 16:19:23 +02:00
|
|
|
|
|
|
|
this.subscribeToRemote = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleSendAudio(): void {
|
2018-05-31 13:08:34 +02:00
|
|
|
if (this.publisherProperties.audioSource === false) {
|
|
|
|
this.publisherProperties.audioSource = this.publisherPropertiesAux.audioSource;
|
|
|
|
} else {
|
|
|
|
this.publisherPropertiesAux.audioSource = this.publisherProperties.audioSource;
|
|
|
|
this.publisherProperties.audioSource = false;
|
2017-09-29 16:19:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleSendVideo(): void {
|
2018-05-31 13:08:34 +02:00
|
|
|
if (this.publisherProperties.videoSource === false) {
|
|
|
|
this.publisherProperties.videoSource = this.publisherPropertiesAux.videoSource;
|
2017-09-29 16:19:23 +02:00
|
|
|
} else {
|
2018-05-31 13:08:34 +02:00
|
|
|
this.publisherPropertiesAux.videoSource = this.publisherProperties.videoSource;
|
|
|
|
this.publisherProperties.videoSource = false;
|
2017-09-29 16:19:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleActiveAudio(): void {
|
2018-05-31 13:08:34 +02:00
|
|
|
this.publisherProperties.publishAudio = !this.publisherProperties.publishAudio;
|
2017-09-29 16:19:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
toggleActiveVideo(): void {
|
2018-05-31 13:08:34 +02:00
|
|
|
this.publisherProperties.publishVideo = !this.publisherProperties.publishVideo;
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
2017-12-11 17:09:57 +01:00
|
|
|
sendMessage(): void {
|
|
|
|
this.session.signal({
|
|
|
|
data: 'Test message',
|
|
|
|
to: [],
|
|
|
|
type: 'chat'
|
2018-04-27 11:43:21 +02:00
|
|
|
})
|
|
|
|
.then(() => {
|
2018-07-03 15:48:21 +02:00
|
|
|
console.log('Message successfully sent');
|
2018-04-27 11:43:21 +02:00
|
|
|
})
|
|
|
|
.catch(error => {
|
|
|
|
console.error(error);
|
2018-04-02 12:11:30 +02:00
|
|
|
});
|
2018-04-27 11:08:03 +02:00
|
|
|
// this.initGrayVideo();
|
2017-12-11 17:09:57 +01:00
|
|
|
}
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
updateSessionEvents(oldValues, firstTime) {
|
2018-03-01 11:25:25 +01:00
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.streamCreated !== oldValues.streamCreated || firstTime) {
|
|
|
|
this.session.off('streamCreated');
|
|
|
|
if (this.sessionEvents.streamCreated) {
|
|
|
|
this.session.on('streamCreated', (event: StreamEvent) => {
|
|
|
|
this.changeDetector.detectChanges();
|
|
|
|
if (this.subscribeTo) {
|
|
|
|
this.syncSubscribe(this.session, event);
|
|
|
|
}
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('streamCreated', event.stream.streamId, event);
|
2018-03-01 11:25:25 +01:00
|
|
|
});
|
2018-05-29 18:32:49 +02:00
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.streamDestroyed !== oldValues.streamDestroyed || firstTime) {
|
|
|
|
this.session.off('streamDestroyed');
|
|
|
|
if (this.sessionEvents.streamDestroyed) {
|
|
|
|
this.session.on('streamDestroyed', (event: StreamEvent) => {
|
|
|
|
const index = this.subscribers.indexOf(<Subscriber>event.stream.streamManager);
|
|
|
|
if (index > -1) {
|
|
|
|
this.subscribers.splice(index, 1);
|
|
|
|
}
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('streamDestroyed', event.stream.streamId, event);
|
2018-03-01 11:25:25 +01:00
|
|
|
});
|
2018-05-29 18:32:49 +02:00
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
|
2018-07-03 15:48:21 +02:00
|
|
|
if (this.sessionEvents.streamPropertyChanged !== oldValues.streamPropertyChanged || firstTime) {
|
|
|
|
this.session.off('streamPropertyChanged');
|
|
|
|
if (this.sessionEvents.streamPropertyChanged) {
|
|
|
|
this.session.on('streamPropertyChanged', (event: StreamPropertyChangedEvent) => {
|
2018-08-01 15:12:34 +02:00
|
|
|
let newValue: string;
|
|
|
|
if (event.changedProperty === 'filter') {
|
|
|
|
newValue = !event.newValue ? undefined : event.newValue.toString();
|
|
|
|
} else {
|
|
|
|
newValue = event.changedProperty === 'videoDimensions' ? JSON.stringify(event.newValue) : event.newValue.toString();
|
|
|
|
}
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('streamPropertyChanged', event.changedProperty + ' [' + newValue + ']', event);
|
2018-07-03 15:48:21 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.connectionCreated !== oldValues.connectionCreated || firstTime) {
|
|
|
|
this.session.off('connectionCreated');
|
|
|
|
if (this.sessionEvents.connectionCreated) {
|
|
|
|
this.session.on('connectionCreated', (event: ConnectionEvent) => {
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('connectionCreated', event.connection.connectionId, event);
|
2018-04-17 15:08:02 +02:00
|
|
|
});
|
2018-05-29 18:32:49 +02:00
|
|
|
}
|
2018-01-11 11:13:50 +01:00
|
|
|
}
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.connectionDestroyed !== oldValues.connectionDestroyed || firstTime) {
|
|
|
|
this.session.off('connectionDestroyed');
|
|
|
|
if (this.sessionEvents.connectionDestroyed) {
|
|
|
|
this.session.on('connectionDestroyed', (event: ConnectionEvent) => {
|
|
|
|
delete this.subscribers[event.connection.connectionId];
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('connectionDestroyed', event.connection.connectionId, event);
|
2018-05-29 18:32:49 +02:00
|
|
|
});
|
2018-01-18 16:09:39 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.sessionDisconnected !== oldValues.sessionDisconnected || firstTime) {
|
|
|
|
this.session.off('sessionDisconnected');
|
|
|
|
if (this.sessionEvents.sessionDisconnected) {
|
|
|
|
this.session.on('sessionDisconnected', (event: SessionDisconnectedEvent) => {
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('sessionDisconnected', '', event);
|
2018-07-19 12:59:58 +02:00
|
|
|
this.subscribers = [];
|
|
|
|
delete this.publisher;
|
|
|
|
delete this.session;
|
|
|
|
delete this.OV;
|
2018-04-17 15:08:02 +02:00
|
|
|
});
|
2018-01-18 16:09:39 +01:00
|
|
|
}
|
2018-05-29 18:32:49 +02:00
|
|
|
}
|
2018-01-18 16:09:39 +01:00
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.signal !== oldValues.signal || firstTime) {
|
|
|
|
this.session.off('signal');
|
|
|
|
if (this.sessionEvents.signal) {
|
|
|
|
this.session.on('signal', (event: SignalEvent) => {
|
2019-09-16 10:57:20 +02:00
|
|
|
this.updateEventList('signal', !!event.from ? event.from.connectionId : 'server'
|
|
|
|
+ ' - ' + event.type
|
|
|
|
+ ' - ' + event.data, event);
|
2018-05-29 18:32:49 +02:00
|
|
|
});
|
2018-04-17 15:08:02 +02:00
|
|
|
}
|
2018-05-29 18:32:49 +02:00
|
|
|
}
|
2018-01-18 16:09:39 +01:00
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.recordingStarted !== oldValues.recordingStarted || firstTime) {
|
|
|
|
this.session.off('recordingStarted');
|
|
|
|
if (this.sessionEvents.recordingStarted) {
|
|
|
|
this.session.on('recordingStarted', (event: RecordingEvent) => {
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('recordingStarted', event.id, event);
|
2018-05-29 18:32:49 +02:00
|
|
|
});
|
2018-01-18 16:09:39 +01:00
|
|
|
}
|
2018-03-02 11:36:12 +01:00
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.recordingStopped !== oldValues.recordingStopped || firstTime) {
|
|
|
|
this.session.off('recordingStopped');
|
|
|
|
if (this.sessionEvents.recordingStopped) {
|
|
|
|
this.session.on('recordingStopped', (event: RecordingEvent) => {
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('recordingStopped', event.id, event);
|
2018-05-29 18:32:49 +02:00
|
|
|
});
|
2018-03-02 11:36:12 +01:00
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.publisherStartSpeaking !== oldValues.publisherStartSpeaking || firstTime) {
|
|
|
|
this.session.off('publisherStartSpeaking');
|
|
|
|
if (this.sessionEvents.publisherStartSpeaking) {
|
|
|
|
this.session.on('publisherStartSpeaking', (event: PublisherSpeakingEvent) => {
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('publisherStartSpeaking', event.connection.connectionId, event);
|
2018-05-29 18:32:49 +02:00
|
|
|
});
|
2018-03-02 11:36:12 +01:00
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
2018-03-02 11:36:12 +01:00
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.publisherStopSpeaking !== oldValues.publisherStopSpeaking || firstTime) {
|
2018-07-22 22:54:36 +02:00
|
|
|
if (!this.sessionEvents.publisherStartSpeaking) {
|
|
|
|
this.session.off('publisherStopSpeaking');
|
|
|
|
}
|
2018-05-29 18:32:49 +02:00
|
|
|
if (this.sessionEvents.publisherStopSpeaking) {
|
|
|
|
this.session.on('publisherStopSpeaking', (event: PublisherSpeakingEvent) => {
|
2019-02-06 15:04:49 +01:00
|
|
|
this.updateEventList('publisherStopSpeaking', event.connection.connectionId, event);
|
2018-05-29 18:32:49 +02:00
|
|
|
});
|
|
|
|
}
|
2018-03-02 11:36:12 +01:00
|
|
|
}
|
2020-02-17 22:00:51 +01:00
|
|
|
|
|
|
|
if (this.sessionEvents.reconnecting !== oldValues.reconnecting || firstTime) {
|
|
|
|
this.session.off('reconnecting');
|
|
|
|
if (this.sessionEvents.reconnecting) {
|
|
|
|
this.session.on('reconnecting', () => {
|
|
|
|
this.updateEventList('reconnecting', '', undefined);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.sessionEvents.reconnected !== oldValues.reconnected || firstTime) {
|
|
|
|
this.session.off('reconnected');
|
|
|
|
if (this.sessionEvents.reconnected) {
|
|
|
|
this.session.on('reconnected', () => {
|
|
|
|
this.updateEventList('reconnected', '', undefined);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
|
2018-04-17 15:08:02 +02:00
|
|
|
syncInitPublisher() {
|
|
|
|
this.publisher = this.OV.initPublisher(
|
2018-05-29 18:32:49 +02:00
|
|
|
undefined,
|
2018-05-31 13:08:34 +02:00
|
|
|
this.publisherProperties,
|
2019-01-21 18:46:40 +01:00
|
|
|
err => {
|
2018-04-17 15:08:02 +02:00
|
|
|
if (err) {
|
|
|
|
console.warn(err);
|
|
|
|
this.openviduError = err;
|
|
|
|
if (err.name === 'SCREEN_EXTENSION_NOT_INSTALLED') {
|
2018-05-18 12:46:41 +02:00
|
|
|
this.dialog.open(ExtensionDialogComponent, {
|
2018-04-17 15:08:02 +02:00
|
|
|
data: { url: err.message },
|
|
|
|
disableClose: true,
|
|
|
|
width: '250px'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if (this.subscribeToRemote) {
|
|
|
|
this.publisher.subscribeToRemote();
|
|
|
|
}
|
|
|
|
|
2018-07-09 16:29:21 +02:00
|
|
|
this.session.publish(this.publisher).catch((error: OpenViduError) => {
|
|
|
|
console.error(error);
|
|
|
|
this.session.unpublish(this.publisher);
|
|
|
|
});
|
2018-04-17 15:08:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
syncSubscribe(session: Session, event) {
|
2018-05-29 18:32:49 +02:00
|
|
|
this.subscribers.push(session.subscribe(event.stream, undefined));
|
2018-04-17 15:08:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
initGrayVideo(): void {
|
|
|
|
this.OV.getUserMedia(
|
|
|
|
{
|
|
|
|
videoSource: undefined,
|
|
|
|
resolution: '1280x720',
|
2018-08-31 16:34:04 +02:00
|
|
|
frameRate: 30,
|
2018-04-17 15:08:02 +02:00
|
|
|
}
|
|
|
|
)
|
2018-04-23 11:08:07 +02:00
|
|
|
.then((mediaStream: MediaStream) => {
|
2018-09-27 09:51:24 +02:00
|
|
|
|
|
|
|
const videoStreamTrack: MediaStreamTrack = mediaStream.getVideoTracks()[0];
|
|
|
|
const video: HTMLVideoElement = document.createElement('video');
|
2018-04-23 11:08:07 +02:00
|
|
|
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);
|
2018-08-31 16:34:04 +02:00
|
|
|
setTimeout(loop, 33); // Drawing at 30fps
|
2018-04-23 11:08:07 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
loop();
|
2018-04-17 15:08:02 +02:00
|
|
|
});
|
2018-09-27 09:51:24 +02:00
|
|
|
const grayVideoTrack: MediaStreamTrack = (<MediaStream>canvas.captureStream(30)).getVideoTracks()[0];
|
2018-08-31 16:34:04 +02:00
|
|
|
this.publisher = this.OV.initPublisher(
|
2018-04-23 11:08:07 +02:00
|
|
|
document.body,
|
|
|
|
{
|
|
|
|
audioSource: false,
|
|
|
|
videoSource: grayVideoTrack,
|
2018-04-27 11:08:03 +02:00
|
|
|
insertMode: VideoInsertMode.APPEND
|
2018-04-23 11:08:07 +02:00
|
|
|
});
|
2018-09-27 09:51:24 +02:00
|
|
|
this.session.publish(this.publisher).catch((error: OpenViduError) => {
|
|
|
|
console.error(error);
|
|
|
|
this.session.unpublish(this.publisher);
|
|
|
|
});
|
|
|
|
|
2018-04-17 15:08:02 +02:00
|
|
|
})
|
2018-04-23 11:08:07 +02:00
|
|
|
.catch(error => {
|
|
|
|
console.error(error);
|
|
|
|
});
|
2018-04-17 15:08:02 +02:00
|
|
|
}
|
|
|
|
|
2018-05-18 12:46:41 +02:00
|
|
|
openSessionPropertiesDialog() {
|
|
|
|
this.sessionProperties.customSessionId = this.sessionName;
|
|
|
|
const dialogRef = this.dialog.open(SessionPropertiesDialogComponent, {
|
2018-06-08 11:07:38 +02:00
|
|
|
data: {
|
|
|
|
sessionProperties: this.sessionProperties,
|
|
|
|
turnConf: this.turnConf,
|
2018-07-09 16:29:21 +02:00
|
|
|
manualTurnConf: this.manualTurnConf,
|
2018-08-01 15:12:34 +02:00
|
|
|
customToken: this.customToken,
|
|
|
|
tokenOptions: this.tokenOptions
|
2018-06-08 11:07:38 +02:00
|
|
|
},
|
2018-08-01 15:12:34 +02:00
|
|
|
width: '450px'
|
2018-05-18 12:46:41 +02:00
|
|
|
});
|
|
|
|
|
2019-01-21 18:46:40 +01:00
|
|
|
dialogRef.afterClosed().subscribe(result => {
|
2018-05-18 12:46:41 +02:00
|
|
|
if (!!result) {
|
2018-06-08 11:07:38 +02:00
|
|
|
this.sessionProperties = result.sessionProperties;
|
2018-05-18 12:46:41 +02:00
|
|
|
if (!!this.sessionProperties.customSessionId) {
|
|
|
|
this.sessionName = this.sessionProperties.customSessionId;
|
|
|
|
}
|
2018-06-08 11:07:38 +02:00
|
|
|
this.turnConf = result.turnConf;
|
|
|
|
this.manualTurnConf = result.manualTurnConf;
|
2018-07-23 18:20:01 +02:00
|
|
|
this.customToken = result.customToken;
|
2018-08-01 15:12:34 +02:00
|
|
|
this.tokenOptions = result.tokenOptions;
|
2018-05-18 12:46:41 +02:00
|
|
|
}
|
2018-05-29 18:32:49 +02:00
|
|
|
document.getElementById('session-settings-btn-' + this.index).classList.remove('cdk-program-focused');
|
2018-05-18 12:46:41 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
openSessionApiDialog() {
|
|
|
|
const dialogRef = this.dialog.open(SessionApiDialogComponent, {
|
|
|
|
data: {
|
2019-01-21 18:46:40 +01:00
|
|
|
openVidu: !!this.OV_NodeClient ? this.OV_NodeClient : new OpenViduAPI(this.openviduUrl, this.openviduSecret),
|
2018-07-13 13:47:06 +02:00
|
|
|
session: this.sessionAPI,
|
2019-01-21 18:46:40 +01:00
|
|
|
sessionId: !!this.session ? this.session.sessionId : this.sessionName,
|
|
|
|
recordingProperties: !!this.recordingProperties ? this.recordingProperties :
|
|
|
|
{
|
|
|
|
name: '',
|
2019-01-29 18:18:53 +01:00
|
|
|
outputMode: this.sessionProperties.defaultOutputMode,
|
2019-01-21 18:46:40 +01:00
|
|
|
recordingLayout: this.sessionProperties.defaultRecordingLayout,
|
|
|
|
customLayout: this.sessionProperties.defaultCustomLayout,
|
2019-01-22 15:10:59 +01:00
|
|
|
resolution: '1920x1080',
|
2019-01-21 18:46:40 +01:00
|
|
|
hasAudio: true,
|
|
|
|
hasVideo: true
|
|
|
|
}
|
2018-05-18 12:46:41 +02:00
|
|
|
},
|
2019-01-21 18:46:40 +01:00
|
|
|
width: '425px',
|
2018-05-31 13:08:34 +02:00
|
|
|
disableClose: true
|
2018-05-18 12:46:41 +02:00
|
|
|
});
|
|
|
|
|
2018-07-13 13:47:06 +02:00
|
|
|
dialogRef.afterClosed().subscribe(result => {
|
|
|
|
if (!result.session) {
|
|
|
|
delete this.sessionAPI;
|
|
|
|
}
|
2019-01-21 18:46:40 +01:00
|
|
|
this.recordingProperties = result.recordingProperties;
|
2018-05-29 18:32:49 +02:00
|
|
|
document.getElementById('session-api-btn-' + this.index).classList.remove('cdk-program-focused');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
openSessionEventsDialog() {
|
|
|
|
|
|
|
|
const oldValues = {
|
|
|
|
connectionCreated: this.sessionEvents.connectionCreated,
|
|
|
|
connectionDestroyed: this.sessionEvents.connectionDestroyed,
|
|
|
|
sessionDisconnected: this.sessionEvents.sessionDisconnected,
|
|
|
|
streamCreated: this.sessionEvents.streamCreated,
|
|
|
|
streamDestroyed: this.sessionEvents.streamDestroyed,
|
2018-07-03 15:48:21 +02:00
|
|
|
streamPropertyChanged: this.sessionEvents.streamPropertyChanged,
|
2018-05-29 18:32:49 +02:00
|
|
|
recordingStarted: this.sessionEvents.recordingStarted,
|
|
|
|
recordingStopped: this.sessionEvents.recordingStopped,
|
|
|
|
signal: this.sessionEvents.signal,
|
|
|
|
publisherStartSpeaking: this.sessionEvents.publisherStartSpeaking,
|
2020-02-17 22:00:51 +01:00
|
|
|
publisherStopSpeaking: this.sessionEvents.publisherStopSpeaking,
|
|
|
|
reconnecting: this.sessionEvents.reconnecting,
|
|
|
|
reconnected: this.sessionEvents.reconnected
|
2018-05-29 18:32:49 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
const dialogRef = this.dialog.open(EventsDialogComponent, {
|
|
|
|
data: {
|
|
|
|
eventCollection: this.sessionEvents,
|
|
|
|
target: 'Session'
|
|
|
|
},
|
|
|
|
width: '280px',
|
|
|
|
autoFocus: false,
|
|
|
|
disableClose: true
|
|
|
|
});
|
|
|
|
|
2019-01-21 18:46:40 +01:00
|
|
|
dialogRef.afterClosed().subscribe(result => {
|
2018-05-29 18:32:49 +02:00
|
|
|
|
|
|
|
if (!!this.session && JSON.stringify(this.sessionEvents) !== JSON.stringify(oldValues)) {
|
|
|
|
this.updateSessionEvents(oldValues, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.sessionEvents = {
|
|
|
|
connectionCreated: result.connectionCreated,
|
|
|
|
connectionDestroyed: result.connectionDestroyed,
|
|
|
|
sessionDisconnected: result.sessionDisconnected,
|
|
|
|
streamCreated: result.streamCreated,
|
|
|
|
streamDestroyed: result.streamDestroyed,
|
2018-07-03 15:48:21 +02:00
|
|
|
streamPropertyChanged: result.streamPropertyChanged,
|
2018-05-29 18:32:49 +02:00
|
|
|
recordingStarted: result.recordingStarted,
|
|
|
|
recordingStopped: result.recordingStopped,
|
|
|
|
signal: result.signal,
|
|
|
|
publisherStartSpeaking: result.publisherStartSpeaking,
|
2020-02-17 22:00:51 +01:00
|
|
|
publisherStopSpeaking: result.publisherStopSpeaking,
|
|
|
|
reconnecting: result.reconnecting,
|
|
|
|
reconnected: result.reconnected
|
2018-05-29 18:32:49 +02:00
|
|
|
};
|
|
|
|
document.getElementById('session-events-btn-' + this.index).classList.remove('cdk-program-focused');
|
2018-05-18 12:46:41 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-05-31 13:08:34 +02:00
|
|
|
openPublisherPropertiesDialog() {
|
|
|
|
const dialogRef = this.dialog.open(PublisherPropertiesDialogComponent, {
|
|
|
|
data: this.publisherProperties,
|
|
|
|
width: '300px',
|
|
|
|
disableClose: true
|
|
|
|
});
|
|
|
|
|
|
|
|
dialogRef.afterClosed().subscribe((result: PublisherProperties) => {
|
|
|
|
if (!!result) {
|
|
|
|
this.publisherProperties = result;
|
|
|
|
this.optionsVideo = this.publisherProperties.videoSource === 'screen' ? 'screen' : 'video';
|
|
|
|
}
|
|
|
|
document.getElementById('publisher-settings-btn-' + this.index).classList.remove('cdk-program-focused');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-05-18 12:46:41 +02:00
|
|
|
getToken(): Promise<string> {
|
2018-07-23 00:36:45 +02:00
|
|
|
this.OV_NodeClient = new OpenViduAPI(this.openviduUrl, this.openviduSecret);
|
2018-05-18 12:46:41 +02:00
|
|
|
if (!this.sessionProperties.customSessionId) {
|
|
|
|
this.sessionProperties.customSessionId = this.sessionName;
|
|
|
|
}
|
2018-07-23 00:36:45 +02:00
|
|
|
return this.OV_NodeClient.createSession(this.sessionProperties)
|
2018-05-18 12:46:41 +02:00
|
|
|
.then(session_NodeClient => {
|
2018-07-13 13:47:06 +02:00
|
|
|
this.sessionAPI = session_NodeClient;
|
2018-08-01 15:12:34 +02:00
|
|
|
return session_NodeClient.generateToken({ role: this.tokenOptions.role, kurentoOptions: this.tokenOptions.kurentoOptions });
|
2018-05-18 12:46:41 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2019-02-06 15:04:49 +01:00
|
|
|
updateEventFromChild(event: OpenViduEvent) {
|
|
|
|
this.updateEventList(event.eventName, event.eventContent, event.event);
|
2018-05-29 18:32:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
updateSubscriberFromChild(newSubscriber: Subscriber) {
|
|
|
|
const oldSubscriber = this.subscribers.filter(sub => {
|
|
|
|
return sub.stream.streamId === newSubscriber.stream.streamId;
|
|
|
|
})[0];
|
|
|
|
this.subscribers[this.subscribers.indexOf(oldSubscriber)] = newSubscriber;
|
|
|
|
}
|
|
|
|
|
2018-05-31 13:08:34 +02:00
|
|
|
updateOptionsVideo(change) {
|
|
|
|
if (change.value === 'screen') {
|
|
|
|
this.publisherPropertiesAux.videoSource = this.publisherProperties.videoSource;
|
|
|
|
this.publisherProperties.videoSource = 'screen';
|
|
|
|
} else {
|
|
|
|
this.publisherProperties.videoSource = this.publisherPropertiesAux.videoSource;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
isVideo(): boolean {
|
|
|
|
return (this.publisherProperties.videoSource === undefined ||
|
|
|
|
typeof this.publisherProperties.videoSource === 'string' &&
|
|
|
|
this.publisherProperties.videoSource !== 'screen');
|
|
|
|
}
|
|
|
|
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|