openvidu/openvidu-components-angular/src/app/openvidu-call/call.component.ts

374 lines
15 KiB
TypeScript
Raw Normal View History

2022-03-10 15:41:51 +01:00
import { Component, OnInit } from '@angular/core';
2024-07-02 19:19:05 +02:00
import {
BroadcastingStartRequestedEvent,
BroadcastingStopRequestedEvent,
RecordingDeleteRequestedEvent,
RecordingStartRequestedEvent,
RecordingStopRequestedEvent,
Room,
RoomEvent
} from 'openvidu-components-angular';
import { RestService } from '../services/rest.service';
2024-07-02 19:19:05 +02:00
import { CustomDevice } from 'dist/openvidu-components-angular/lib/models/device.model';
import { LangOption } from 'dist/openvidu-components-angular/lib/models/lang.model';
import { ActivatedRoute, Router } from '@angular/router';
2025-05-20 18:54:54 +02:00
import { ParticipantLeftEvent, ParticipantModel } from '../../../projects/openvidu-components-angular/src/lib/models/participant.model';
import { monkeyPatchMediaDevices } from '../utils/media-devices';
2022-04-28 13:09:42 +02:00
@Component({
selector: 'app-call',
templateUrl: './call.component.html',
styleUrls: ['./call.component.scss'],
standalone: false
})
export class CallComponent implements OnInit {
2024-07-02 19:19:05 +02:00
roomName = 'daily-call';
token: string;
tokenError: string | undefined;
isSessionAlive: boolean = false;
configReady: boolean = false;
minimal: boolean = false;
lang: string = 'es';
langOptions: LangOption[] = [
{ name: 'Spanish', lang: 'es' },
{ name: 'custom', lang: 'cus' }
];
prejoin: boolean = true;
prejoinDisplayParticipantName: boolean = true;
participantName: string = `Participant${Math.floor(Math.random() * 1000)}`;
videoEnabled: boolean = true;
audioEnabled: boolean = true;
toolbarCameraButton: boolean = true;
toolbarMicrophoneButton: boolean = true;
toolbarScreenshareButton: boolean = true;
toolbarFullscreenButton: boolean = true;
toolbarRecordingButton: boolean = true;
toolbarBroadcastingButton: boolean = true;
toolbarActivitiesPanelButton: boolean = true;
toolbarBackgroundEffectsButton: boolean = true;
toolbarLeaveButton: boolean = true;
toolbarChatPanelButton: boolean = true;
toolbarParticipantsPanelButton: boolean = true;
toolbarDisplayLogo: boolean = true;
toolbarDisplayRoomName: boolean = true;
streamDisplayParticipantName: boolean = true;
streamDisplayAudioDetection: boolean = true;
streamVideoControls: boolean = true;
participantPanelItemMuteButton: boolean = true;
activitiesPanelRecordingActivity: boolean = true;
activitiesPanelBroadcastingActivity: boolean = true;
toolbarSettingsButton: boolean = true;
2025-05-20 18:54:54 +02:00
fakeDevices: boolean = false;
private redirectOnLeaves: boolean = true;
2024-07-02 19:19:05 +02:00
private staticVideos = [
'https://videos.pexels.com/video-files/4089575/4089575-hd_1280_720_50fps.mp4',
'https://videos.pexels.com/video-files/8375762/8375762-hd_1080_2048_25fps.mp4',
'https://videos.pexels.com/video-files/4994156/4994156-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/5752499/5752499-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/6012390/6012390-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/6388880/6388880-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/5956873/5956873-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/5384955/5384955-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/5199626/5199626-hd_1280_720_25fps.mp4',
'https://videos.pexels.com/video-files/5638228/5638228-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/5647316/5647316-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/5992459/5992459-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/5438937/5438937-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/5586701/5586701-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/8375616/8375616-hd_1080_2048_25fps.mp4',
'https://videos.pexels.com/video-files/5087894/5087894-hd_1080_1920_25fps.mp4',
'https://videos.pexels.com/video-files/9569674/9569674-hd_1080_2048_25fps.mp4'
];
private areStaticVideosEnabled = false;
2023-02-22 13:08:22 +01:00
constructor(
private restService: RestService,
2024-07-02 19:19:05 +02:00
private router: Router,
private activatedRoute: ActivatedRoute
2023-02-22 13:08:22 +01:00
) {}
2022-03-10 15:41:51 +01:00
async ngOnInit() {
2024-07-02 19:19:05 +02:00
this.activatedRoute.queryParams.subscribe((params) => {
if (params['roomName']) this.roomName = params['roomName'];
// if (params['token']) this.token = params['token'];
if (params['minimal'] !== undefined) this.minimal = params['minimal'] === 'true';
if (params['lang']) this.lang = params['lang'];
if (params['langOptions'] === 'true') {
try {
this.langOptions = [
{ name: 'Esp', lang: 'es' },
{ name: 'Eng', lang: 'en' }
];
} catch {}
}
if (params['prejoin'] !== undefined) this.prejoin = params['prejoin'] === 'true';
if (params['displayParticipantName'] !== undefined)
this.prejoinDisplayParticipantName = params['displayParticipantName'] === 'true';
if (params['participantName']) this.participantName = params['participantName'];
if (params['videoEnabled'] !== undefined) this.videoEnabled = params['videoEnabled'] === 'true';
if (params['audioEnabled'] !== undefined) this.audioEnabled = params['audioEnabled'] === 'true';
if (params['cameraBtn'] !== undefined) this.toolbarCameraButton = params['cameraBtn'] === 'true';
if (params['toolbarMicrophoneButton'] !== undefined)
this.toolbarMicrophoneButton = params['toolbarMicrophoneButton'] === 'true';
2025-05-20 18:54:54 +02:00
if (params['screenshareBtn'] !== undefined) this.toolbarScreenshareButton = params['screenshareBtn'] === 'true';
if (params['fullscreenBtn'] !== undefined) this.toolbarFullscreenButton = params['fullscreenBtn'] === 'true';
if (params['toolbarRecordingButton'] !== undefined) this.toolbarRecordingButton = params['toolbarRecordingButton'] === 'true';
if (params['toolbarBroadcastingButton'] !== undefined)
this.toolbarBroadcastingButton = params['toolbarBroadcastingButton'] === 'true';
if (params['toolbarBackgroundEffectsButton'] !== undefined)
this.toolbarBackgroundEffectsButton = params['toolbarBackgroundEffectsButton'] === 'true';
if (params['activitiesPanelBtn'] !== undefined) this.toolbarActivitiesPanelButton = params['activitiesPanelBtn'] === 'true';
if (params['leaveBtn'] !== undefined) this.toolbarLeaveButton = params['leaveBtn'] === 'true';
if (params['chatPanelBtn'] !== undefined) this.toolbarChatPanelButton = params['chatPanelBtn'] === 'true';
if (params['participantsPanelBtn'] !== undefined)
this.toolbarParticipantsPanelButton = params['participantsPanelBtn'] === 'true';
if (params['displayLogo'] !== undefined) this.toolbarDisplayLogo = params['displayLogo'] === 'true';
if (params['displayRoomName'] !== undefined) this.toolbarDisplayRoomName = params['displayRoomName'] === 'true';
if (params['displayParticipantName'] !== undefined)
this.streamDisplayParticipantName = params['displayParticipantName'] === 'true';
if (params['displayAudioDetection'] !== undefined)
this.streamDisplayAudioDetection = params['displayAudioDetection'] === 'true';
if (params['streamVideoControls'] !== undefined) this.streamVideoControls = params['streamVideoControls'] === 'true';
2025-05-20 18:54:54 +02:00
if (params['participantMuteBtn'] !== undefined) this.participantPanelItemMuteButton = params['participantMuteBtn'] === 'true';
if (params['activitiesPanelRecordingActivity'] !== undefined)
this.activitiesPanelRecordingActivity = params['activitiesPanelRecordingActivity'] === 'true';
if (params['activitiesPanelBroadcastingActivity'] !== undefined)
this.activitiesPanelBroadcastingActivity = params['activitiesPanelBroadcastingActivity'] === 'true';
if (params['toolbarSettingsBtn'] !== undefined) this.toolbarSettingsButton = params['toolbarSettingsBtn'] === 'true';
if (params['staticVideos'] !== undefined) this.areStaticVideosEnabled = params['staticVideos'] === 'true';
2025-05-20 18:54:54 +02:00
if (params['fakeDevices'] !== undefined) this.fakeDevices = params['fakeDevices'] === 'true';
if (params['redirect'] === undefined) {
this.redirectOnLeaves = true;
} else {
this.redirectOnLeaves = params['redirect'] === 'true';
}
this.configReady = true;
2025-05-20 18:54:54 +02:00
if (this.areStaticVideosEnabled) {
setTimeout(() => {
const videoElements = document.querySelectorAll('video');
this.replaceWithStaticVideos(videoElements);
}, 3000);
}
if (this.fakeDevices) {
console.warn('Using fake devices');
monkeyPatchMediaDevices();
}
2024-07-02 19:19:05 +02:00
});
}
2024-07-02 19:19:05 +02:00
async onTokenRequested(participantName: string) {
console.warn('VC TOKEN REQUESTED', participantName);
2025-05-20 18:54:54 +02:00
this.appendElement('onTokenRequested');
2024-07-02 19:19:05 +02:00
await this.requestForTokens(participantName);
2022-04-28 13:09:42 +02:00
}
2024-07-02 19:19:05 +02:00
async onReadyToJoin() {
2025-05-20 18:54:54 +02:00
this.appendElement('onReadyToJoin');
2024-07-02 19:19:05 +02:00
console.warn('VC IS READY TO JOIN');
}
async onParticipantLeft(event: ParticipantLeftEvent) {
2025-05-20 18:54:54 +02:00
this.appendElement('onParticipantLeft');
console.warn('VC PARTICIPANT LEFT', event);
2025-05-20 18:54:54 +02:00
if (this.redirectOnLeaves) await this.router.navigate(['/']);
}
2024-07-02 19:19:05 +02:00
onRoomCreated(room: Room) {
2025-05-20 18:54:54 +02:00
this.appendElement('onRoomCreated');
console.warn('VC ROOM CREATED', room.name);
2024-07-02 19:19:05 +02:00
room.on(RoomEvent.Connected, () => {
if (this.areStaticVideosEnabled) {
setTimeout(() => {
const videoElements = document.querySelectorAll('video');
this.replaceWithStaticVideos(videoElements);
}, 3000);
}
});
room.on(RoomEvent.TrackPublished, (publication, participant) => {
participant.videoTrackPublications.forEach((publication) => {
if (this.areStaticVideosEnabled) {
setTimeout(() => {
if (publication.videoTrack?.attachedElements) {
this.replaceWithStaticVideos(publication.videoTrack?.attachedElements);
const firstVideo = this.staticVideos.shift();
this.staticVideos.push(firstVideo);
}
}, 2000);
}
});
});
}
2025-05-20 18:54:54 +02:00
onParticipantCreated(event: ParticipantModel) {
this.appendElement(event.name + '-onParticipantCreated');
console.warn('VC PARTICIPANT CREATED', event);
}
2024-07-02 19:19:05 +02:00
onVideoEnabledChanged(value: boolean) {
2025-05-20 18:54:54 +02:00
this.appendElement('onVideoEnabledChanged-' + value);
2024-07-02 19:19:05 +02:00
console.warn('VC video enabled: ', value);
2022-03-10 15:41:51 +01:00
}
2024-07-02 19:19:05 +02:00
onVideoDeviceChanged(device: CustomDevice) {
2025-05-20 18:54:54 +02:00
this.appendElement('onVideoDeviceChanged');
2024-07-02 19:19:05 +02:00
console.warn('VC video device changed: ', device);
2022-03-10 15:41:51 +01:00
}
2024-07-02 19:19:05 +02:00
onAudioEnabledChanged(value: boolean) {
2025-05-20 18:54:54 +02:00
this.appendElement('onAudioEnabledChanged-' + value);
2024-07-02 19:19:05 +02:00
console.warn('VC audio enabled: ', value);
2022-03-10 15:41:51 +01:00
}
2024-07-02 19:19:05 +02:00
onAudioDeviceChanged(device: CustomDevice) {
2025-05-20 18:54:54 +02:00
this.appendElement('onAudioDeviceChanged');
2024-07-02 19:19:05 +02:00
console.warn('VC audio device changed: ', device);
2022-03-10 15:41:51 +01:00
}
2024-07-02 19:19:05 +02:00
onScreenShareEnabledChanged(enabled: boolean) {
2025-05-20 18:54:54 +02:00
this.appendElement('onScreenShareEnabledChanged');
2024-07-02 19:19:05 +02:00
console.warn('VC screenshare enabled: ', enabled);
2022-03-10 15:41:51 +01:00
}
2024-07-02 19:19:05 +02:00
onFullscreenEnabledChanged(enabled: boolean) {
2025-05-20 18:54:54 +02:00
this.appendElement('onFullscreenEnabledChanged-' + enabled);
2024-07-02 19:19:05 +02:00
console.warn('VC fullscreen enabled: ', enabled);
}
onParticipantsPanelStatusChanged(event) {
2025-05-20 18:54:54 +02:00
this.appendElement('onParticipantsPanelStatusChanged-' + event.isOpened);
2024-07-02 19:19:05 +02:00
console.warn('VC participants panel status changed: ', event);
}
onChatPanelStatusChanged(event) {
2025-05-20 18:54:54 +02:00
this.appendElement('onChatPanelStatusChanged-' + event.isOpened);
2024-07-02 19:19:05 +02:00
console.warn('VC chat status changed: ', event);
}
async onRoomDisconnected() {
2025-05-20 18:54:54 +02:00
this.appendElement('onRoomDisconnected');
2022-03-10 15:41:51 +01:00
this.isSessionAlive = false;
console.log('VC LEAVE BUTTON CLICKED');
await this.router.navigate(['/']);
2022-03-10 15:41:51 +01:00
}
2022-03-10 15:41:51 +01:00
onFullscreenButtonClicked() {
2025-05-20 18:54:54 +02:00
this.appendElement('onFullscreenButtonClicked');
2022-03-10 15:41:51 +01:00
console.warn('TOOLBAR fullscreen CLICKED');
}
onParticipantsPanelButtonClicked() {
2025-05-20 18:54:54 +02:00
this.appendElement('onParticipantsPanelButtonClicked');
2022-03-10 15:41:51 +01:00
console.warn('TOOLBAR participants CLICKED');
}
onChatPanelButtonClicked() {
2025-05-20 18:54:54 +02:00
this.appendElement('onChatPanelButtonClicked');
2022-03-10 15:41:51 +01:00
console.warn('TOOLBAR chat CLICKED');
}
2022-03-10 15:41:51 +01:00
onLeaveButtonClicked() {
2025-05-20 18:54:54 +02:00
this.appendElement('onLeaveButtonClicked');
this.isSessionAlive = false;
2022-03-10 15:41:51 +01:00
console.log('TOOLBAR LEAVE CLICKED');
}
2022-06-22 12:42:02 +02:00
2024-07-02 19:19:05 +02:00
onLangChanged(event: LangOption) {
2025-05-20 18:54:54 +02:00
this.appendElement('onLangChanged-' + event.lang);
2024-07-02 19:19:05 +02:00
console.warn('LANG CHANGED', event);
}
2025-05-20 18:54:54 +02:00
onSettingsPanelStatusChanged(event) {
this.appendElement('onSettingsPanelStatusChanged-' + event.isOpened);
console.warn('VC settings panel status changed: ', event);
}
onActivitiesPanelStatusChanged(event) {
this.appendElement('onActivitiesPanelStatusChanged-' + event.isOpened);
console.warn('VC activities panel status changed: ', event);
}
2024-07-02 19:19:05 +02:00
async onBroadcastingStartRequested(event: BroadcastingStartRequestedEvent) {
2025-05-20 18:54:54 +02:00
this.appendElement(`onBroadcastingStartRequested-${event.roomName}-${event.broadcastUrl}`);
2024-07-02 19:19:05 +02:00
console.log('START STREAMING', event);
try {
2024-07-02 19:19:05 +02:00
const resp = await this.restService.startBroadcasting(event.broadcastUrl);
console.log('Broadcasting response ', resp);
} catch (error) {
console.error(error);
}
}
2024-07-02 19:19:05 +02:00
async onBroadcastingStopRequested(event: BroadcastingStopRequestedEvent) {
2025-05-20 18:54:54 +02:00
this.appendElement('onBroadcastingStopRequested');
2024-07-02 19:19:05 +02:00
console.log('STOP STREAMING', event);
try {
const resp = await this.restService.stopBroadcasting();
console.log('Broadcasting response ', resp);
} catch (error) {
console.error(error);
}
}
2024-07-02 19:19:05 +02:00
async onRecordingStartRequested(event: RecordingStartRequestedEvent) {
2025-05-20 18:54:54 +02:00
this.appendElement('onRecordingStartRequested-' + event.roomName);
2024-07-02 19:19:05 +02:00
console.warn('START RECORDING CLICKED', event);
2022-06-22 12:42:02 +02:00
try {
2024-07-02 19:19:05 +02:00
await this.restService.startRecording(this.roomName);
2022-06-22 12:42:02 +02:00
} catch (error) {
2024-07-02 19:19:05 +02:00
console.error(error);
2022-06-22 12:42:02 +02:00
}
}
2024-07-02 19:19:05 +02:00
async onRecordingStopRequested(event: RecordingStopRequestedEvent) {
2025-05-20 18:54:54 +02:00
this.appendElement('onRecordingStopRequested');
2024-07-02 19:19:05 +02:00
console.warn('STOP RECORDING CLICKED', event);
2022-06-22 12:42:02 +02:00
try {
2024-07-02 19:19:05 +02:00
await this.restService.stopRecording(event);
2022-06-22 12:42:02 +02:00
} catch (error) {
2024-07-02 19:19:05 +02:00
console.error(error);
2022-06-22 12:42:02 +02:00
}
}
2024-07-02 19:19:05 +02:00
async onRecordingDeleteRequested(event: RecordingDeleteRequestedEvent) {
2025-05-20 18:54:54 +02:00
this.appendElement('onRecordingDeleteRequested');
2024-07-02 19:19:05 +02:00
console.warn('DELETE RECORDING requested', event);
2022-06-22 12:42:02 +02:00
try {
2024-07-02 19:19:05 +02:00
await this.restService.deleteRecording(event);
2022-06-22 12:42:02 +02:00
} catch (error) {
2024-07-02 19:19:05 +02:00
console.error(error);
2022-06-22 12:42:02 +02:00
}
}
2024-07-02 19:19:05 +02:00
private async requestForTokens(participantName: string) {
try {
const { token } = await this.restService.getTokenFromBackend(this.roomName, participantName);
this.token = token;
} catch (error) {
console.error(error);
this.tokenError = error.error;
}
}
2024-07-02 19:19:05 +02:00
private replaceWithStaticVideos(videoElements) {
let sourceIndex = 0;
for (let i = 0; i < videoElements.length; i++) {
const videoElement = videoElements[i];
videoElement.srcObject = null;
videoElement.src = this.staticVideos[sourceIndex];
console.log(`Assigned ${this.staticVideos[sourceIndex]}`);
sourceIndex = (sourceIndex + 1) % this.staticVideos.length;
videoElement.addEventListener('ended', () => {
// Allow loop
videoElement.currentTime = 0;
videoElement.play();
});
}
}
2025-05-20 18:54:54 +02:00
private appendElement(id: string) {
var eventsDiv = document.getElementById('events');
eventsDiv?.setAttribute('style', 'position: absolute;');
var element = document.createElement('div');
element.setAttribute('id', id);
element.setAttribute('style', 'height: 1px;');
eventsDiv?.appendChild(element);
}
}