Youtube videos now refresh metadata 10 seconds before playback starts.
This commit is contained in:
parent
a71f1d6cc0
commit
60cd21d938
|
|
@ -42,6 +42,8 @@ module.exports = class{
|
|||
this.syncTimer = null;
|
||||
//Create variable to hold next playing item timer
|
||||
this.nextTimer = null;
|
||||
//Create vairable to hold pre-switch timer
|
||||
this.preSwitchTimer = null;
|
||||
//Create variable to hold currently playing media object
|
||||
this.nowPlaying = null;
|
||||
|
||||
|
|
@ -97,12 +99,12 @@ module.exports = class{
|
|||
//Set title
|
||||
const title = validator.escape(validator.trim(data.title));
|
||||
|
||||
//set start
|
||||
let start = this.getStart(data.start);
|
||||
|
||||
//Pull media list
|
||||
const mediaList = await yanker.yankMedia(url, title);
|
||||
|
||||
//set start
|
||||
let start = this.getStart(data.start);
|
||||
|
||||
//If we didn't find any media
|
||||
if(mediaList == null || mediaList.length <= 0){
|
||||
//Bitch, moan, complain...
|
||||
|
|
@ -286,6 +288,7 @@ module.exports = class{
|
|||
|
||||
//Clear out any stale timers to prevent ghost queueing
|
||||
clearTimeout(this.nextTimer);
|
||||
clearTimeout(this.preSwitchTimer);
|
||||
|
||||
//If we have a current item and it isn't currently playing
|
||||
if(currentItem != null && (this.nowPlaying == null || currentItem.uuid != this.nowPlaying.uuid)){
|
||||
|
|
@ -293,8 +296,23 @@ module.exports = class{
|
|||
this.start(currentItem, Math.round((new Date().getTime() - currentItem.startTime) / 1000) + currentItem.startTimeStamp, volatile);
|
||||
//If we have a next item
|
||||
}else if(nextItem != null){
|
||||
//Get current time as epoch
|
||||
const now = new Date().getTime();
|
||||
//Calculate the amount of time in ms that the next item will start in
|
||||
const startsIn = nextItem.startTime - new Date().getTime();
|
||||
const startsIn = nextItem.startTime - now;
|
||||
//Delay between pre-switch function call and start of media
|
||||
//This should be enough time to do things like pre-fetch updated raw links from youtube
|
||||
const preSwitchDelta = 10 * 1000;
|
||||
//Calculate when the pre-switch timer would be called
|
||||
const preSwitchTime = nextItem.startTime - preSwitchDelta;
|
||||
//Calculate how long the pre-switch timer will be called in
|
||||
const preSwitchIn = preSwitchTime - now;
|
||||
|
||||
//If we have enough time to call the pre-switch timer
|
||||
if(preSwitchIn > preSwitchDelta){
|
||||
//Set the pre-switch timer
|
||||
this.preSwitchTimer = setTimeout(()=>{this.preSwitch(nextItem)}, preSwitchIn);
|
||||
}
|
||||
|
||||
//Set the next timer
|
||||
this.nextTimer = setTimeout(()=>{this.start(nextItem, nextItem.startTimeStamp, volatile)}, startsIn);
|
||||
|
|
@ -655,6 +673,17 @@ module.exports = class{
|
|||
return true;
|
||||
}
|
||||
|
||||
async preSwitch(mediaObj){
|
||||
//Check if media needs a new raw link and update if it does
|
||||
if(await yanker.refreshRawLink(mediaObj)){
|
||||
//If the fetch took so god damned long we've already started the video (isn't 10 seconds enough?)
|
||||
if(this.nowPlaying != null && this.nowPlaying.uuid == mediaObj.uuid){
|
||||
//Tell the clients to update the raw file for the current item fore.st-style, as it probably got sent out with a stale link
|
||||
this.server.io.in(this.channel.name).emit("updateCurrentRawFile", {file: mediaObj.rawLink});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async start(mediaObj, timestamp = mediaObj.startTimeStamp, volatile = false){
|
||||
//If something is already playing
|
||||
if(this.nowPlaying != null){
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ queuedProperties.methods.rehydrate = function(){
|
|||
this.type,
|
||||
this.duration,
|
||||
//We don't save raw links that are stored seperate from the standard URL as they tend to expire.
|
||||
null,
|
||||
undefined,
|
||||
this.startTime,
|
||||
this.startTimeStamp,
|
||||
this.earlyEnd,
|
||||
|
|
|
|||
|
|
@ -38,6 +38,22 @@ module.exports.yankMedia = async function(url, title){
|
|||
}
|
||||
}
|
||||
|
||||
module.exports.refreshRawLink = async function(mediaObj){
|
||||
switch(mediaObj.type){
|
||||
case 'yt':
|
||||
//Re-fetch media metadata
|
||||
metadata = await ytdlpUtil.fetchYoutubeVideoMetadata(mediaObj.id);
|
||||
//Refresh media rawlink from metadata
|
||||
mediaObj.rawLink = metadata[0].rawLink;
|
||||
|
||||
//return media object
|
||||
return mediaObj;
|
||||
}
|
||||
|
||||
//Return null to tell the calling function there is no refresh required for this media type
|
||||
return null;
|
||||
}
|
||||
|
||||
//I'd be lying if this didn't take at least some inspiration/regex patterns from extractQueryParam() in cytube/forest's browser-side 'util.js'
|
||||
//Still this has some improvements like url pre-checks and the fact that it's handled serverside, recuing possibility of bad requests.
|
||||
//Some of the regex expressions for certain services have also been improved, such as youtube, and the fore.st-unique archive.org
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ class player{
|
|||
this.client.socket.on("start", this.start.bind(this));
|
||||
this.client.socket.on("sync", this.sync.bind(this));
|
||||
this.client.socket.on("end", this.end.bind(this));
|
||||
this.client.socket.on("updateCurrentRawFile", this.updateCurrentRawFile.bind(this));
|
||||
}
|
||||
|
||||
start(data){
|
||||
|
|
@ -144,6 +145,17 @@ class player{
|
|||
this.lockSync();
|
||||
}
|
||||
|
||||
updateCurrentRawFile(data){
|
||||
//Grab current item from media handler
|
||||
const currentItem = this.mediaHandler.nowPlaying;
|
||||
|
||||
//Update raw link
|
||||
currentItem.rawLink = data.file;
|
||||
|
||||
//Re-start the item
|
||||
this.start({media: currentItem});
|
||||
}
|
||||
|
||||
lockSync(){
|
||||
//Enable syncing
|
||||
this.syncLock = true;
|
||||
|
|
|
|||
Loading…
Reference in a new issue