openvidu-recording: Add comments
This commit is contained in:
parent
f5da0c397d
commit
99bb02ce6a
@ -41,6 +41,7 @@ async function joinRoom() {
|
||||
}
|
||||
});
|
||||
|
||||
// When recording status changes...
|
||||
room.on(LivekitClient.RoomEvent.RecordingStatusChanged, async (isRecording) => {
|
||||
await updateRecordingInfo(isRecording);
|
||||
});
|
||||
@ -66,6 +67,7 @@ async function joinRoom() {
|
||||
const localVideoTrack = this.room.localParticipant.videoTrackPublications.values().next().value.track;
|
||||
addTrack(localVideoTrack, userName, true);
|
||||
|
||||
// Update recording info
|
||||
await updateRecordingInfo(room.isRecording);
|
||||
} catch (error) {
|
||||
console.log("There was an error connecting to the room:", error.message);
|
||||
@ -126,6 +128,7 @@ document.addEventListener("DOMContentLoaded", async function () {
|
||||
generateFormValues();
|
||||
}
|
||||
|
||||
// Remove recording video when the dialog is closed
|
||||
document.getElementById("recording-video-dialog").addEventListener("close", () => {
|
||||
const recordingVideo = document.getElementById("recording-video");
|
||||
recordingVideo.src = "";
|
||||
|
||||
@ -68,17 +68,20 @@ app.post("/recordings/start", async (req, res) => {
|
||||
|
||||
const activeEgresses = await getActiveEgressesByRoom(roomName);
|
||||
|
||||
// Check if there is already an active egress for this room
|
||||
if (activeEgresses.length > 0) {
|
||||
res.status(409).json({ errorMessage: "Recording already started for this room" });
|
||||
return;
|
||||
}
|
||||
|
||||
// Use the EncodedFileOutput to save the recording to an MP4 file
|
||||
const fileOutput = new EncodedFileOutput({
|
||||
fileType: EncodedFileType.MP4,
|
||||
filepath: `${RECORDINGS_PATH}{room_name}-{room_id}-{time}`
|
||||
});
|
||||
|
||||
try {
|
||||
// Start a RoomCompositeEgress to record all participants in the room
|
||||
const egressInfo = await egressClient.startRoomCompositeEgress(roomName, { file: fileOutput });
|
||||
const recording = {
|
||||
name: egressInfo.fileResults[0].filename.split("/").pop(),
|
||||
@ -101,6 +104,7 @@ app.post("/recordings/stop", async (req, res) => {
|
||||
|
||||
const activeEgresses = await getActiveEgressesByRoom(roomName);
|
||||
|
||||
// Check if there is an active egress for this room
|
||||
if (activeEgresses.length === 0) {
|
||||
res.status(409).json({ errorMessage: "Recording not started for this room" });
|
||||
return;
|
||||
@ -109,6 +113,7 @@ app.post("/recordings/stop", async (req, res) => {
|
||||
const egressId = activeEgresses[0].egressId;
|
||||
|
||||
try {
|
||||
// Stop the Egress to finish the recording
|
||||
const egressInfo = await egressClient.stopEgress(egressId);
|
||||
const file = egressInfo.fileResults[0];
|
||||
const recording = {
|
||||
@ -125,6 +130,7 @@ app.post("/recordings/stop", async (req, res) => {
|
||||
|
||||
const getActiveEgressesByRoom = async (roomName) => {
|
||||
try {
|
||||
// List all active egresses for the room
|
||||
return await egressClient.listEgress({ roomName, active: true });
|
||||
} catch (error) {
|
||||
console.error("Error listing egresses.", error);
|
||||
@ -140,6 +146,8 @@ app.get("/recordings", async (req, res) => {
|
||||
const keyStart = RECORDINGS_PATH + (roomName ? `${roomName}` + (roomId ? `-${roomId}` : "") : "");
|
||||
const keyEnd = ".mp4.json";
|
||||
const regex = new RegExp(`^${keyStart}.*${keyEnd}$`);
|
||||
|
||||
// List all Egress metadata files in the recordings path that match the regex
|
||||
const payloadKeys = await s3Service.listObjects(RECORDINGS_PATH, regex);
|
||||
const recordings = await Promise.all(payloadKeys.map((payloadKey) => getRecordingInfo(payloadKey)));
|
||||
res.json({ recordings });
|
||||
@ -150,8 +158,10 @@ app.get("/recordings", async (req, res) => {
|
||||
});
|
||||
|
||||
const getRecordingInfo = async (payloadKey) => {
|
||||
// Get the Egress metadata file as JSON
|
||||
const data = await s3Service.getObjectAsJson(payloadKey);
|
||||
|
||||
// Get the recording file size
|
||||
const recordingKey = payloadKey.replace(".json", "");
|
||||
const size = await s3Service.getObjectSize(recordingKey);
|
||||
|
||||
@ -175,10 +185,15 @@ app.get("/recordings/:recordingName", async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
// Get the recording file from S3
|
||||
const { body, size } = await s3Service.getObject(key);
|
||||
|
||||
// Set the response headers
|
||||
res.setHeader("Content-Type", "video/mp4");
|
||||
res.setHeader("Content-Length", size);
|
||||
res.setHeader("Accept-Ranges", "bytes");
|
||||
|
||||
// Pipe the recording file to the response
|
||||
body.pipe(res).on("finish", () => res.end());
|
||||
} catch (error) {
|
||||
console.error("Error getting recording.", error);
|
||||
@ -197,6 +212,7 @@ app.delete("/recordings/:recordingName", async (req, res) => {
|
||||
}
|
||||
|
||||
try {
|
||||
// Delete the recording file and metadata file from S3
|
||||
await Promise.all([s3Service.deleteObject(key), s3Service.deleteObject(`${key}.json`)]);
|
||||
res.json({ message: "Recording deleted" });
|
||||
} catch (error) {
|
||||
|
||||
@ -81,6 +81,8 @@ export class S3Service {
|
||||
};
|
||||
const command = new ListObjectsV2Command(params);
|
||||
const { Contents: objects } = await this.run(command);
|
||||
|
||||
// Filter objects by regex and return the keys
|
||||
return (
|
||||
objects
|
||||
?.filter((object) => regex.test(object.Key))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user