Fixed post-crash recovery for actively livestreaming channels.

This commit is contained in:
rainbow napkin 2026-06-03 23:25:55 -04:00
parent ee47e1b844
commit 3ca91288d2
4 changed files with 34 additions and 13 deletions

View file

@ -83,7 +83,7 @@ class archivedMedia extends queuedMedia{
media.startTime, media.startTime,
media.startTimeStamp, media.startTimeStamp,
media.earlyEnd, media.earlyEnd,
null, media.uuid,
channel); channel);
} }

View file

@ -1267,7 +1267,7 @@ class queue{
//If archiving is enabled //If archiving is enabled
if(!noArchive){ if(!noArchive){
//Add the item to the channel archive //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 //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 we have a remainder from a livestream
if(chanDB.media.liveRemainder){ if(chanDB.media.liveRemainder){
//Iterate backwards through the archive to pull the newest first, since that's probably where this fucker is let archive = await this.getArchive();
for(let archiveIndex = (chanDB.media.archived.length - 1); archiveIndex > 0; archiveIndex--){
//Grab the current media object
const archivedMedia = chanDB.media.archived[archiveIndex];
//Iterate backwards through channel archive
for(let archiveIndex = (archive.length - 1); archiveIndex > 0; archiveIndex--){
//If the current object matches our remainder UUID //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 //Null out any early end
archivedMedia.earlyEnd = null; archive[archiveIndex].earlyEnd = null;
//Re-hydrate the item //Re-hydrate the item
const archivedMediaObject = archivedMedia.rehydrate(); const archivedMediaObject = archive[archiveIndex].rehydrate();
//if we still have a video to finish //if we still have a video to finish
if(archivedMediaObject.getEndTime() > now){ if(archivedMediaObject.getEndTime() > now){
//Set the fucker as now playing //Convert the fucker back to queuedMedia and save as now playing
chanDB.media.nowPlaying = archivedMediaObject; chanDB.media.nowPlaying = queuedMedia.fromArchivedMedia(archivedMediaObject);
//Schedule the fucker in RAM, w/ the start function also running in RAM-Only mode //Schedule the fucker in RAM, w/ the start function also running in RAM-Only mode
this.scheduleMedia([archivedMediaObject], null, chanDB, true, true, true); this.scheduleMedia([archivedMediaObject], null, chanDB, true, true, true);
//Splice the fucker out of the archive //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 //Break out of the loop

View file

@ -88,6 +88,27 @@ class queuedMedia extends media{
startTimeStamp); 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 * Converts array of media objects into array of queuedMedia objects
* @param {Array} mediaList - Array of media objects to queue * @param {Array} mediaList - Array of media objects to queue

View file

@ -22,7 +22,7 @@ const mediaSchema = require('./mediaSchema');
const archivedMedia = require('../../../app/channel/media/archivedMedia'); 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({ const archivedProperties = new mongoose.Schema({
channel: { channel: {