const fs = require("fs"); const path = require("path"); const videoAccessLog = new Map(); const CACHE_TIMEOUT = 10 * 60 * 1000; function createCacheManager() { setInterval(cleanupUnusedVideos, 5 * 60 * 1000); setTimeout(cleanupUnusedVideos, 30 * 1000); scanExistingVideos(); console.log( `Video caching ${ process.env.ENABLE_CACHING === "true" ? "enabled" : "disabled" }` ); return function cacheMiddleware(req, res, next) { if (req.path.startsWith("/videocd/")) { const pathParts = req.path.split("/").filter(Boolean); if (pathParts.length >= 2) { const videoId = pathParts[1]; videoAccessLog.set(videoId, Date.now()); console.log(`Video ${videoId} accessed at ${new Date().toISOString()}`); } } next(); }; } function scanExistingVideos() { const videoHostDir = path.join(process.cwd(), "videohost"); if (!fs.existsSync(videoHostDir)) { console.log("Video directory does not exist yet"); return; } try { const videoDirs = fs.readdirSync(videoHostDir); const now = Date.now(); for (const videoId of videoDirs) { const videoDir = path.join(videoHostDir, videoId); try { if (fs.statSync(videoDir).isDirectory()) { videoAccessLog.set(videoId, now); } } catch (err) { console.error(`Error checking directory ${videoId}: ${err.message}`); } } console.log( `Found and tracking ${videoAccessLog.size} existing video directories` ); } catch (err) { console.error(`Error scanning video directory: ${err.message}`); } } function cleanupUnusedVideos() { const isCachingEnabled = process.env.ENABLE_CACHING === "true"; if (isCachingEnabled) { console.log("Video caching is enabled, skipping cleanup"); return; } console.log("Running video cache cleanup check"); const now = Date.now(); const videoHostDir = path.join(process.cwd(), "videohost"); if (!fs.existsSync(videoHostDir)) { console.log("Video directory does not exist, nothing to clean up"); return; } try { const videoDirs = fs.readdirSync(videoHostDir); for (const videoId of videoDirs) { const lastAccess = videoAccessLog.get(videoId) || 0; const timeSinceAccess = now - lastAccess; if (timeSinceAccess > CACHE_TIMEOUT) { const videoDir = path.join(videoHostDir, videoId); try { if (fs.statSync(videoDir).isDirectory()) { console.log( `Removing unused video directory: ${videoId} (last accessed ${Math.floor( timeSinceAccess / 60000 )} minutes ago)` ); fs.rmSync(videoDir, { recursive: true, force: true }); videoAccessLog.delete(videoId); } } catch (err) { console.error(`Error deleting directory ${videoId}: ${err.message}`); } } } } catch (err) { console.error(`Error during video cache cleanup: ${err.message}`); } } module.exports = createCacheManager;