108 lines
4.1 KiB
TypeScript
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;
|
|
}
|
|
}
|