2017-09-30 13:48:40 +02:00
|
|
|
import {
|
|
|
|
Component, Input, HostListener, ChangeDetectorRef, SimpleChanges, ElementRef, ViewChild,
|
|
|
|
OnInit, OnDestroy, OnChanges
|
|
|
|
} from '@angular/core';
|
2017-09-29 13:54:22 +02:00
|
|
|
import { OpenVidu, Session, Subscriber, Publisher, Stream } from 'openvidu-browser';
|
2017-09-28 19:13:29 +02:00
|
|
|
|
|
|
|
declare var $: any;
|
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'app-openvidu-instance',
|
|
|
|
templateUrl: './openvidu-instance.component.html',
|
|
|
|
styleUrls: ['./openvidu-instance.component.css']
|
|
|
|
})
|
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-09-29 16:19:23 +02:00
|
|
|
// Session join data
|
|
|
|
clientData: string;
|
|
|
|
sessionName: string;
|
|
|
|
|
|
|
|
// Session options
|
2017-09-29 13:54:22 +02:00
|
|
|
subscribeTo = true;
|
|
|
|
publishTo = true;
|
2017-09-28 19:13:29 +02:00
|
|
|
sendAudio = true;
|
|
|
|
sendVideo = true;
|
|
|
|
activeAudio = true;
|
|
|
|
activeVideo = true;
|
|
|
|
sendVideoRadio = true;
|
2017-09-29 13:54:22 +02:00
|
|
|
subscribeToRemote = false;
|
2017-09-29 16:19:23 +02:00
|
|
|
optionsVideo = 'video';
|
|
|
|
|
|
|
|
// Form 'check' and 'disable' attributes
|
|
|
|
checkSubscribeTo = true;
|
|
|
|
checkPublishTo = true;
|
|
|
|
checkSendAudio = true;
|
|
|
|
checkSendVideo = true;
|
|
|
|
checkActiveAudio = true;
|
|
|
|
checkActiveVideo = true;
|
|
|
|
checkRadioVideo = true;
|
|
|
|
checkRadioScreen = false;
|
|
|
|
disableSubscribeTo = false;
|
|
|
|
disablePublishTo = false;
|
|
|
|
disableSendAudio = false;
|
|
|
|
disableSendVideo = false;
|
|
|
|
disableActiveAudio = false;
|
|
|
|
disableActiveVideo = false;
|
|
|
|
disableRadioButtons = false;
|
2017-09-28 19:13:29 +02:00
|
|
|
|
|
|
|
// OpenVidu objects
|
|
|
|
OV: OpenVidu;
|
|
|
|
session: Session;
|
2017-09-29 13:54:22 +02:00
|
|
|
publisher: Publisher;
|
|
|
|
|
2017-09-29 16:19:23 +02:00
|
|
|
// Session audio and video status
|
2017-09-29 13:54:22 +02:00
|
|
|
audioMuted = false;
|
|
|
|
videoMuted = false;
|
|
|
|
audioIcon = 'mic';
|
|
|
|
videoIcon = 'videocam';
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2017-09-30 13:48:40 +02:00
|
|
|
events: string[] = [];
|
|
|
|
|
2017-09-28 19:13:29 +02:00
|
|
|
constructor(private changeDetector: ChangeDetectorRef) {
|
|
|
|
this.generateSessionInfo();
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnInit() { }
|
|
|
|
|
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';
|
|
|
|
}
|
|
|
|
|
|
|
|
private removeHttps = input => input.replace(/^https?:\/\//, '');
|
|
|
|
|
|
|
|
private joinSession(): void {
|
|
|
|
|
|
|
|
if (this.session) {
|
|
|
|
this.leaveSession();
|
|
|
|
}
|
|
|
|
|
|
|
|
const OV: OpenVidu = new OpenVidu();
|
|
|
|
|
|
|
|
this.session = OV.initSession('wss://'
|
2017-09-30 13:48:40 +02:00
|
|
|
+ this.removeHttps(this.openviduUrl)
|
2017-09-28 19:13:29 +02:00
|
|
|
+ '/'
|
|
|
|
+ this.sessionName + '?secret='
|
|
|
|
+ this.openviduSecret);
|
|
|
|
|
|
|
|
this.session.on('streamCreated', (event) => {
|
|
|
|
|
|
|
|
this.changeDetector.detectChanges();
|
|
|
|
|
2017-09-29 13:54:22 +02:00
|
|
|
if (this.subscribeTo) {
|
|
|
|
const subscriber: Subscriber = this.session.subscribe(event.stream, 'remote-vid-' + this.session.connection.connectionId);
|
|
|
|
subscriber.on('videoElementCreated', (e) => {
|
|
|
|
this.appendUserData(e.element, subscriber.stream.connection.data, subscriber.stream.connection);
|
2017-09-30 13:48:40 +02:00
|
|
|
this.updateEventList('videoElementCreated');
|
2017-09-29 13:54:22 +02:00
|
|
|
});
|
|
|
|
subscriber.on('videoPlaying', (e) => {
|
2017-09-30 13:48:40 +02:00
|
|
|
this.updateEventList('videoPlaying');
|
2017-09-29 13:54:22 +02:00
|
|
|
});
|
|
|
|
}
|
2017-09-30 13:48:40 +02:00
|
|
|
this.updateEventList('streamCreated');
|
2017-09-28 19:13:29 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
this.session.on('streamDestroyed', (event) => {
|
|
|
|
this.removeUserData(event.stream.connection);
|
2017-09-30 13:48:40 +02:00
|
|
|
this.updateEventList('streamDestroyed');
|
2017-09-28 19:13:29 +02:00
|
|
|
});
|
|
|
|
|
2017-09-30 13:48:40 +02:00
|
|
|
this.session.on('connectionCreated', (event) => {
|
|
|
|
this.updateEventList('connectionCreated');
|
|
|
|
});
|
|
|
|
this.session.on('connetionDestroyed', (event) => {
|
|
|
|
this.updateEventList('connetionDestroyed');
|
|
|
|
});
|
|
|
|
this.session.on('sessionDisconnected', (event) => {
|
|
|
|
this.updateEventList('sessionDisconnected');
|
|
|
|
});
|
2017-09-28 19:13:29 +02:00
|
|
|
|
|
|
|
this.session.connect(null, this.clientData, (error) => {
|
|
|
|
if (!error) {
|
2017-09-29 13:54:22 +02:00
|
|
|
if (this.publishTo) {
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2017-09-29 13:54:22 +02:00
|
|
|
this.audioMuted = !this.activeAudio;
|
|
|
|
this.videoMuted = !this.activeVideo;
|
|
|
|
this.updateAudioIcon();
|
|
|
|
this.updateVideoIcon();
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2017-09-29 13:54:22 +02:00
|
|
|
this.publisher = OV.initPublisher('local-vid-' + this.session.connection.connectionId, {
|
2017-09-29 16:19:23 +02:00
|
|
|
audio: this.sendAudio,
|
|
|
|
video: this.sendVideo,
|
|
|
|
activeAudio: this.activeAudio,
|
|
|
|
activeVideo: this.activeVideo,
|
2017-09-29 13:54:22 +02:00
|
|
|
quality: 'MEDIUM'
|
|
|
|
});
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2017-09-29 13:54:22 +02:00
|
|
|
this.publisher.on('videoElementCreated', (event) => {
|
2017-09-30 13:48:40 +02:00
|
|
|
this.updateEventList('videoElementCreated');
|
2017-09-29 13:54:22 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
this.publisher.on('videoPlaying', (e) => {
|
2017-09-30 13:48:40 +02:00
|
|
|
this.updateEventList('videoPlaying');
|
|
|
|
});
|
|
|
|
|
|
|
|
this.publisher.on('remoteVideoPlaying', (e) => {
|
|
|
|
this.updateEventList('remoteVideoPlaying');
|
2017-09-29 13:54:22 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
if (this.subscribeToRemote) {
|
|
|
|
this.publisher.subscribeToRemote();
|
|
|
|
}
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2017-09-29 13:54:22 +02:00
|
|
|
this.session.publish(this.publisher);
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2017-09-29 13:54:22 +02:00
|
|
|
}
|
2017-09-28 19:13:29 +02:00
|
|
|
} else {
|
|
|
|
console.log('There was an error connecting to the session:', error.code, error.message);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private leaveSession(): void {
|
|
|
|
if (this.session) {
|
|
|
|
this.session.disconnect();
|
|
|
|
}
|
|
|
|
this.session = null;
|
|
|
|
this.OV = null;
|
2017-09-29 13:54:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private toggleAudio() {
|
|
|
|
this.publisher.publishAudio(this.audioMuted);
|
|
|
|
this.audioMuted = !this.audioMuted;
|
|
|
|
this.updateAudioIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
private updateAudioIcon() {
|
|
|
|
this.audioMuted ? this.audioIcon = 'mic_off' : this.audioIcon = 'mic';
|
|
|
|
}
|
|
|
|
|
|
|
|
private toggleVideo() {
|
|
|
|
this.publisher.publishVideo(this.videoMuted);
|
|
|
|
this.videoMuted = !this.videoMuted;
|
|
|
|
this.updateVideoIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
private updateVideoIcon() {
|
|
|
|
this.videoMuted ? this.videoIcon = 'videocam_off' : this.videoIcon = 'videocam';
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private appendUserData(videoElement, data, connection): void {
|
2017-09-29 13:54:22 +02:00
|
|
|
const dataNode = document.createElement('div');
|
2017-09-28 19:13:29 +02:00
|
|
|
dataNode.className = 'data-node';
|
|
|
|
dataNode.id = 'data-' + (connection ? connection.connectionId : data);
|
|
|
|
dataNode.innerHTML = '<p>' + data + '</p>';
|
2017-09-29 13:54:22 +02:00
|
|
|
videoElement.parentNode.insertBefore(dataNode, videoElement.nextSibling);
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private removeUserData(connection): void {
|
2017-09-29 13:54:22 +02:00
|
|
|
$('#remote-vid-' + this.session.connection.connectionId).find('#data-' + connection.connectionId).remove();
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
2017-09-30 13:48:40 +02:00
|
|
|
private updateEventList(event: string) {
|
|
|
|
this.events.push(event);
|
|
|
|
}
|
|
|
|
|
2017-09-29 16:19:23 +02:00
|
|
|
toggleSubscribeTo(): void {
|
|
|
|
this.subscribeTo = !this.subscribeTo;
|
|
|
|
}
|
|
|
|
|
|
|
|
togglePublishTo(): void {
|
|
|
|
this.publishTo = !this.publishTo;
|
|
|
|
|
|
|
|
this.sendAudio = this.publishTo;
|
|
|
|
this.sendVideo = this.publishTo;
|
|
|
|
this.activeAudio = this.publishTo;
|
|
|
|
this.activeVideo = this.publishTo;
|
|
|
|
|
|
|
|
this.checkPublishTo = this.publishTo;
|
|
|
|
this.checkSendAudio = this.publishTo;
|
|
|
|
this.checkSendVideo = this.publishTo;
|
|
|
|
this.checkActiveAudio = this.publishTo;
|
|
|
|
this.checkActiveVideo = this.publishTo;
|
|
|
|
|
|
|
|
if (this.publishTo) {
|
|
|
|
this.checkRadioVideo = true;
|
|
|
|
this.optionsVideo = 'video';
|
|
|
|
} else {
|
|
|
|
this.checkRadioVideo = false;
|
|
|
|
this.optionsVideo = '';
|
2017-09-29 13:54:22 +02:00
|
|
|
}
|
2017-09-29 16:19:23 +02:00
|
|
|
|
|
|
|
this.disableSendAudio = !this.publishTo;
|
|
|
|
this.disableSendVideo = !this.publishTo;
|
|
|
|
this.disableActiveAudio = !this.publishTo;
|
|
|
|
this.disableActiveVideo = !this.publishTo;
|
|
|
|
this.disableRadioButtons = !this.publishTo;
|
|
|
|
|
|
|
|
this.subscribeToRemote = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleSendAudio(): void {
|
|
|
|
this.sendAudio = !this.sendAudio;
|
|
|
|
|
|
|
|
this.activeAudio = this.sendAudio;
|
|
|
|
this.checkActiveAudio = this.sendAudio;
|
|
|
|
this.disableActiveAudio = !this.sendAudio;
|
|
|
|
|
|
|
|
if (!this.sendAudio && !this.sendVideo && this.publishTo) {
|
|
|
|
this.togglePublishTo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleSendVideo(): void {
|
|
|
|
this.sendVideo = !this.sendVideo;
|
|
|
|
|
|
|
|
this.activeVideo = this.sendVideo;
|
|
|
|
|
|
|
|
this.checkActiveVideo = this.sendVideo;
|
|
|
|
this.checkRadioScreen = false;
|
|
|
|
if (this.sendVideo) {
|
|
|
|
this.checkRadioVideo = true;
|
|
|
|
this.optionsVideo = 'video';
|
|
|
|
} else {
|
|
|
|
this.checkRadioVideo = false;
|
|
|
|
this.optionsVideo = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
this.disableActiveVideo = !this.sendVideo;
|
|
|
|
this.disableRadioButtons = !this.sendVideo;
|
|
|
|
|
|
|
|
if (!this.sendAudio && !this.sendVideo && this.publishTo) {
|
|
|
|
this.togglePublishTo();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleActiveAudio(): void {
|
|
|
|
this.activeAudio = !this.activeAudio;
|
|
|
|
}
|
|
|
|
|
|
|
|
toggleActiveVideo(): void {
|
|
|
|
this.activeVideo = !this.activeVideo;
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|