2017-09-30 13:48:40 +02:00
|
|
|
import {
|
|
|
|
Component, Input, HostListener, ChangeDetectorRef, SimpleChanges, ElementRef, ViewChild,
|
|
|
|
OnInit, OnDestroy, OnChanges
|
|
|
|
} from '@angular/core';
|
2018-03-01 11:25:25 +01:00
|
|
|
import { Subscription } from 'rxjs/Subscription';
|
|
|
|
|
|
|
|
import { OpenVidu, Session, Subscriber, Publisher, Stream, Connection, LocalRecorder } from 'openvidu-browser';
|
|
|
|
import { MatDialog, MatDialogRef } from '@angular/material';
|
2017-10-04 10:30:15 +02:00
|
|
|
import { ExtensionDialogComponent } from './extension-dialog.component';
|
2018-03-01 11:25:25 +01:00
|
|
|
import { LocalRecordingDialogComponent } from '../test-sessions/local-recording-dialog.component';
|
2017-10-09 18:48:05 +02:00
|
|
|
import { TestFeedService } from '../../services/test-feed.service';
|
2018-03-01 11:25:25 +01:00
|
|
|
import { MuteSubscribersService } from '../../services/mute-subscribers.service';
|
2017-09-28 19:13:29 +02:00
|
|
|
|
|
|
|
declare var $: any;
|
|
|
|
|
2017-10-02 15:18:28 +02:00
|
|
|
export interface SessionConf {
|
|
|
|
subscribeTo: boolean;
|
|
|
|
publishTo: boolean;
|
|
|
|
sendAudio: boolean;
|
|
|
|
sendVideo: 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',
|
|
|
|
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-10-02 15:18:28 +02:00
|
|
|
@Input()
|
|
|
|
sessionConf: SessionConf;
|
|
|
|
|
2017-09-29 16:19:23 +02:00
|
|
|
// Session join data
|
2017-10-16 15:49:23 +02:00
|
|
|
secureSession = false;
|
2017-09-29 16:19:23 +02:00
|
|
|
clientData: string;
|
|
|
|
sessionName: string;
|
2017-10-16 15:49:23 +02:00
|
|
|
sessionIdInput: string;
|
|
|
|
tokenInput: string;
|
2017-09-29 16:19:23 +02:00
|
|
|
|
|
|
|
// Session options
|
2017-10-02 15:18:28 +02:00
|
|
|
subscribeTo;
|
|
|
|
publishTo;
|
|
|
|
sendAudio;
|
|
|
|
sendVideo;
|
2017-09-28 19:13:29 +02:00
|
|
|
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;
|
|
|
|
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;
|
2018-01-11 11:13:50 +01:00
|
|
|
subscribers = {};
|
2017-09-29 13:54:22 +02:00
|
|
|
|
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;
|
2018-01-11 11:13:50 +01:00
|
|
|
unpublished = false;
|
2018-01-18 16:09:39 +01:00
|
|
|
publisherChanged = false;
|
2017-09-29 13:54:22 +02:00
|
|
|
audioIcon = 'mic';
|
|
|
|
videoIcon = 'videocam';
|
2018-01-11 11:13:50 +01:00
|
|
|
publishIcon = 'stop';
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
sendAudioChange: boolean;
|
|
|
|
sendVideoChange: boolean;
|
|
|
|
|
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-03-01 11:25:25 +01:00
|
|
|
private publisherRecorder: LocalRecorder;
|
|
|
|
private publisherRecording = false;
|
|
|
|
private publisherPaused = false;
|
|
|
|
private muteSubscribersSubscription: Subscription;
|
|
|
|
|
2018-01-11 11:13:50 +01:00
|
|
|
constructor(
|
|
|
|
private changeDetector: ChangeDetectorRef,
|
2017-10-16 17:16:14 +02:00
|
|
|
private extensionDialog: MatDialog,
|
2018-03-01 11:25:25 +01:00
|
|
|
private recordDialog: MatDialog,
|
|
|
|
private testFeedService: TestFeedService,
|
|
|
|
private muteSubscribersService: MuteSubscribersService,
|
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;
|
|
|
|
this.sendAudio = this.sessionConf.sendAudio;
|
|
|
|
this.sendVideo = this.sessionConf.sendVideo;
|
|
|
|
|
|
|
|
if (!this.publishTo) {
|
|
|
|
this.publishTo = !this.publishTo;
|
|
|
|
this.togglePublishTo();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.sessionConf.startSession) {
|
|
|
|
this.joinSession();
|
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
|
|
|
|
this.muteSubscribersSubscription = this.muteSubscribersService.mutedEvent$.subscribe(
|
|
|
|
muteOrUnmute => {
|
|
|
|
Object.keys(this.subscribers).forEach((key) => {
|
|
|
|
this.subscribers[key].videoElement.muted = muteOrUnmute;
|
|
|
|
});
|
|
|
|
});
|
2017-10-02 15:18:28 +02:00
|
|
|
}
|
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() {
|
2018-03-01 11:25:25 +01:00
|
|
|
if (!!this.muteSubscribersSubscription) { this.muteSubscribersSubscription.unsubscribe(); }
|
2017-09-28 19:13:29 +02:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2017-10-16 15:49:23 +02:00
|
|
|
let sessionId;
|
|
|
|
let token;
|
|
|
|
|
|
|
|
if (this.secureSession) {
|
|
|
|
sessionId = this.sessionIdInput;
|
|
|
|
token = this.tokenInput;
|
|
|
|
} else {
|
|
|
|
sessionId = 'wss://'
|
|
|
|
+ this.removeHttps(this.openviduUrl)
|
|
|
|
+ this.sessionName + '?secret='
|
|
|
|
+ this.openviduSecret;
|
|
|
|
token = null;
|
|
|
|
}
|
|
|
|
this.joinSessionShared(sessionId, token);
|
|
|
|
}
|
|
|
|
|
|
|
|
private joinSessionShared(sId, token): void {
|
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
this.OV = new OpenVidu();
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
this.session = this.OV.initSession(sId);
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
this.addSessionEvents(this.session);
|
2017-12-12 14:36:43 +01:00
|
|
|
|
2017-10-16 15:49:23 +02:00
|
|
|
this.session.connect(token, this.clientData, (error) => {
|
2017-09-28 19:13:29 +02:00
|
|
|
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;
|
2018-01-11 11:13:50 +01:00
|
|
|
this.unpublished = false;
|
2017-09-29 13:54:22 +02:00
|
|
|
this.updateAudioIcon();
|
|
|
|
this.updateVideoIcon();
|
2018-01-11 11:13:50 +01:00
|
|
|
this.updatePublishIcon();
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
this.sendAudioChange = this.sendAudio;
|
|
|
|
this.sendVideoChange = this.sendVideo;
|
|
|
|
|
|
|
|
this.publisher = this.OV.initPublisher(
|
2017-10-04 10:30:15 +02:00
|
|
|
'local-vid-' + this.session.connection.connectionId,
|
|
|
|
{
|
|
|
|
audio: this.sendAudio,
|
|
|
|
video: this.sendVideo,
|
2018-01-18 16:09:39 +01:00
|
|
|
audioActive: this.activeAudio,
|
|
|
|
videoActive: this.activeVideo,
|
2017-10-04 10:30:15 +02:00
|
|
|
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'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2017-09-28 19:13:29 +02:00
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
this.addPublisherEvents(this.publisher);
|
2018-01-11 11:13:50 +01:00
|
|
|
|
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 {
|
2018-03-02 11:36:12 +01:00
|
|
|
if (!!this.publisherRecorder) {
|
|
|
|
this.restartPublisherRecord();
|
|
|
|
}
|
|
|
|
Object.keys(this.subscribers).forEach((key) => {
|
|
|
|
if (!!this.subscribers[key].recorder) {
|
|
|
|
this.restartSubscriberRecord(key);
|
|
|
|
}
|
|
|
|
});
|
2017-09-28 19:13:29 +02:00
|
|
|
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 toggleVideo() {
|
|
|
|
this.publisher.publishVideo(this.videoMuted);
|
|
|
|
this.videoMuted = !this.videoMuted;
|
|
|
|
this.updateVideoIcon();
|
|
|
|
}
|
|
|
|
|
2018-01-11 11:13:50 +01:00
|
|
|
private updateAudioIcon() {
|
|
|
|
this.audioMuted ? this.audioIcon = 'mic_off' : this.audioIcon = 'mic';
|
|
|
|
}
|
|
|
|
|
2017-09-29 13:54:22 +02:00
|
|
|
private updateVideoIcon() {
|
|
|
|
this.videoMuted ? this.videoIcon = 'videocam_off' : this.videoIcon = 'videocam';
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
2018-01-11 11:13:50 +01:00
|
|
|
private updatePublishIcon() {
|
|
|
|
this.unpublished ? this.publishIcon = 'play_arrow' : this.publishIcon = 'stop';
|
|
|
|
}
|
|
|
|
|
2018-03-01 11:25:25 +01:00
|
|
|
private appendSubscriberData(videoElement: HTMLVideoElement, connection: 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';
|
2018-01-11 11:13:50 +01:00
|
|
|
dataNode.id = 'data-' + this.session.connection.connectionId + '-' + connection.connectionId;
|
|
|
|
dataNode.innerHTML = '<p class="name">' + connection.data + '</p>' +
|
2018-03-01 11:25:25 +01:00
|
|
|
'<button id="sub-btn-' + this.session.connection.connectionId + '-' + connection.connectionId +
|
|
|
|
'" class="sub-btn" title="Subscribe/Unsubscribe"><mat-icon id="icon-' + this.session.connection.connectionId +
|
|
|
|
'-' + connection.connectionId + '" aria-label="Subscribe or unsubscribe" class="mat-icon material-icons" role="img"' +
|
|
|
|
'aria-hidden="true">notifications</mat-icon></button>' +
|
|
|
|
'<button id="record-btn-' + this.session.connection.connectionId + '-' + connection.connectionId +
|
|
|
|
'" class="sub-btn rec-btn" title="Record"><mat-icon id="record-icon-' +
|
|
|
|
this.session.connection.connectionId + '-' + connection.connectionId +
|
|
|
|
'" aria-label="Start/Stop recording" class="mat-icon material-icons" role="img"' +
|
|
|
|
'aria-hidden="true">fiber_manual_record</mat-icon></button>' +
|
|
|
|
'<button style="display:none" id="pause-btn-' + this.session.connection.connectionId + '-' + connection.connectionId +
|
|
|
|
'" class="sub-btn rec-btn" title="Pause/Resume"><mat-icon id="pause-icon-' +
|
|
|
|
this.session.connection.connectionId + '-' + connection.connectionId +
|
|
|
|
'" aria-label="Pause/Resume recording" class="mat-icon material-icons" role="img"' +
|
|
|
|
'aria-hidden="true">pause</mat-icon></button>';
|
2017-09-29 13:54:22 +02:00
|
|
|
videoElement.parentNode.insertBefore(dataNode, videoElement.nextSibling);
|
2018-01-11 11:13:50 +01:00
|
|
|
document.getElementById('sub-btn-' + this.session.connection.connectionId + '-' + connection.connectionId).addEventListener('click',
|
|
|
|
this.subUnsubFromSubscriber.bind(this, connection.connectionId));
|
2018-03-01 11:25:25 +01:00
|
|
|
document.getElementById('record-btn-' + this.session.connection.connectionId + '-' + connection.connectionId).addEventListener('click',
|
|
|
|
this.recordSubscriber.bind(this, connection.connectionId));
|
|
|
|
document.getElementById('pause-btn-' + this.session.connection.connectionId + '-' + connection.connectionId).addEventListener('click',
|
|
|
|
this.pauseSubscriber.bind(this, connection.connectionId));
|
|
|
|
}
|
|
|
|
|
|
|
|
private appendPublisherData(videoElement: HTMLVideoElement): void {
|
|
|
|
const dataNode = document.createElement('div');
|
|
|
|
dataNode.className = 'data-node';
|
|
|
|
dataNode.id = 'data-' + this.session.connection.connectionId + '-' + this.session.connection.connectionId;
|
|
|
|
dataNode.innerHTML =
|
|
|
|
'<button id="local-record-btn-' + this.session.connection.connectionId +
|
|
|
|
'" class="sub-btn rec-btn publisher-rec-btn" title="Record"><mat-icon id="local-record-icon-' + this.session.connection.connectionId +
|
|
|
|
'" aria-label="Start/Stop local recording" class="mat-icon material-icons" role="img" aria-hidden="true">' +
|
|
|
|
'fiber_manual_record</mat-icon></button>' +
|
|
|
|
'<button style="display:none" id="local-pause-btn-' + this.session.connection.connectionId +
|
|
|
|
'" class="sub-btn rec-btn publisher-rec-btn" title="Pause/Resume">' +
|
|
|
|
'<mat-icon id="local-pause-icon-' + this.session.connection.connectionId +
|
|
|
|
'" aria-label="Pause/Resume local recording" class="mat-icon material-icons" role="img" aria-hidden="true">' +
|
|
|
|
'pause</mat-icon></button>';
|
|
|
|
videoElement.parentNode.insertBefore(dataNode, videoElement.nextSibling);
|
|
|
|
document.getElementById('local-record-btn-' + this.session.connection.connectionId).addEventListener('click',
|
|
|
|
this.recordPublisher.bind(this));
|
|
|
|
document.getElementById('local-pause-btn-' + this.session.connection.connectionId).addEventListener('click',
|
|
|
|
this.pausePublisher.bind(this));
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|
|
|
|
|
2018-01-11 11:13:50 +01:00
|
|
|
private removeUserData(connectionId: string): void {
|
|
|
|
$('#remote-vid-' + this.session.connection.connectionId)
|
|
|
|
.find('#data-' + this.session.connection.connectionId + '-' + connectionId).remove();
|
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;
|
|
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2017-12-11 17:09:57 +01:00
|
|
|
sendMessage(): void {
|
|
|
|
this.session.signal({
|
|
|
|
data: 'Test message',
|
|
|
|
to: [],
|
|
|
|
type: 'chat'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-03-01 11:25:25 +01:00
|
|
|
recordPublisher(): void {
|
|
|
|
if (!this.publisherRecording) {
|
|
|
|
this.publisherRecorder = this.OV.initLocalRecorder(this.publisher.stream);
|
|
|
|
this.publisherRecorder.record();
|
|
|
|
this.publisherRecording = true;
|
|
|
|
document.getElementById('local-record-icon-' + this.session.connection.connectionId).innerHTML = 'stop';
|
|
|
|
document.getElementById('local-pause-btn-' + this.session.connection.connectionId).style.display = 'block';
|
|
|
|
} else {
|
|
|
|
this.publisherRecorder.stop()
|
|
|
|
.then(() => {
|
|
|
|
let dialogRef: MatDialogRef<LocalRecordingDialogComponent>;
|
|
|
|
dialogRef = this.recordDialog.open(LocalRecordingDialogComponent, {
|
|
|
|
disableClose: true,
|
|
|
|
data: {
|
|
|
|
recorder: this.publisherRecorder
|
|
|
|
}
|
|
|
|
});
|
|
|
|
dialogRef.componentInstance.myReference = dialogRef;
|
|
|
|
|
|
|
|
dialogRef.afterOpen().subscribe(() => {
|
|
|
|
this.afterOpenPreview(this.publisherRecorder);
|
|
|
|
});
|
|
|
|
dialogRef.afterClosed().subscribe(() => {
|
2018-03-02 11:36:12 +01:00
|
|
|
this.afterClosePreview();
|
2018-03-01 11:25:25 +01:00
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
console.error('Error stopping LocalRecorder: ' + error);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pausePublisher(): void {
|
|
|
|
if (!this.publisherPaused) {
|
|
|
|
this.publisherRecorder.pause();
|
|
|
|
document.getElementById('local-pause-icon-' + this.session.connection.connectionId).innerHTML = 'play_arrow';
|
|
|
|
} else {
|
|
|
|
this.publisherRecorder.resume();
|
|
|
|
document.getElementById('local-pause-icon-' + this.session.connection.connectionId).innerHTML = 'pause';
|
|
|
|
}
|
|
|
|
this.publisherPaused = !this.publisherPaused;
|
|
|
|
}
|
|
|
|
|
|
|
|
recordSubscriber(connectionId: string): void {
|
|
|
|
const subscriber: Subscriber = this.subscribers[connectionId].subscriber;
|
|
|
|
const recording = this.subscribers[connectionId].recording;
|
|
|
|
if (!recording) {
|
|
|
|
this.subscribers[connectionId].recorder = this.OV.initLocalRecorder(subscriber.stream);
|
|
|
|
this.subscribers[connectionId].recorder.record();
|
|
|
|
this.subscribers[connectionId].recording = true;
|
|
|
|
document.getElementById('record-icon-' + this.session.connection.connectionId + '-' + connectionId).innerHTML = 'stop';
|
|
|
|
document.getElementById('pause-btn-' + this.session.connection.connectionId + '-' + connectionId).style.display = 'block';
|
|
|
|
} else {
|
|
|
|
this.subscribers[connectionId].recorder.stop()
|
|
|
|
.then(() => {
|
|
|
|
let dialogRef: MatDialogRef<LocalRecordingDialogComponent>;
|
|
|
|
dialogRef = this.recordDialog.open(LocalRecordingDialogComponent, {
|
|
|
|
disableClose: true,
|
|
|
|
data: {
|
|
|
|
recorder: this.subscribers[connectionId].recorder
|
|
|
|
}
|
|
|
|
});
|
|
|
|
dialogRef.componentInstance.myReference = dialogRef;
|
|
|
|
|
|
|
|
dialogRef.afterOpen().subscribe(() => {
|
|
|
|
this.afterOpenPreview(this.subscribers[connectionId].recorder);
|
|
|
|
});
|
|
|
|
dialogRef.afterClosed().subscribe(() => {
|
2018-03-02 11:36:12 +01:00
|
|
|
this.afterClosePreview(connectionId);
|
2018-03-01 11:25:25 +01:00
|
|
|
});
|
|
|
|
})
|
|
|
|
.catch((error) => {
|
|
|
|
console.error('Error stopping LocalRecorder: ' + error);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pauseSubscriber(connectionId: string): void {
|
|
|
|
const subscriber: Subscriber = this.subscribers[connectionId].subscriber;
|
|
|
|
const subscriberPaused = this.subscribers[connectionId].paused;
|
|
|
|
if (!subscriberPaused) {
|
|
|
|
this.subscribers[connectionId].recorder.pause();
|
|
|
|
document.getElementById('pause-icon-' + this.session.connection.connectionId + '-' + connectionId).innerHTML = 'play_arrow';
|
|
|
|
} else {
|
|
|
|
this.subscribers[connectionId].recorder.resume();
|
|
|
|
document.getElementById('pause-icon-' + this.session.connection.connectionId + '-' + connectionId).innerHTML = 'pause';
|
|
|
|
}
|
|
|
|
this.subscribers[connectionId].paused = !this.subscribers[connectionId].paused;
|
|
|
|
}
|
|
|
|
|
2018-01-11 11:13:50 +01:00
|
|
|
publishUnpublish(): void {
|
|
|
|
if (this.unpublished) {
|
|
|
|
this.session.publish(this.publisher);
|
|
|
|
} else {
|
|
|
|
this.session.unpublish(this.publisher);
|
2018-03-01 11:25:25 +01:00
|
|
|
this.removeUserData(this.session.connection.connectionId);
|
|
|
|
this.restartPublisherRecord();
|
2018-01-11 11:13:50 +01:00
|
|
|
}
|
|
|
|
this.unpublished = !this.unpublished;
|
|
|
|
this.updatePublishIcon();
|
|
|
|
}
|
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
changePublisher() {
|
|
|
|
|
|
|
|
if (!this.unpublished) {
|
|
|
|
this.session.unpublish(this.publisher);
|
2018-03-01 11:25:25 +01:00
|
|
|
this.removeUserData(this.session.connection.connectionId);
|
2018-03-02 11:36:12 +01:00
|
|
|
this.restartPublisherRecord();
|
2018-01-18 16:09:39 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let screenChange;
|
|
|
|
if (!this.publisherChanged) {
|
|
|
|
if (this.sendAudio && !this.sendVideo) {
|
|
|
|
this.sendAudioChange = false;
|
|
|
|
this.sendVideoChange = true;
|
|
|
|
screenChange = false;
|
|
|
|
} else if (!this.sendAudio && this.sendVideo) {
|
|
|
|
this.sendAudioChange = true;
|
|
|
|
this.sendVideoChange = false;
|
|
|
|
} else if (this.sendAudio && this.sendVideo && this.optionsVideo === 'video') {
|
|
|
|
this.sendAudioChange = false;
|
|
|
|
this.sendVideoChange = true;
|
|
|
|
screenChange = true;
|
|
|
|
} else if (this.sendAudio && this.sendVideo && this.optionsVideo === 'screen') {
|
|
|
|
this.sendAudioChange = false;
|
|
|
|
this.sendVideoChange = true;
|
|
|
|
screenChange = false;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.sendAudioChange = this.sendAudio;
|
|
|
|
this.sendVideoChange = this.sendVideo;
|
|
|
|
screenChange = this.optionsVideo === 'screen' ? true : false;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.audioMuted = false;
|
|
|
|
this.videoMuted = false;
|
|
|
|
this.unpublished = false;
|
|
|
|
this.updateAudioIcon();
|
|
|
|
this.updateVideoIcon();
|
|
|
|
this.updatePublishIcon();
|
|
|
|
|
|
|
|
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
|
|
|
|
},
|
|
|
|
(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'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2018-02-27 14:47:03 +01:00
|
|
|
this.addPublisherEvents(this.publisher);
|
|
|
|
this.session.publish(this.publisher);
|
2018-01-18 16:09:39 +01:00
|
|
|
|
2018-02-27 14:47:03 +01:00
|
|
|
this.publisherChanged = !this.publisherChanged;
|
2018-01-18 16:09:39 +01:00
|
|
|
}
|
|
|
|
|
2018-01-11 11:13:50 +01:00
|
|
|
subUnsubFromSubscriber(connectionId: string) {
|
|
|
|
let subscriber: Subscriber = this.subscribers[connectionId].subscriber;
|
|
|
|
if (this.subscribers[connectionId].subbed) {
|
|
|
|
this.session.unsubscribe(subscriber);
|
2018-03-01 11:25:25 +01:00
|
|
|
this.restartSubscriberRecord(connectionId);
|
2018-01-11 11:13:50 +01:00
|
|
|
document.getElementById('data-' + this.session.connection.connectionId + '-' + connectionId).style.marginLeft = '0';
|
|
|
|
document.getElementById('icon-' + this.session.connection.connectionId + '-' + connectionId).innerHTML = 'notifications_off';
|
2018-03-01 11:25:25 +01:00
|
|
|
document.getElementById('record-btn-' + this.session.connection.connectionId + '-' + connectionId).remove();
|
|
|
|
document.getElementById('pause-btn-' + this.session.connection.connectionId + '-' + connectionId).remove();
|
2018-01-11 11:13:50 +01:00
|
|
|
} else {
|
|
|
|
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()) {
|
|
|
|
$(e.element).css({ 'background-color': '#4d4d4d' });
|
|
|
|
$(e.element).attr('poster', 'assets/images/volume.png');
|
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
this.subscribers[connectionId].videoElement = e.element;
|
2018-01-11 11:13:50 +01:00
|
|
|
this.updateEventList('videoElementCreated', e.element.id);
|
|
|
|
});
|
|
|
|
subscriber.on('videoPlaying', (e) => {
|
2018-03-01 11:25:25 +01:00
|
|
|
this.removeUserData(connectionId);
|
|
|
|
this.appendSubscriberData(e.element, subscriber.stream.connection);
|
2018-01-11 11:13:50 +01:00
|
|
|
this.updateEventList('videoPlaying', e.element.id);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
this.subscribers[connectionId].subbed = !this.subscribers[connectionId].subbed;
|
|
|
|
}
|
|
|
|
|
2018-01-18 16:09:39 +01:00
|
|
|
addSessionEvents(session: Session) {
|
|
|
|
session.on('streamCreated', (event) => {
|
|
|
|
|
|
|
|
this.changeDetector.detectChanges();
|
|
|
|
|
|
|
|
if (this.subscribeTo) {
|
|
|
|
const subscriber: Subscriber = session.subscribe(event.stream, 'remote-vid-' + session.connection.connectionId);
|
2018-03-01 11:25:25 +01:00
|
|
|
this.subscribers[subscriber.stream.connection.connectionId] = {
|
|
|
|
'subscriber': subscriber,
|
|
|
|
'subbed': true,
|
|
|
|
'recorder': undefined,
|
|
|
|
'recording': false,
|
|
|
|
'paused': false,
|
|
|
|
'videoElement': undefined
|
|
|
|
};
|
2018-01-18 16:09:39 +01:00
|
|
|
subscriber.on('videoElementCreated', (e) => {
|
|
|
|
if (!event.stream.getRecvVideo()) {
|
|
|
|
$(e.element).css({ 'background-color': '#4d4d4d' });
|
|
|
|
$(e.element).attr('poster', 'assets/images/volume.png');
|
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
this.subscribers[subscriber.stream.connection.connectionId].videoElement = e.element;
|
2018-01-18 16:09:39 +01:00
|
|
|
this.updateEventList('videoElementCreated', e.element.id);
|
|
|
|
});
|
|
|
|
subscriber.on('videoPlaying', (e) => {
|
2018-03-01 11:25:25 +01:00
|
|
|
this.appendSubscriberData(e.element, subscriber.stream.connection);
|
2018-01-18 16:09:39 +01:00
|
|
|
this.updateEventList('videoPlaying', e.element.id);
|
|
|
|
});
|
2018-02-27 14:47:03 +01:00
|
|
|
subscriber.on('videoElementDestroyed', (e) => {
|
|
|
|
this.updateEventList('videoElementDestroyed', '(Subscriber)');
|
|
|
|
});
|
2018-01-18 16:09:39 +01:00
|
|
|
}
|
|
|
|
this.updateEventList('streamCreated', event.stream.connection.connectionId);
|
|
|
|
});
|
|
|
|
|
|
|
|
session.on('streamDestroyed', (event) => {
|
|
|
|
this.removeUserData(event.stream.connection.connectionId);
|
|
|
|
this.updateEventList('streamDestroyed', event.stream.connection.connectionId);
|
|
|
|
});
|
|
|
|
session.on('connectionCreated', (event) => {
|
|
|
|
this.updateEventList('connectionCreated', event.connection.connectionId);
|
|
|
|
});
|
|
|
|
session.on('connectionDestroyed', (event) => {
|
|
|
|
this.updateEventList('connectionDestroyed', event.connection.connectionId);
|
|
|
|
});
|
|
|
|
session.on('sessionDisconnected', (event) => {
|
|
|
|
this.updateEventList('sessionDisconnected', 'No data');
|
|
|
|
});
|
|
|
|
session.on('signal', (event) => {
|
|
|
|
this.updateEventList('signal', event.from.connectionId + '-' + event.data);
|
|
|
|
});
|
|
|
|
|
|
|
|
/*session.on('publisherStartSpeaking', (event) => {
|
|
|
|
console.log('Publisher start speaking');
|
|
|
|
console.log(event);
|
|
|
|
});
|
|
|
|
|
|
|
|
session.on('publisherStopSpeaking', (event) => {
|
|
|
|
console.log('Publisher stop speaking');
|
|
|
|
console.log(event);
|
|
|
|
});*/
|
|
|
|
}
|
|
|
|
|
|
|
|
addPublisherEvents(publisher: Publisher) {
|
|
|
|
publisher.on('videoElementCreated', (event) => {
|
|
|
|
if (this.publishTo &&
|
|
|
|
(!this.sendVideoChange ||
|
|
|
|
this.sendVideoChange &&
|
|
|
|
!(this.optionsVideo !== 'screen') &&
|
|
|
|
this.openviduError &&
|
|
|
|
this.openviduError.name === 'NO_VIDEO_DEVICE')) {
|
|
|
|
$(event.element).css({ 'background-color': '#4d4d4d' });
|
|
|
|
$(event.element).attr('poster', 'assets/images/volume.png');
|
|
|
|
}
|
|
|
|
this.updateEventList('videoElementCreated', event.element.id);
|
|
|
|
});
|
|
|
|
|
|
|
|
publisher.on('accessAllowed', (e) => {
|
|
|
|
this.updateEventList('accessAllowed', '');
|
|
|
|
});
|
|
|
|
|
|
|
|
publisher.on('accessDenied', (e) => {
|
|
|
|
this.updateEventList('accessDenied', '');
|
|
|
|
});
|
|
|
|
|
|
|
|
publisher.on('videoPlaying', (e) => {
|
2018-03-01 11:25:25 +01:00
|
|
|
this.appendPublisherData(e.element);
|
2018-01-18 16:09:39 +01:00
|
|
|
this.updateEventList('videoPlaying', e.element.id);
|
|
|
|
});
|
|
|
|
|
|
|
|
publisher.on('remoteVideoPlaying', (e) => {
|
2018-03-01 11:25:25 +01:00
|
|
|
this.appendPublisherData(e.element);
|
2018-01-18 16:09:39 +01:00
|
|
|
this.updateEventList('remoteVideoPlaying', e.element.id);
|
|
|
|
});
|
|
|
|
|
|
|
|
publisher.on('streamCreated', (e) => {
|
|
|
|
this.updateEventList('streamCreated', e.stream.connection.connectionId);
|
|
|
|
});
|
|
|
|
|
|
|
|
publisher.on('streamDestroyed', (e) => {
|
|
|
|
this.updateEventList('streamDestroyed', e.stream.connection.connectionId);
|
|
|
|
});
|
2018-02-27 14:47:03 +01:00
|
|
|
|
|
|
|
publisher.on('videoElementDestroyed', (e) => {
|
|
|
|
this.updateEventList('videoElementDestroyed', '(Publisher)');
|
|
|
|
});
|
2018-01-18 16:09:39 +01:00
|
|
|
}
|
|
|
|
|
2018-03-01 11:25:25 +01:00
|
|
|
private afterOpenPreview(recorder: LocalRecorder): void {
|
|
|
|
this.muteSubscribersService.updateMuted(true);
|
2018-03-02 11:36:12 +01:00
|
|
|
recorder.preview('recorder-preview').controls = true;
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
|
2018-03-02 11:36:12 +01:00
|
|
|
private afterClosePreview(connectionId?: string): void {
|
2018-03-01 11:25:25 +01:00
|
|
|
this.muteSubscribersService.updateMuted(false);
|
2018-03-02 11:36:12 +01:00
|
|
|
if (!!connectionId) {
|
|
|
|
this.restartSubscriberRecord(connectionId);
|
|
|
|
} else {
|
|
|
|
this.restartPublisherRecord();
|
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private restartPublisherRecord(): void {
|
2018-03-02 11:36:12 +01:00
|
|
|
if (!!this.session) {
|
|
|
|
let el: HTMLElement = document.getElementById('local-record-icon-' + this.session.connection.connectionId);
|
|
|
|
if (!!el) {
|
|
|
|
el.innerHTML = 'fiber_manual_record';
|
|
|
|
}
|
|
|
|
el = document.getElementById('local-pause-icon-' + this.session.connection.connectionId);
|
|
|
|
if (!!el) {
|
|
|
|
el.innerHTML = 'pause';
|
|
|
|
}
|
|
|
|
el = document.getElementById('local-pause-btn-' + this.session.connection.connectionId);
|
|
|
|
if (!!el) {
|
|
|
|
el.style.display = 'none';
|
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
this.publisherPaused = false;
|
|
|
|
this.publisherRecording = false;
|
2018-03-02 11:36:12 +01:00
|
|
|
if (!!this.publisherRecorder) {
|
|
|
|
this.publisherRecorder.clean();
|
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private restartSubscriberRecord(connectionId: string): void {
|
2018-03-02 11:36:12 +01:00
|
|
|
if (!!this.session) {
|
|
|
|
let el: HTMLElement = document.getElementById('record-icon-' + this.session.connection.connectionId + '-' + connectionId);
|
|
|
|
if (!!el) {
|
|
|
|
el.innerHTML = 'fiber_manual_record';
|
|
|
|
}
|
|
|
|
el = document.getElementById('pause-icon-' + this.session.connection.connectionId + '-' + connectionId);
|
|
|
|
if (!!el) {
|
|
|
|
el.innerHTML = 'pause';
|
|
|
|
}
|
|
|
|
el = document.getElementById('pause-btn-' + this.session.connection.connectionId + '-' + connectionId);
|
|
|
|
if (!!el) {
|
|
|
|
el.style.display = 'none';
|
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
this.subscribers[connectionId].recording = false;
|
|
|
|
this.subscribers[connectionId].paused = false;
|
2018-03-02 11:36:12 +01:00
|
|
|
|
|
|
|
if (!!this.subscribers[connectionId].recorder) {
|
|
|
|
this.subscribers[connectionId].recorder.clean();
|
|
|
|
}
|
2018-03-01 11:25:25 +01:00
|
|
|
}
|
|
|
|
|
2017-09-28 19:13:29 +02:00
|
|
|
}
|