108 lines
4.1 KiB
TypeScript

import { Component, HostListener, OnDestroy } from '@angular/core';
import { ReactiveFormsModule, FormControl, FormGroup, Validators } from '@angular/forms';
import { Room } from 'livekit-client';
import { VideoComponent } from './video/video.component';
import { AudioComponent } from './audio/audio.component';
import { HttpClient } from '@angular/common/http';
import { lastValueFrom } from 'rxjs';
// For local development, leave these variables empty
// For production, configure them with correct URLs depending on your deployment
var APPLICATION_SERVER_URL = '';
var LIVEKIT_URL = '';
@Component({
selector: 'app-root',
standalone: true,
imports: [ReactiveFormsModule, AudioComponent, VideoComponent],
templateUrl: './app.component.html',
styleUrl: './app.component.css',
})
export class AppComponent implements OnDestroy {
roomForm = new FormGroup({
roomName: new FormControl('Test Room', Validators.required),
participantName: new FormControl('Participant' + Math.floor(Math.random() * 100), Validators.required),
});
room?: Room;
constructor(private httpClient: HttpClient) {
this.configureUrls();
}
configureUrls() {
// If APPLICATION_SERVER_URL is not configured, use default value from local development
if (!APPLICATION_SERVER_URL) {
if (window.location.hostname === 'localhost') {
APPLICATION_SERVER_URL = 'http://localhost:6080/';
} else {
APPLICATION_SERVER_URL = 'https://' + window.location.hostname + ':6443/';
}
}
// If LIVEKIT_URL is not configured, use default value from local development
if (!LIVEKIT_URL) {
if (window.location.hostname === 'localhost') {
LIVEKIT_URL = 'ws://localhost:7880/';
} else {
LIVEKIT_URL = 'wss://' + window.location.hostname + ':7443/';
}
}
}
async joinRoom() {
// Initialize a new Room object
this.room = new Room();
try {
// Get the room name and participant name from the form
const roomName = this.roomForm.value.roomName!;
const participantName = this.roomForm.value.participantName!;
// Get a token from your application server with the room name and participant name
const token = await this.getToken(roomName, participantName);
// Connect to the room with the LiveKit URL and the token
await this.room.connect(LIVEKIT_URL, token);
// Publish your camera and microphone
await this.room.localParticipant.enableCameraAndMicrophone();
} catch (error: any) {
console.log('There was an error connecting to the room:', error?.error?.errorMessage || error?.message || error);
await this.leaveRoom();
}
}
async leaveRoom() {
// Leave the room by calling 'disconnect' method over the Room object
await this.room?.disconnect();
delete this.room;
}
@HostListener('window:beforeunload')
async ngOnDestroy() {
// On window closed or component destroyed, leave the room
await this.leaveRoom();
}
/**
* --------------------------------------------
* GETTING A TOKEN FROM YOUR APPLICATION SERVER
* --------------------------------------------
* The method below request the creation of a token to
* your application server. This prevents the need to expose
* your LiveKit API key and secret to the client side.
*
* In this sample code, there is no user control at all. Anybody could
* access your application server endpoints. In a real production
* environment, your application server must identify the user to allow
* access to the endpoints.
*/
async getToken(roomName: string, participantName: string): Promise<string> {
const response = await lastValueFrom(
this.httpClient.post<{ token: string }>(APPLICATION_SERVER_URL + 'token', { roomName, participantName })
);
return response.token;
}
}