backend: refactor recording metadata handling to use MeetStorageService

This commit is contained in:
Carlos Santos 2025-05-28 14:09:08 +02:00
parent f58e0fd111
commit 2e51681cd9
4 changed files with 27 additions and 10 deletions

View File

@ -217,13 +217,12 @@ export class LivekitWebhookService {
try { try {
const recordingInfo: MeetRecordingInfo = RecordingHelper.toRecordingInfo(egressInfo); const recordingInfo: MeetRecordingInfo = RecordingHelper.toRecordingInfo(egressInfo);
const { roomId, recordingId, status } = recordingInfo; const { roomId, recordingId, status } = recordingInfo;
const metadataPath = RecordingHelper.buildMetadataFilePath(recordingId);
this.logger.debug(`Recording '${recordingId}' in room '${roomId}' status: '${status}'`); this.logger.debug(`Recording '${recordingId}' in room '${roomId}' status: '${status}'`);
// Common tasks for all webhook types // Common tasks for all webhook types
const commonTasks = [ const commonTasks = [
this.s3Service.saveObject(metadataPath, recordingInfo), this.storageService.saveRecordingMetadata(recordingInfo),
this.recordingService.sendRecordingSignalToOpenViduComponents(roomId, recordingInfo) this.recordingService.sendRecordingSignalToOpenViduComponents(roomId, recordingInfo)
]; ];

View File

@ -28,6 +28,7 @@ import {
IScheduledTask, IScheduledTask,
LiveKitService, LiveKitService,
LoggerService, LoggerService,
MeetStorageService,
MutexService, MutexService,
RedisLock, RedisLock,
RoomService, RoomService,
@ -45,6 +46,7 @@ export class RecordingService {
@inject(MutexService) protected mutexService: MutexService, @inject(MutexService) protected mutexService: MutexService,
@inject(TaskSchedulerService) protected taskSchedulerService: TaskSchedulerService, @inject(TaskSchedulerService) protected taskSchedulerService: TaskSchedulerService,
@inject(SystemEventService) protected systemEventService: SystemEventService, @inject(SystemEventService) protected systemEventService: SystemEventService,
@inject(MeetStorageService) protected storageService: MeetStorageService,
@inject(LoggerService) protected logger: LoggerService @inject(LoggerService) protected logger: LoggerService
) { ) {
// Register the recording garbage collector task // Register the recording garbage collector task
@ -544,7 +546,7 @@ export class RecordingService {
protected generateCompositeOptionsFromRequest(layout = 'grid'): RoomCompositeOptions { protected generateCompositeOptionsFromRequest(layout = 'grid'): RoomCompositeOptions {
return { return {
layout: layout, layout: layout
// customBaseUrl: customLayout, // customBaseUrl: customLayout,
// audioOnly: false, // audioOnly: false,
// videoOnly: false // videoOnly: false
@ -645,10 +647,9 @@ export class RecordingService {
} }
protected async updateRecordingStatus(recordingId: string, status: MeetRecordingStatus): Promise<void> { protected async updateRecordingStatus(recordingId: string, status: MeetRecordingStatus): Promise<void> {
const metadataPath = RecordingHelper.buildMetadataFilePath(recordingId);
const recordingInfo = await this.getRecording(recordingId); const recordingInfo = await this.getRecording(recordingId);
recordingInfo.status = status; recordingInfo.status = status;
await this.s3Service.saveObject(metadataPath, recordingInfo); await this.storageService.saveRecordingMetadata(recordingInfo);
} }
/** /**

View File

@ -4,6 +4,7 @@ import { inject, injectable } from 'inversify';
import INTERNAL_CONFIG from '../../../config/internal-config.js'; import INTERNAL_CONFIG from '../../../config/internal-config.js';
import { OpenViduMeetError, RedisKeyName } from '../../../models/index.js'; import { OpenViduMeetError, RedisKeyName } from '../../../models/index.js';
import { LoggerService, RedisService, S3Service, StorageProvider } from '../../index.js'; import { LoggerService, RedisService, S3Service, StorageProvider } from '../../index.js';
import { RecordingHelper } from '../../../helpers/recording.helper.js';
/** /**
* Implementation of the StorageProvider interface using AWS S3 for persistent storage * Implementation of the StorageProvider interface using AWS S3 for persistent storage
@ -360,9 +361,14 @@ export class S3StorageProvider<
} }
async saveRecordingMetadata(recordingInfo: MRec): Promise<MRec> { async saveRecordingMetadata(recordingInfo: MRec): Promise<MRec> {
//TODO : Implement this method to save recording metadata for a room try {
this.logger.warn('saveMeetRecordingInfo is not implemented yet'); const metadataPath = RecordingHelper.buildMetadataFilePath(recordingInfo.recordingId);
await this.s3Service.saveObject(metadataPath, recordingInfo);
return recordingInfo; return recordingInfo;
} catch (error) {
this.handleError(error, `Error saving recording metadata for recording ${recordingInfo.recordingId}`);
throw error;
}
} }
async deleteRecordingMetadata(recordingId: string): Promise<void> { async deleteRecordingMetadata(recordingId: string): Promise<void> {

View File

@ -1,4 +1,4 @@
import { AuthMode, AuthType, GlobalPreferences, MeetRoom } from '@typings-ce'; import { AuthMode, AuthType, GlobalPreferences, MeetRecordingInfo, MeetRoom } from '@typings-ce';
import { inject, injectable } from 'inversify'; import { inject, injectable } from 'inversify';
import ms from 'ms'; import ms from 'ms';
import { MEET_NAME_ID, MEET_SECRET, MEET_USER, MEET_WEBHOOK_ENABLED, MEET_WEBHOOK_URL } from '../../environment.js'; import { MEET_NAME_ID, MEET_SECRET, MEET_USER, MEET_WEBHOOK_ENABLED, MEET_WEBHOOK_URL } from '../../environment.js';
@ -18,7 +18,8 @@ import { LoggerService, MutexService, StorageFactory, StorageProvider } from '..
@injectable() @injectable()
export class MeetStorageService< export class MeetStorageService<
GPrefs extends GlobalPreferences = GlobalPreferences, GPrefs extends GlobalPreferences = GlobalPreferences,
MRoom extends MeetRoom = MeetRoom MRoom extends MeetRoom = MeetRoom,
MRec extends MeetRecordingInfo = MeetRecordingInfo
> { > {
protected storageProvider: StorageProvider; protected storageProvider: StorageProvider;
constructor( constructor(
@ -181,6 +182,16 @@ export class MeetStorageService<
return this.storageProvider.updateArchivedRoomMetadata(roomId); return this.storageProvider.updateArchivedRoomMetadata(roomId);
} }
/**
* Saves recording metadata to the storage provider.
*
* @param recordingInfo - The recording metadata object to be saved
* @returns A promise that resolves to the saved recording metadata object
*/
async saveRecordingMetadata(recordingInfo: MRec): Promise<MRec> {
return this.storageProvider.saveRecordingMetadata(recordingInfo) as Promise<MRec>;
}
/** /**
* Returns the default global preferences. * Returns the default global preferences.
* @returns {GPrefs} * @returns {GPrefs}