From 3ca91288d2d24a41b950232cf5962a0cd32bcf3d Mon Sep 17 00:00:00 2001 From: rainbow napkin Date: Wed, 3 Jun 2026 23:25:55 -0400 Subject: [PATCH] Fixed post-crash recovery for actively livestreaming channels. --- src/app/channel/media/archivedMedia.js | 2 +- src/app/channel/media/queue.js | 22 +++++++++---------- src/app/channel/media/queuedMedia.js | 21 ++++++++++++++++++ .../channel/media/archivedMediaSchema.js | 2 +- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/src/app/channel/media/archivedMedia.js b/src/app/channel/media/archivedMedia.js index 9aaa85f..11fe9ef 100644 --- a/src/app/channel/media/archivedMedia.js +++ b/src/app/channel/media/archivedMedia.js @@ -83,7 +83,7 @@ class archivedMedia extends queuedMedia{ media.startTime, media.startTimeStamp, media.earlyEnd, - null, + media.uuid, channel); } diff --git a/src/app/channel/media/queue.js b/src/app/channel/media/queue.js index d5627d9..705fe82 100644 --- a/src/app/channel/media/queue.js +++ b/src/app/channel/media/queue.js @@ -1267,7 +1267,7 @@ class queue{ //If archiving is enabled if(!noArchive){ //Add the item to the channel archive - this.archiveMedia(wasPlaying); + await this.archiveMedia(wasPlaying); } //broadcast queue using unsaved archive, run this before chanDB.save() for better responsiveness @@ -1828,29 +1828,29 @@ class queue{ //If we have a remainder from a livestream if(chanDB.media.liveRemainder){ - //Iterate backwards through the archive to pull the newest first, since that's probably where this fucker is - for(let archiveIndex = (chanDB.media.archived.length - 1); archiveIndex > 0; archiveIndex--){ - //Grab the current media object - const archivedMedia = chanDB.media.archived[archiveIndex]; + let archive = await this.getArchive(); + + //Iterate backwards through channel archive + for(let archiveIndex = (archive.length - 1); archiveIndex > 0; archiveIndex--){ //If the current object matches our remainder UUID - if((archivedMedia.uuid.toString() == chanDB.media.liveRemainder.toString())){ + if((archive[archiveIndex].uuid.toString() == chanDB.media.liveRemainder.toString())){ //Null out any early end - archivedMedia.earlyEnd = null; + archive[archiveIndex].earlyEnd = null; //Re-hydrate the item - const archivedMediaObject = archivedMedia.rehydrate(); + const archivedMediaObject = archive[archiveIndex].rehydrate(); //if we still have a video to finish if(archivedMediaObject.getEndTime() > now){ - //Set the fucker as now playing - chanDB.media.nowPlaying = archivedMediaObject; + //Convert the fucker back to queuedMedia and save as now playing + chanDB.media.nowPlaying = queuedMedia.fromArchivedMedia(archivedMediaObject); //Schedule the fucker in RAM, w/ the start function also running in RAM-Only mode this.scheduleMedia([archivedMediaObject], null, chanDB, true, true, true); //Splice the fucker out of the archive - chanDB.media.archived.splice(archiveIndex, 1); + await archivedMediaModel.deleteOne({channel: this.channel.name, uuid: new BSON.UUID(chanDB.media.liveRemainder)}); } //Break out of the loop diff --git a/src/app/channel/media/queuedMedia.js b/src/app/channel/media/queuedMedia.js index 863c770..94acb41 100644 --- a/src/app/channel/media/queuedMedia.js +++ b/src/app/channel/media/queuedMedia.js @@ -88,6 +88,27 @@ class queuedMedia extends media{ startTimeStamp); } + /** + * Creates a queuedMedia object from an archivedMedia object + * @param {String} channel - Channel where object was queued + * @returns {archivedMedia} queuedMedia object created from given media object + */ + static fromArchivedMedia(media){ + //Create and return queuedMedia object from given media object and arguments + return new this( + media.title, + media.fileName, + media.url, + media.id, + media.type, + media.duration, + media.rawLink, + media.startTime, + media.startTimeStamp, + media.earlyEnd, + media.uuid); + } + /** * Converts array of media objects into array of queuedMedia objects * @param {Array} mediaList - Array of media objects to queue diff --git a/src/schemas/channel/media/archivedMediaSchema.js b/src/schemas/channel/media/archivedMediaSchema.js index 115d45d..4b58169 100644 --- a/src/schemas/channel/media/archivedMediaSchema.js +++ b/src/schemas/channel/media/archivedMediaSchema.js @@ -22,7 +22,7 @@ const mediaSchema = require('./mediaSchema'); const archivedMedia = require('../../../app/channel/media/archivedMedia'); /** - * DB Schema for documents representing a queued media object + * DB Schema for documents representing a archived media object */ const archivedProperties = new mongoose.Schema({ channel: {