Video resolver and cache working

This commit is contained in:
Ben Kyd
2020-06-18 02:13:54 +00:00
parent 88fa7a0d93
commit 55df78ff94
4 changed files with 122 additions and 10 deletions

View File

@@ -19,4 +19,4 @@ VideoInput.oninput = () =>
Socket.on('VideoListResolution', (req) => console.log(req));
Socket.on('VideoListResolved')
Socket.on('VideoListResolved', (req) => console.log(req));

View File

@@ -1,13 +1,16 @@
const Logger = require('./logger');
module.exports.Configuration = {}
module.exports.Load = () =>
{
module.exports.Configuration = {
this.Configuration = {
LogFile: 'logs.log',
ListenPort: 8080,
PublicDirectory: 'public',
StorageDirectory: './tmp/',
CacheCleanInterval: 2
CacheCleanInterval: 30000, // 5 mins
CacheTimeToUse: 60000, // 10 mins
}
Logger.Log('Configuration loaded');
}

View File

@@ -1,6 +1,9 @@
const Logger = require('./logger')
const Config = require('./config');
const YoutubeHelper = require('./youtubehelper');
const YoutubeDownloader = require('./youtubedownloader');
const express = require('express');
let app;
@@ -74,15 +77,17 @@ async function VideoListUpdate(socket, req)
let ResolveQueue = [];
Res.Error = false;
Res.Content = [];
for (video of VideoArray)
{
if (YoutubeRegex.exec(video))
{
let VideoID = video.match(YoutubeRegex)[5];
// generate ID lol
ResolveQueue.push(video);
ResolveQueue.push(VideoID);
Res.Content.push({
id: 1,
id: VideoID,
url: video,
valid: true,
action: 'Resolving'
@@ -100,7 +105,17 @@ async function VideoListUpdate(socket, req)
socket.emit('VideoListResolution', Res);
if (ResolveQueue.length == 0)
return;
const Resolution = await YoutubeHelper.GetVideoInfoArr(ResolveQueue);
const ResolutionRes = {
Error: false,
Content: Resolution
};
socket.emit('VideoListResolved', ResolutionRes);
}

View File

@@ -1,30 +1,124 @@
const Config = require('./config');
const Logger = require('./logger');
const YTDL = require('ytdl-core');
// TODO: does the video resolver need a queue?
// cache
let ResolutionCache = [];
function CheckCache()
function HitCache(id)
{
if (ResolutionCache[id])
{
Logger.Log(`Cache hit! ${id}`)
ResolutionCache[id].LastUsed = Date.now();
return ResolutionCache[id].Video;
} else
{
return false;
}
}
function RegisterCache(video)
{
ResolutionCache[video.player_response.videoDetails.videoId] = {
Id: video.player_response.videoDetails.videoId,
Video: video,
LastUsed: Date.now(),
TimeCreated: Date.now()
}
}
function CleanCache()
{
// TODO: fix weird bug where a cleaned
// entry's timeused lingers
let ExpiredEntrys = [];
for (id in ResolutionCache)
{
entry = ResolutionCache[id];
// if cache entry has expired
const LastUsed = Date.now() - entry.LastUsed;
if (LastUsed > Config.Configuration.CacheTimeToUse)
{
// remove expired entry
Logger.Log(`Cache entry '${id}' expired`);
ExpiredEntrys.push(id);
delete entry;
}
}
for (expiredEntry of ExpiredEntrys)
{
delete ResolutionCache[expiredEntry];
}
}
module.exports.InitResolverCache = async () =>
{
setInterval(CleanCache, Config.Configuration.CacheCleanInterval);
Logger.Log('Video resolver cache settup')
}
module.exports.GetVideoInfoArr = async (arr) =>
{
let ret = [];
// TODO: make async AND retain order
for (video of arr)
{
ret.push(await this.GetVideoInfo(video));
}
return ret;
}
module.exports.GetVideoInfo = async (video) =>
{
try
{
const CacheHit = HitCache(video);
let Video = {};
if (CacheHit)
{
Video = CacheHit
} else
{
// TODO: is the YouTube API faster for this?
Logger.Log(`Resolving '${video}'`)
Video = await YTDL.getInfo(video);
// register the info into the cache
RegisterCache(Video);
}
let Res = BuildBasicInfoFromInfo(Video);
return Res;
} catch (e)
{
Logger.Log(`Error resolving video '${video}', ${e}`);
return { Error: "Video cannot resolve" };
}
}
function BuildBasicInfoFromInfo(info)
{
let ret = {};
ret.id = info.player_response.videoDetails.videoId;
ret.title = info.player_response.videoDetails.title;
ret.desc = info.player_response.videoDetails.shortDescription;
ret.views = info.player_response.videoDetails.viewCount;
if (!info.player_response.videoDetails.thumbnail.thumbnails[0])
{
ret.thumbnail = info.player_response.videoDetails.thumbnail.thumbnails[1].url;
} else
{
ret.thumbnail = info.player_response.videoDetails.thumbnail.thumbnails[0].url;
}
ret.channel = info.player_response.videoDetails.author;
ret.runtime = info.player_response.videoDetails.lengthSeconds;
return ret;
}