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 {
|
2018-06-15 14:45:47 +02:00
|
|
|
OpenVidu, Session, Subscriber, Publisher, VideoInsertMode, StreamEvent, ConnectionEvent,
|
|
|
|
SessionDisconnectedEvent, SignalEvent, RecordingEvent,
|
2018-07-09 16:29:21 +02: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,
|
|
|
|
OpenViduRole
|
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 {
|
|
|
|
name: string;
|
|
|
|
content: string;
|
|
|
|
}
|
|
|
|
|
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';
|
|
|
|
|
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-13 13:47:06 +02:00
|
|
|
sessionAPI: SessionAPI;
|
2018-05-18 12:46:41 +02:00
|
|
|
sessionProperties: SessionPropertiesAPI = {
|
|
|
|
mediaMode: MediaMode.ROUTED,
|
|
|
|
recordingMode: RecordingMode.MANUAL,
|
|
|
|
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,
|
|
|
|
publisherStopSpeaking: false
|
|
|
|
};
|
2018-01-18 16:09:39 +01:00
|
|
|
|
2018-06-08 11:07:38 +02:00
|
|
|
turnConf = 'auto';
|
|
|
|
manualTurnConf: RTCIceServer = { urls: [] };
|
2018-07-09 16:29:21 +02:00
|
|
|
participantRole: OpenViduRole = OpenViduRole.PUBLISHER;
|
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-05-18 12:46:41 +02:00
|
|
|
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,
|
|
|
|
publisherStopSpeaking: true
|
|
|
|
}, 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();
|
|
|
|
|
2017-09-29 13:54:22 +02:00
|
|
|
if (this.publishTo) {
|
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-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
|
|
|
}
|
|
|
|
|
2017-10-02 15:18:28 +02:00
|
|
|
private updateEventList(event: string, content: string) {
|
|
|
|
this.events.push({ name: event, content: content });
|
2017-10-09 18:48:05 +02:00
|
|
|
this.testFeedService.pushNewEvent(this.sessionName, this.session.connection.connectionId, event, content);
|
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);
|
|
|
|
}
|
|
|
|
this.updateEventList('streamCreated', event.stream.streamId);
|
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);
|
|
|
|
}
|
|
|
|
this.updateEventList('streamDestroyed', event.stream.streamId);
|
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) => {
|
|
|
|
const newValue = event.changedProperty === 'videoDimensions' ? JSON.stringify(event.newValue) : event.newValue.toString();
|
|
|
|
this.updateEventList('streamPropertyChanged', event.changedProperty + ' [' + newValue + ']');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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) => {
|
|
|
|
this.updateEventList('connectionCreated', event.connection.connectionId);
|
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];
|
|
|
|
this.updateEventList('connectionDestroyed', event.connection.connectionId);
|
|
|
|
});
|
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) => {
|
|
|
|
this.updateEventList('sessionDisconnected', 'No data');
|
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) => {
|
|
|
|
this.updateEventList('signal', event.from.connectionId + '-' + event.data);
|
|
|
|
});
|
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) => {
|
|
|
|
this.updateEventList('recordingStarted', event.id);
|
|
|
|
});
|
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) => {
|
|
|
|
this.updateEventList('recordingStopped', event.id);
|
|
|
|
});
|
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) => {
|
|
|
|
this.updateEventList('publisherStartSpeaking', event.connection.connectionId);
|
|
|
|
});
|
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) => {
|
|
|
|
this.updateEventList('publisherStopSpeaking', event.connection.connectionId);
|
|
|
|
});
|
|
|
|
}
|
2018-03-02 11:36:12 +01:00
|
|
|
}
|
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,
|
2018-04-17 15:08:02 +02:00
|
|
|
(err) => {
|
|
|
|
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',
|
|
|
|
frameRate: 10,
|
|
|
|
}
|
|
|
|
)
|
2018-04-23 11:08:07 +02:00
|
|
|
.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();
|
2018-04-17 15:08:02 +02:00
|
|
|
});
|
2018-04-23 11:08:07 +02:00
|
|
|
const grayVideoTrack = canvas.captureStream(30).getVideoTracks()[0];
|
|
|
|
this.OV.initPublisher(
|
|
|
|
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-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,
|
|
|
|
participantRole: this.participantRole
|
2018-06-08 11:07:38 +02:00
|
|
|
},
|
|
|
|
width: '280px'
|
2018-05-18 12:46:41 +02:00
|
|
|
});
|
|
|
|
|
2018-06-08 11:07:38 +02: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-09 16:29:21 +02:00
|
|
|
this.participantRole = result.participantRole;
|
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: {
|
|
|
|
openVidu: new OpenViduAPI(this.openviduUrl, this.openviduSecret),
|
2018-07-13 13:47:06 +02:00
|
|
|
session: this.sessionAPI,
|
2018-05-18 12:46:41 +02:00
|
|
|
sessionId: !!this.session ? this.session.sessionId : this.sessionName
|
|
|
|
},
|
2018-05-31 13:08:34 +02:00
|
|
|
width: '280px',
|
|
|
|
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;
|
|
|
|
}
|
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,
|
|
|
|
publisherStopSpeaking: this.sessionEvents.publisherStopSpeaking
|
|
|
|
};
|
|
|
|
|
|
|
|
const dialogRef = this.dialog.open(EventsDialogComponent, {
|
|
|
|
data: {
|
|
|
|
eventCollection: this.sessionEvents,
|
|
|
|
target: 'Session'
|
|
|
|
},
|
|
|
|
width: '280px',
|
|
|
|
autoFocus: false,
|
|
|
|
disableClose: true
|
|
|
|
});
|
|
|
|
|
|
|
|
dialogRef.afterClosed().subscribe((result) => {
|
|
|
|
|
|
|
|
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,
|
|
|
|
publisherStopSpeaking: result.publisherStopSpeaking
|
|
|
|
};
|
|
|
|
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> {
|
|
|
|
const OV_NodeClient = new OpenViduAPI(this.openviduUrl, this.openviduSecret);
|
|
|
|
if (!this.sessionProperties.customSessionId) {
|
|
|
|
this.sessionProperties.customSessionId = this.sessionName;
|
|
|
|
}
|
|
|
|
return OV_NodeClient.createSession(this.sessionProperties)
|
|
|
|
.then(session_NodeClient => {
|
2018-07-13 13:47:06 +02:00
|
|
|
this.sessionAPI = session_NodeClient;
|
2018-07-09 16:29:21 +02:00
|
|
|
return session_NodeClient.generateToken({ role: this.participantRole });
|
2018-05-18 12:46:41 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-05-29 18:32:49 +02:00
|
|
|
udpateEventFromChild(event) {
|
|
|
|
this.updateEventList(event.event, event.content);
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
}
|