openvidu-recording-improved: Notify participants when recording is deleted and remove corresponding container
This commit is contained in:
parent
2cc5d505da
commit
8664ba3312
@ -47,6 +47,15 @@ async function joinRoom() {
|
||||
await updateRecordingInfo(recordingStatus);
|
||||
});
|
||||
|
||||
// When a message is received...
|
||||
room.on(LivekitClient.RoomEvent.DataReceived, async (payload, _participant, _kind, topic) => {
|
||||
// If the message is a recording deletion notification, remove the recording from the list
|
||||
if (topic === "RECORDING_DELETED") {
|
||||
const { recordingName } = JSON.parse(new TextDecoder().decode(payload));
|
||||
deleteRecordingContainer(recordingName);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
// Get the room name and participant name from the form
|
||||
const roomName = document.getElementById("room-name").value;
|
||||
@ -267,8 +276,21 @@ async function deleteRecording(recordingName) {
|
||||
const [error, _] = await httpRequest("DELETE", `/recordings/${recordingName}`);
|
||||
|
||||
if (!error || error.status === 404) {
|
||||
const roomId = await room?.getSid();
|
||||
await listRecordings(room?.name, roomId);
|
||||
deleteRecordingContainer(recordingName);
|
||||
}
|
||||
}
|
||||
|
||||
function deleteRecordingContainer(recordingName) {
|
||||
const recordingContainer = document.getElementById(recordingName);
|
||||
|
||||
if (recordingContainer) {
|
||||
recordingContainer.remove();
|
||||
|
||||
const recordingsList = document.getElementById("recording-list");
|
||||
|
||||
if (recordingsList.children.length === 0) {
|
||||
recordingsList.innerHTML = "<span>There are no recordings available</span>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,9 @@
|
||||
import { Router } from "express";
|
||||
import { RecordingService } from "../services/recording.service.js";
|
||||
import { RoomService } from "../services/room.service.js";
|
||||
|
||||
const recordingService = new RecordingService();
|
||||
const roomService = new RoomService();
|
||||
|
||||
export const recordingController = Router();
|
||||
|
||||
@ -104,7 +106,11 @@ recordingController.delete("/:recordingName", async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const { roomName } = await recordingService.getRecordingMetadata(recordingName);
|
||||
await recordingService.deleteRecording(recordingName);
|
||||
|
||||
// Notify to all participants that the recording was deleted
|
||||
await roomService.sendDataToRoom(roomName, { recordingName });
|
||||
res.json({ message: "Recording deleted" });
|
||||
} catch (error) {
|
||||
console.error("Error deleting recording.", error);
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
import { EgressClient, EgressStatus, EncodedFileOutput, EncodedFileType } from "livekit-server-sdk";
|
||||
import { LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET, RECORDINGS_PATH, RECORDINGS_METADATA_PATH } from "../config.js";
|
||||
import {
|
||||
LIVEKIT_URL,
|
||||
LIVEKIT_API_KEY,
|
||||
LIVEKIT_API_SECRET,
|
||||
RECORDINGS_PATH,
|
||||
RECORDINGS_METADATA_PATH
|
||||
} from "../config.js";
|
||||
import { S3Service } from "./s3.service.js";
|
||||
|
||||
const s3Service = new S3Service();
|
||||
@ -58,34 +64,41 @@ export class RecordingService {
|
||||
}
|
||||
}
|
||||
|
||||
async getRecordingMetadata(recordingName) {
|
||||
const key = this.getMetadataKey(recordingName);
|
||||
return s3Service.getObjectAsJson(key);
|
||||
}
|
||||
|
||||
async getRecordingStream(recordingName) {
|
||||
const key = RECORDINGS_PATH + recordingName;
|
||||
const key = this.getRecordingKey(recordingName);
|
||||
return s3Service.getObject(key);
|
||||
}
|
||||
|
||||
async existsRecording(recordingName) {
|
||||
const key = RECORDINGS_PATH + recordingName;
|
||||
const key = this.getRecordingKey(recordingName);
|
||||
return s3Service.exists(key);
|
||||
}
|
||||
|
||||
async deleteRecording(recordingName) {
|
||||
const recordingKey = RECORDINGS_PATH + recordingName;
|
||||
const metadataKey = RECORDINGS_PATH + RECORDINGS_METADATA_PATH + recordingName.replace(".mp4", ".json");
|
||||
const metadataKey = this.getMetadataKey(recordingName);
|
||||
// Delete the recording file and metadata file from S3
|
||||
await Promise.all([s3Service.deleteObject(recordingKey), s3Service.deleteObject(metadataKey)]);
|
||||
}
|
||||
|
||||
async saveRecordingMetadata(egressInfo) {
|
||||
const recordingInfo = this.convertToRecordingInfo(egressInfo);
|
||||
const metadataName = recordingInfo.name.replace(".mp4", ".json");
|
||||
const key = RECORDINGS_PATH + RECORDINGS_METADATA_PATH + metadataName;
|
||||
const key = this.getMetadataKey(recordingInfo.name);
|
||||
await s3Service.uploadObject(key, recordingInfo);
|
||||
}
|
||||
|
||||
convertToRecordingInfo(egressInfo) {
|
||||
const file = egressInfo.fileResults[0];
|
||||
return {
|
||||
id: egressInfo.egressId,
|
||||
name: file.filename.split("/").pop(),
|
||||
roomName: egressInfo.roomName,
|
||||
roomId: egressInfo.roomId,
|
||||
startedAt: Number(egressInfo.startedAt) / 1_000_000,
|
||||
duration: Number(file.duration) / 1_000_000_000,
|
||||
size: Number(file.size)
|
||||
@ -106,4 +119,12 @@ export class RecordingService {
|
||||
return "FAILED";
|
||||
}
|
||||
}
|
||||
|
||||
getRecordingKey(recordingName) {
|
||||
return RECORDINGS_PATH + recordingName;
|
||||
}
|
||||
|
||||
getMetadataKey(recordingName) {
|
||||
return RECORDINGS_PATH + RECORDINGS_METADATA_PATH + recordingName.replace(".mp4", ".json");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
import { RoomServiceClient } from "livekit-server-sdk";
|
||||
import { DataPacket_Kind, RoomServiceClient } from "livekit-server-sdk";
|
||||
import { LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET, APP_NAME } from "../config.js";
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
|
||||
export class RoomService {
|
||||
static instance;
|
||||
|
||||
@ -37,4 +39,18 @@ export class RoomService {
|
||||
};
|
||||
return this.roomClient.updateRoomMetadata(roomName, JSON.stringify(metadata));
|
||||
}
|
||||
|
||||
async sendDataToRoom(roomName, rawData) {
|
||||
const data = encoder.encode(JSON.stringify(rawData));
|
||||
const options = {
|
||||
topic: "RECORDING_DELETED",
|
||||
destinationSids: []
|
||||
};
|
||||
|
||||
try {
|
||||
await this.roomClient.sendData(roomName, data, DataPacket_Kind.RELIABLE, options);
|
||||
} catch (error) {
|
||||
console.error("Error sending data to room", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user