2022-03-10 14:12:43 +01:00
|
|
|
import {
|
|
|
|
AfterViewInit,
|
|
|
|
Component,
|
|
|
|
ContentChild,
|
|
|
|
EventEmitter,
|
|
|
|
Input,
|
|
|
|
OnDestroy,
|
|
|
|
OnInit,
|
|
|
|
Output,
|
|
|
|
TemplateRef,
|
|
|
|
ViewChild
|
|
|
|
} from '@angular/core';
|
|
|
|
import { OpenViduErrorName } from 'openvidu-browser';
|
|
|
|
import { Subscription } from 'rxjs';
|
2022-02-17 17:26:30 +01:00
|
|
|
import {
|
|
|
|
ChatPanelDirective,
|
|
|
|
LayoutDirective,
|
|
|
|
PanelDirective,
|
|
|
|
ParticipantPanelItemDirective,
|
2022-03-10 12:33:49 +01:00
|
|
|
ParticipantPanelItemElementsDirective,
|
2022-02-17 17:26:30 +01:00
|
|
|
ParticipantsPanelDirective,
|
|
|
|
StreamDirective,
|
2022-03-10 11:42:48 +01:00
|
|
|
ToolbarAdditionalButtonsDirective,
|
2022-02-17 17:26:30 +01:00
|
|
|
ToolbarDirective
|
2022-03-07 15:50:27 +01:00
|
|
|
} from '../../directives/template/openvidu-angular.directive';
|
2022-02-17 17:26:30 +01:00
|
|
|
import { ILogger } from '../../models/logger.model';
|
2022-03-10 14:12:43 +01:00
|
|
|
import { ParticipantProperties } from '../../models/participant.model';
|
|
|
|
import { ActionService } from '../../services/action/action.service';
|
|
|
|
import { OpenViduAngularConfigService } from '../../services/config/openvidu-angular.config.service';
|
|
|
|
import { DeviceService } from '../../services/device/device.service';
|
2022-02-17 17:26:30 +01:00
|
|
|
import { LoggerService } from '../../services/logger/logger.service';
|
2022-03-10 14:12:43 +01:00
|
|
|
import { OpenViduService } from '../../services/openvidu/openvidu.service';
|
|
|
|
import { ParticipantService } from '../../services/participant/participant.service';
|
|
|
|
import { StorageService } from '../../services/storage/storage.service';
|
2022-03-10 16:17:27 +01:00
|
|
|
import { TokenService } from '../../services/token/token.service';
|
2022-01-20 11:53:56 +01:00
|
|
|
|
|
|
|
@Component({
|
|
|
|
selector: 'ov-videoconference',
|
|
|
|
templateUrl: './videoconference.component.html',
|
|
|
|
styleUrls: ['./videoconference.component.css']
|
|
|
|
})
|
2022-03-10 14:12:43 +01:00
|
|
|
export class VideoconferenceComponent implements OnInit, OnDestroy, AfterViewInit {
|
2022-03-07 15:50:27 +01:00
|
|
|
// *** Toolbar ***
|
2022-02-17 17:26:30 +01:00
|
|
|
@ContentChild(ToolbarDirective) externalToolbar: ToolbarDirective;
|
2022-03-10 11:42:48 +01:00
|
|
|
@ContentChild(ToolbarAdditionalButtonsDirective) externalToolbarAdditionalButtons: ToolbarAdditionalButtonsDirective;
|
2022-03-07 15:50:27 +01:00
|
|
|
|
|
|
|
// *** Panels ***
|
2022-02-17 17:26:30 +01:00
|
|
|
@ContentChild(PanelDirective) externalPanel: PanelDirective;
|
|
|
|
@ContentChild(ChatPanelDirective) externalChatPanel: ChatPanelDirective;
|
|
|
|
@ContentChild(ParticipantsPanelDirective) externalParticipantsPanel: ParticipantsPanelDirective;
|
|
|
|
@ContentChild(ParticipantPanelItemDirective) externalParticipantPanelItem: ParticipantPanelItemDirective;
|
2022-03-10 12:33:49 +01:00
|
|
|
@ContentChild(ParticipantPanelItemElementsDirective) externalParticipantPanelItemElements: ParticipantPanelItemElementsDirective;
|
|
|
|
|
2022-03-07 15:50:27 +01:00
|
|
|
// *** Layout ***
|
2022-02-17 17:26:30 +01:00
|
|
|
@ContentChild(LayoutDirective) externalLayout: LayoutDirective;
|
|
|
|
@ContentChild(StreamDirective) externalStream: StreamDirective;
|
2022-02-03 17:08:23 +01:00
|
|
|
|
2022-02-17 17:26:30 +01:00
|
|
|
@ViewChild('defaultToolbar', { static: false, read: TemplateRef }) defaultToolbarTemplate: TemplateRef<any>;
|
|
|
|
@ViewChild('defaultPanel', { static: false, read: TemplateRef }) defaultPanelTemplate: TemplateRef<any>;
|
|
|
|
@ViewChild('defaultChatPanel', { static: false, read: TemplateRef }) defaultChatPanelTemplate: TemplateRef<any>;
|
|
|
|
@ViewChild('defaultParticipantsPanel', { static: false, read: TemplateRef }) defaultParticipantsPanelTemplate: TemplateRef<any>;
|
|
|
|
@ViewChild('defaultParticipantPanelItem', { static: false, read: TemplateRef }) defaultParticipantPanelItemTemplate: TemplateRef<any>;
|
|
|
|
@ViewChild('defaultLayout', { static: false, read: TemplateRef }) defaultLayoutTemplate: TemplateRef<any>;
|
|
|
|
@ViewChild('defaultStream', { static: false, read: TemplateRef }) defaultStreamTemplate: TemplateRef<any>;
|
|
|
|
|
|
|
|
openviduAngularToolbarTemplate: TemplateRef<any>;
|
2022-03-10 11:42:48 +01:00
|
|
|
openviduAngularToolbarAdditionalButtonsTemplate: TemplateRef<any>;
|
2022-02-17 17:26:30 +01:00
|
|
|
openviduAngularPanelTemplate: TemplateRef<any>;
|
|
|
|
openviduAngularChatPanelTemplate: TemplateRef<any>;
|
|
|
|
openviduAngularParticipantsPanelTemplate: TemplateRef<any>;
|
|
|
|
openviduAngularParticipantPanelItemTemplate: TemplateRef<any>;
|
2022-03-10 12:33:49 +01:00
|
|
|
openviduAngularParticipantPanelItemElementsTemplate: TemplateRef<any>;
|
2022-02-17 17:26:30 +01:00
|
|
|
openviduAngularLayoutTemplate: TemplateRef<any>;
|
|
|
|
openviduAngularStreamTemplate: TemplateRef<any>;
|
2022-01-20 11:53:56 +01:00
|
|
|
|
2022-03-07 15:50:27 +01:00
|
|
|
// *** Parameters ***
|
2022-02-11 13:18:50 +01:00
|
|
|
@Input() sessionName: string;
|
2022-03-07 15:50:27 +01:00
|
|
|
@Input() participantName: string;
|
2022-01-20 11:53:56 +01:00
|
|
|
|
2022-02-04 10:54:17 +01:00
|
|
|
@Input()
|
|
|
|
set tokens(tokens: { webcam: string; screen: string }) {
|
|
|
|
if (!tokens || (!tokens.webcam && !tokens.screen)) {
|
|
|
|
//No tokens received
|
|
|
|
// throw new Error('No tokens received');
|
2022-02-17 17:26:30 +01:00
|
|
|
this.log.w('No tokens received');
|
2022-02-04 10:54:17 +01:00
|
|
|
} else {
|
|
|
|
if (tokens.webcam || tokens.screen) {
|
2022-03-10 16:17:27 +01:00
|
|
|
this.tokenService.setWebcamToken(tokens.webcam);
|
|
|
|
this.tokenService.setScreenToken(tokens.screen);
|
|
|
|
this.canPublish = true;
|
2022-02-04 10:54:17 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-01-20 11:53:56 +01:00
|
|
|
|
2022-03-07 15:50:27 +01:00
|
|
|
// *** Events ***
|
|
|
|
|
|
|
|
// Event sent when user click on the join button in pre-join page
|
2022-03-09 15:31:21 +01:00
|
|
|
@Output() onJoinButtonClicked = new EventEmitter<any>();
|
|
|
|
// Event sent when user click on the join button in pre-join page
|
|
|
|
@Output() onToolbarLeaveButtonClicked = new EventEmitter<any>();
|
|
|
|
@Output() onToolbarCameraButtonClicked = new EventEmitter<any>();
|
|
|
|
@Output() onToolbarMicrophoneButtonClicked = new EventEmitter<any>();
|
|
|
|
@Output() onToolbarScreenshareButtonClicked = new EventEmitter<any>();
|
|
|
|
@Output() onToolbarFullscreenButtonClicked = new EventEmitter<any>();
|
|
|
|
@Output() onToolbarParticipantsPanelButtonClicked = new EventEmitter<any>();
|
|
|
|
@Output() onToolbarChatPanelButtonClicked = new EventEmitter<any>();
|
2022-03-07 15:50:27 +01:00
|
|
|
|
|
|
|
// Event sent when participant has joined the session
|
|
|
|
@Output() onParticipantJoined = new EventEmitter<any>();
|
|
|
|
|
|
|
|
// Event sent when participant has left the session
|
2022-03-09 15:31:21 +01:00
|
|
|
// @Output() onParticipantLeft = new EventEmitter<any>();
|
2022-03-07 15:50:27 +01:00
|
|
|
|
|
|
|
// Event sent when session has been created
|
|
|
|
@Output() onSessionCreated = new EventEmitter<any>();
|
|
|
|
|
2022-02-11 13:18:50 +01:00
|
|
|
joinSessionClicked: boolean = false;
|
2022-03-10 14:12:43 +01:00
|
|
|
participantReady: boolean = false;
|
2022-03-10 16:17:27 +01:00
|
|
|
canPublish: boolean = false;
|
2022-02-11 13:18:50 +01:00
|
|
|
error: boolean = false;
|
|
|
|
errorMessage: string = '';
|
2022-03-10 14:12:43 +01:00
|
|
|
showPrejoin: boolean = true;
|
|
|
|
private prejoinSub: Subscription;
|
2022-02-17 17:26:30 +01:00
|
|
|
private log: ILogger;
|
|
|
|
|
2022-03-10 14:12:43 +01:00
|
|
|
constructor(
|
|
|
|
private loggerSrv: LoggerService,
|
|
|
|
private storageSrv: StorageService,
|
|
|
|
private participantService: ParticipantService,
|
|
|
|
private deviceSrv: DeviceService,
|
|
|
|
private openviduService: OpenViduService,
|
|
|
|
private actionService: ActionService,
|
2022-03-10 16:17:27 +01:00
|
|
|
private libService: OpenViduAngularConfigService,
|
|
|
|
private tokenService: TokenService,
|
2022-03-10 14:12:43 +01:00
|
|
|
) {
|
2022-02-17 17:26:30 +01:00
|
|
|
this.log = this.loggerSrv.get('VideoconferenceComponent');
|
|
|
|
}
|
|
|
|
|
2022-03-10 14:12:43 +01:00
|
|
|
async ngOnInit() {
|
|
|
|
this.subscribeToVideconferenceDirectives();
|
|
|
|
await this.deviceSrv.initializeDevices();
|
|
|
|
const nickname = this.storageSrv.getNickname() || 'OpenVidu_User' + Math.floor(Math.random() * 100);
|
|
|
|
const props: ParticipantProperties = {
|
|
|
|
local: true,
|
|
|
|
nickname
|
|
|
|
};
|
|
|
|
this.participantService.initLocalParticipant(props);
|
|
|
|
this.openviduService.initialize();
|
|
|
|
|
|
|
|
if (this.deviceSrv.hasVideoDeviceAvailable() || this.deviceSrv.hasAudioDeviceAvailable()) {
|
|
|
|
await this.initwebcamPublisher();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private async initwebcamPublisher() {
|
|
|
|
try {
|
|
|
|
const publisher = await this.openviduService.initDefaultPublisher(undefined);
|
|
|
|
if (publisher) {
|
|
|
|
publisher.once('accessDenied', (e: any) => {
|
|
|
|
this.handlePublisherError(e);
|
|
|
|
});
|
|
|
|
publisher.once('accessAllowed', () => {
|
|
|
|
this.participantReady = true;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
this.actionService.openDialog(error.name.replace(/_/g, ' '), error.message, true);
|
|
|
|
this.log.e(error);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ngOnDestroy(): void {
|
|
|
|
if (this.prejoinSub) this.prejoinSub.unsubscribe();
|
|
|
|
}
|
|
|
|
|
2022-02-17 17:26:30 +01:00
|
|
|
ngAfterViewInit() {
|
|
|
|
if (this.externalToolbar) {
|
|
|
|
this.openviduAngularToolbarTemplate = this.externalToolbar.template;
|
|
|
|
this.log.d('Setting EXTERNAL TOOLBAR');
|
|
|
|
} else {
|
2022-03-10 11:42:48 +01:00
|
|
|
if (this.externalToolbarAdditionalButtons) {
|
2022-03-10 12:33:49 +01:00
|
|
|
this.log.d('Setting EXTERNAL TOOLBAR ADDITIONAL BUTTONS');
|
2022-03-10 11:42:48 +01:00
|
|
|
this.openviduAngularToolbarAdditionalButtonsTemplate = this.externalToolbarAdditionalButtons.template;
|
|
|
|
}
|
2022-02-17 17:26:30 +01:00
|
|
|
this.openviduAngularToolbarTemplate = this.defaultToolbarTemplate;
|
|
|
|
this.log.d('Setting DEFAULT TOOLBAR');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.externalPanel) {
|
|
|
|
this.openviduAngularPanelTemplate = this.externalPanel.template;
|
|
|
|
this.log.d('Setting EXTERNAL PANEL');
|
|
|
|
} else {
|
|
|
|
this.log.d('Setting DEFAULT PANEL');
|
|
|
|
|
|
|
|
if (this.externalParticipantsPanel) {
|
|
|
|
this.openviduAngularParticipantsPanelTemplate = this.externalParticipantsPanel.template;
|
|
|
|
this.log.d('Setting EXTERNAL PARTICIPANTS PANEL');
|
|
|
|
} else {
|
|
|
|
this.log.d('Setting DEFAULT PARTICIPANTS PANEL');
|
|
|
|
if (this.externalParticipantPanelItem) {
|
|
|
|
this.openviduAngularParticipantPanelItemTemplate = this.externalParticipantPanelItem.template;
|
|
|
|
this.log.d('Setting EXTERNAL P ITEM');
|
|
|
|
} else {
|
2022-03-10 12:33:49 +01:00
|
|
|
if (this.externalParticipantPanelItemElements) {
|
|
|
|
this.log.d('Setting EXTERNAL PARTICIPANT PANEL ITEM ELEMENT');
|
|
|
|
this.openviduAngularParticipantPanelItemElementsTemplate = this.externalParticipantPanelItemElements.template;
|
|
|
|
}
|
2022-02-17 17:26:30 +01:00
|
|
|
this.openviduAngularParticipantPanelItemTemplate = this.defaultParticipantPanelItemTemplate;
|
|
|
|
this.log.d('Setting DEFAULT P ITEM');
|
|
|
|
}
|
|
|
|
this.openviduAngularParticipantsPanelTemplate = this.defaultParticipantsPanelTemplate;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.externalChatPanel) {
|
|
|
|
this.openviduAngularChatPanelTemplate = this.externalChatPanel.template;
|
|
|
|
this.log.d('Setting EXTERNAL CHAT PANEL');
|
|
|
|
} else {
|
|
|
|
this.openviduAngularChatPanelTemplate = this.defaultChatPanelTemplate;
|
|
|
|
this.log.d('Setting DEFAULT CHAT PANEL');
|
|
|
|
}
|
|
|
|
this.openviduAngularPanelTemplate = this.defaultPanelTemplate;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.externalLayout) {
|
|
|
|
this.openviduAngularLayoutTemplate = this.externalLayout.template;
|
|
|
|
this.log.d('Setting EXTERNAL LAYOUT');
|
|
|
|
} else {
|
|
|
|
this.log.d('Setting DEAFULT LAYOUT');
|
|
|
|
|
|
|
|
if (this.externalStream) {
|
|
|
|
this.openviduAngularStreamTemplate = this.externalStream.template;
|
|
|
|
this.log.d('Setting EXTERNAL STREAM');
|
|
|
|
} else {
|
|
|
|
this.openviduAngularStreamTemplate = this.defaultStreamTemplate;
|
|
|
|
this.log.d('Setting DEFAULT STREAM');
|
|
|
|
}
|
|
|
|
this.openviduAngularLayoutTemplate = this.defaultLayoutTemplate;
|
|
|
|
}
|
|
|
|
}
|
2022-02-11 13:18:50 +01:00
|
|
|
|
2022-03-09 15:31:21 +01:00
|
|
|
_onJoinButtonClicked() {
|
2022-03-02 11:00:58 +01:00
|
|
|
this.joinSessionClicked = true;
|
2022-03-09 15:31:21 +01:00
|
|
|
this.onJoinButtonClicked.emit();
|
|
|
|
}
|
|
|
|
onLeaveButtonClicked() {
|
|
|
|
this.joinSessionClicked = false;
|
2022-03-10 14:12:43 +01:00
|
|
|
this.participantReady = false;
|
2022-03-09 15:31:21 +01:00
|
|
|
this.onToolbarLeaveButtonClicked.emit();
|
|
|
|
}
|
|
|
|
onCameraButtonClicked() {
|
|
|
|
this.onToolbarCameraButtonClicked.emit();
|
|
|
|
}
|
|
|
|
|
|
|
|
onMicrophoneButtonClicked() {
|
|
|
|
this.onToolbarMicrophoneButtonClicked.emit();
|
|
|
|
}
|
|
|
|
onScreenshareButtonClicked() {
|
|
|
|
this.onToolbarScreenshareButtonClicked.emit();
|
|
|
|
}
|
|
|
|
onFullscreenButtonClicked() {
|
|
|
|
this.onToolbarFullscreenButtonClicked.emit();
|
|
|
|
}
|
|
|
|
onParticipantsPanelButtonClicked() {
|
|
|
|
this.onToolbarParticipantsPanelButtonClicked.emit();
|
|
|
|
}
|
|
|
|
onChatPanelButtonClicked() {
|
|
|
|
this.onToolbarChatPanelButtonClicked.emit();
|
2022-01-20 11:53:56 +01:00
|
|
|
}
|
2022-03-10 17:08:12 +01:00
|
|
|
_onSessionCreated(event: any) {
|
|
|
|
this.onSessionCreated.emit(event);
|
|
|
|
}
|
2022-03-10 14:12:43 +01:00
|
|
|
|
|
|
|
private handlePublisherError(e: any) {
|
|
|
|
let message: string;
|
|
|
|
if (e.name === OpenViduErrorName.DEVICE_ALREADY_IN_USE) {
|
|
|
|
this.log.w('Video device already in use. Disabling video device...');
|
|
|
|
// Allow access to the room with only mic if camera device is already in use
|
|
|
|
this.deviceSrv.disableVideoDevices();
|
|
|
|
return this.initwebcamPublisher();
|
|
|
|
}
|
|
|
|
if (e.name === OpenViduErrorName.DEVICE_ACCESS_DENIED) {
|
|
|
|
message = 'Access to media devices was not allowed.';
|
|
|
|
this.deviceSrv.disableVideoDevices();
|
|
|
|
this.deviceSrv.disableAudioDevices();
|
|
|
|
return this.initwebcamPublisher();
|
|
|
|
} else if (e.name === OpenViduErrorName.NO_INPUT_SOURCE_SET) {
|
|
|
|
message = 'No video or audio devices have been found. Please, connect at least one.';
|
|
|
|
}
|
|
|
|
this.actionService.openDialog(e.name.replace(/_/g, ' '), message, true);
|
|
|
|
this.log.e(e.message);
|
|
|
|
}
|
|
|
|
|
|
|
|
private subscribeToVideconferenceDirectives() {
|
|
|
|
this.prejoinSub = this.libService.prejoin.subscribe((value: boolean) => {
|
|
|
|
this.showPrejoin = value;
|
|
|
|
// this.cd.markForCheck();
|
|
|
|
});
|
|
|
|
}
|
2022-01-20 11:53:56 +01:00
|
|
|
}
|