/*Canopy - The next generation of stoner streaming software Copyright (C) 2024-2025 Rainbownapkin and the TTN Community This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see .*/ //Local Imports const media = require('./media'); /** * Class extending media which represents a queued piece of media * @extends media */ class queuedMedia extends media{ /** * Creates a new queued media object * @param {Number} startTime - JS Epoch representing start time * @param {Number} startTimeStamp - Media start time stamp in seconds (relative to duration) * @param {Number} earlyEnd - Media end timestamp in seconds (relative to duration) * @param {String} uuid - Media object's unique identifier */ constructor(title, fileName, url, id, type, duration, rawLink, startTime, startTimeStamp = 0, earlyEnd, uuid){ //Call derived constructor super(title, fileName, url, id, type, duration, rawLink); /** * JS Epoch (millis) representing start time */ this.startTime = startTime; /** * Media start time stamp in seconds (relative to duration) */ this.startTimeStamp = startTimeStamp; /** * Media ent timestamp in seconds (relative to duration) */ this.earlyEnd = earlyEnd; /** * Media status type */ this.status = 'queued'; //If we have a null uuid (can't use default argument because of 'this') if(uuid == null){ //Generate id unique to this specific entry of this specific file within this specific channel's queue //That way even if we have six copies of the same video queued, we can still uniquely idenitify each instance this.genUUID(); }else{ /** * Media object's unique identifier */ this.uuid = uuid; } } //statics /** * Creates a queuedMedia object from a media object * @param {media} media - Media object to queue * @param {Number} startTime - Start time formatted as a JS Epoch * @param {Number} startTimeStamp - Start time stamp in seconds * @returns {queuedMedia} queuedMedia object created from given media object */ static fromMedia(media, startTime, startTimeStamp){ //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, startTime, startTimeStamp); } /** * Converts array of media objects into array of queuedMedia objects * @param {Array} mediaList - Array of media objects to queue * @param {Number} start - Start time formatted as JS Epoch * @returns Array of converted queued media objects */ static fromMediaArray(mediaList, start){ //Queued Media List const queuedMediaList = []; //Start Time Offset let startOffset = 0; for(let media of mediaList){ //Convert mediaObj to queuedMedia and push to the back of the list queuedMediaList.push(this.fromMedia(media, start + startOffset, 0)); //Set start offset to end of the current item startOffset += (media.duration * 1000) + 5; } return queuedMediaList; } //methods /** * Generates new unique identifier for queued media */ genUUID(){ this.uuid = crypto.randomUUID(); } /** * Generates a unique clone of a given media object * @returns unique clone of media object */ clone(){ return new queuedMedia( this.title, this.fileName, this.url, this.id, this.type, this.duration, this.rawLink, this.startTime, this.startTimeStamp, this.earlyEnd ); } /** * return the end time of a given queuedMedia object * @param {boolean} fullTime - Overrides early ends * @returns end time of given queuedMedia object */ getEndTime(fullTime = false){ //If we have an early ending if(this.earlyEnd == null || fullTime){ //Calculate our ending return this.startTime + ((this.duration - this.startTimeStamp) * 1000); }else{ //Return our early end return this.startTime + (this.earlyEnd * 1000); } } } module.exports = queuedMedia;