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;
|
this.syncTimer = null;
|
||||||
//Create variable to hold next playing item timer
|
//Create variable to hold next playing item timer
|
||||||
this.nextTimer = null;
|
this.nextTimer = null;
|
||||||
|
//Create vairable to hold pre-switch timer
|
||||||
|
this.preSwitchTimer = null;
|
||||||
//Create variable to hold currently playing media object
|
//Create variable to hold currently playing media object
|
||||||
this.nowPlaying = null;
|
this.nowPlaying = null;
|
||||||
|
|
||||||
|
|
@ -97,12 +99,12 @@ module.exports = class{
|
||||||
//Set title
|
//Set title
|
||||||
const title = validator.escape(validator.trim(data.title));
|
const title = validator.escape(validator.trim(data.title));
|
||||||
|
|
||||||
//set start
|
|
||||||
let start = this.getStart(data.start);
|
|
||||||
|
|
||||||
//Pull media list
|
//Pull media list
|
||||||
const mediaList = await yanker.yankMedia(url, title);
|
const mediaList = await yanker.yankMedia(url, title);
|
||||||
|
|
||||||
|
//set start
|
||||||
|
let start = this.getStart(data.start);
|
||||||
|
|
||||||
//If we didn't find any media
|
//If we didn't find any media
|
||||||
if(mediaList == null || mediaList.length <= 0){
|
if(mediaList == null || mediaList.length <= 0){
|
||||||
//Bitch, moan, complain...
|
//Bitch, moan, complain...
|
||||||
|
|
@ -286,6 +288,7 @@ module.exports = class{
|
||||||
|
|
||||||
//Clear out any stale timers to prevent ghost queueing
|
//Clear out any stale timers to prevent ghost queueing
|
||||||
clearTimeout(this.nextTimer);
|
clearTimeout(this.nextTimer);
|
||||||
|
clearTimeout(this.preSwitchTimer);
|
||||||
|
|
||||||
//If we have a current item and it isn't currently playing
|
//If we have a current item and it isn't currently playing
|
||||||
if(currentItem != null && (this.nowPlaying == null || currentItem.uuid != this.nowPlaying.uuid)){
|
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);
|
this.start(currentItem, Math.round((new Date().getTime() - currentItem.startTime) / 1000) + currentItem.startTimeStamp, volatile);
|
||||||
//If we have a next item
|
//If we have a next item
|
||||||
}else if(nextItem != null){
|
}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
|
//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
|
//Set the next timer
|
||||||
this.nextTimer = setTimeout(()=>{this.start(nextItem, nextItem.startTimeStamp, volatile)}, startsIn);
|
this.nextTimer = setTimeout(()=>{this.start(nextItem, nextItem.startTimeStamp, volatile)}, startsIn);
|
||||||
|
|
@ -655,6 +673,17 @@ module.exports = class{
|
||||||
return true;
|
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){
|
async start(mediaObj, timestamp = mediaObj.startTimeStamp, volatile = false){
|
||||||
//If something is already playing
|
//If something is already playing
|
||||||
if(this.nowPlaying != null){
|
if(this.nowPlaying != null){
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ queuedProperties.methods.rehydrate = function(){
|
||||||
this.type,
|
this.type,
|
||||||
this.duration,
|
this.duration,
|
||||||
//We don't save raw links that are stored seperate from the standard URL as they tend to expire.
|
//We don't save raw links that are stored seperate from the standard URL as they tend to expire.
|
||||||
null,
|
undefined,
|
||||||
this.startTime,
|
this.startTime,
|
||||||
this.startTimeStamp,
|
this.startTimeStamp,
|
||||||
this.earlyEnd,
|
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'
|
//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.
|
//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
|
//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("start", this.start.bind(this));
|
||||||
this.client.socket.on("sync", this.sync.bind(this));
|
this.client.socket.on("sync", this.sync.bind(this));
|
||||||
this.client.socket.on("end", this.end.bind(this));
|
this.client.socket.on("end", this.end.bind(this));
|
||||||
|
this.client.socket.on("updateCurrentRawFile", this.updateCurrentRawFile.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
start(data){
|
start(data){
|
||||||
|
|
@ -144,6 +145,17 @@ class player{
|
||||||
this.lockSync();
|
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(){
|
lockSync(){
|
||||||
//Enable syncing
|
//Enable syncing
|
||||||
this.syncLock = true;
|
this.syncLock = true;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue