From a6bcbc1c7b3c0372194855df2b3f73028422b9a7 Mon Sep 17 00:00:00 2001 From: Violet Date: Sun, 29 Oct 2023 23:28:17 -0500 Subject: [PATCH] channels!!! --- index.js | 180 +++++++++++++++++++++++++++---------------- static/mainStyle.css | 15 ++++ 2 files changed, 130 insertions(+), 65 deletions(-) diff --git a/index.js b/index.js index 390a466..0c825ba 100644 --- a/index.js +++ b/index.js @@ -14,6 +14,7 @@ const cssPath = path.join(staticPath, 'mainStyle.css') const resources = path.join(__dirname, 'resources') const cachePath = path.join(__dirname, 'cache') +// const cachePath = "/tmp/cache/SimpleTube" const playerPath = path.join(resources, 'player.html') const searchPath = path.join(resources, 'searchPage.html') @@ -28,6 +29,7 @@ if (fs.existsSync(cachePath)) { fs.mkdirSync(cachePath) + var videoCache = {} var app = express() @@ -40,30 +42,97 @@ app.listen(PORT, () => { console.log("Simpletube is now listening on port: " + PORT) }) +function cacher(id, ready) { + console.log(id) + vidpath = path.join(__dirname, `cache/${id}.mp4`) + + var debounce = true + + var dp = 0 + var video = ytdl(id, { filter: 'videoandaudio', quality: "highest", format: 'mp4' }) + .on("progress", (chunk, ct, et) => { + + if (debounce && (ct / et) > 0.015) { + debounce = false + videoCache[id] = { + "path": vidpath, + "size": et, + "downloaded": false, + "download%": 0, + "lastUsed": new Date().getTime() + } + + ready(vidpath, fs.readFileSync(vidpath)) + } + var percent = Math.round(ct / et * 100) + if (!debounce && percent > dp && id in videoCache && "path" in videoCache[id]) { + dp = percent + videoCache[id]["download%"] = dp + } + }) + .on("finish", () => { + if (id in videoCache) { + videoCache[id]["downloaded"] = true + } + }) + return video +} + app.get("/search", async (req, res) => { var search = req.query.q || "How to search on SimpleTube" res.setHeader("Content-Type", "text/html") - youtube.search(search).then((results) => { + youtube.search(search, { type: "all" }).then((results) => { var videos = results.videos + var html = fs.readFileSync(searchPath).toString() - + html = html.replace("{SEARCH}", search) var addedHTML = "" + var channels = results.channels + + if (channels.length > 0) { + + addedHTML += "


Channels:

" + + for (let index = 0; index < channels.length; index++) { + const channel = channels[index] + addedHTML += ` +
+ +
+ ` + } + } + + addedHTML += "


Videos:

" + for (let index = 0; index < videos.length; index++) { const result = videos[index]; addedHTML += ` -
+
-
- - + -
- +
+

${result.title || "No Title Found"}

${result.description.substring(0, 75) + "..." || "No Description"}

@@ -71,7 +140,7 @@ app.get("/search", async (req, res) => { @@ -79,13 +148,12 @@ app.get("/search", async (req, res) => {
` } - + res.send(html.replace("{RESULTS}", addedHTML)) }) }) app.get("/video", async (req, res) => { - var id = req.query.q || req.query.v var range = req.headers.range @@ -106,64 +174,46 @@ app.get("/video", async (req, res) => { if (range) { function ready(vidpath) { - const fileSize = videoCache[id].size - // const fileSize = fs.statSync(vidpath).size + 1 - const parts = range.replace(/bytes=/, "").split("-") - const start = parseInt(parts[0], 10) - const end = parts[1] - ? parseInt(parts[1], 10) - : fileSize - 1 - - if (start >= fs.statSync(vidpath).size + 1) { - console.log("AAAAAAAAA") - res.status(416).send('Requested range not satisfiable\n' + start + ' >= ' + fileSize); - return + if (fs.existsSync(vidpath)) { + const fileSize = videoCache[id].size + const parts = range.replace(/bytes=/, "").split("-") + const start = parseInt(parts[0], 10) + const end = parts[1] + ? parseInt(parts[1], 10) + : fileSize - 1 + + if (start >= fs.statSync(vidpath).size + 1) { + return + } + + const chunksize = (end - start) + 1 + + const head = { + 'Content-Range': `bytes ${start}-${end}/${fileSize}`, + 'Accept-Ranges': 'bytes', + 'Content-Length': chunksize, + 'Content-Type': 'video/mp4', + } + + res.writeHead(206, head) + + if (fs.existsSync(vidpath)) { + fs.createReadStream(vidpath, { start: start }).pipe(res) + } } - - const chunksize = (end - start) + 1 - - const head = { - 'Content-Range': `bytes ${start}-${end}/${fileSize}`, - 'Accept-Ranges': 'bytes', - 'Content-Length': chunksize, - 'Content-Type': 'video/mp4', - } - - res.writeHead(206, head) - - fs.createReadStream(vidpath, { start: start }).pipe(res) } + console.log(videoCache) + if (id in videoCache) { - ready(videoCache[id].path) + if ("path" in videoCache[id]) { + ready(videoCache[id].path) + videoCache[id].lastUsed = new Date().getTime() + } } else { - vidpath = path.join(__dirname, `cache/${id}.mp4`) - - var debounce = true - - var dp = 0 - ytdl(id, { filter: 'videoandaudio', quality: "highest", format: 'mp4' }) - .on("progress", (chunk, ct, et) => { - if (debounce && (ct / et) > 0.05) { - debounce = false - videoCache[id] = { - "path": vidpath, - "size": et, - "downloaded": false, - "download%": 0 - } - ready(vidpath, fs.readFileSync(vidpath)) - } - var percent = Math.round(ct / et * 100) - if (!debounce && percent > dp) { - dp = percent - videoCache[id]["download%"] = dp - } - }) - .on("finish", () => { - videoCache[id]["downloaded"] = true - }) - .pipe(fs.createWriteStream(vidpath)) + videoCache[id] = [] + var video = cacher(id, ready) + video.pipe(fs.createWriteStream(vidpath)) } @@ -204,7 +254,7 @@ app.get("/watch", async (req, res) => { for (let index = 0; index < 2; index++) { html = html.replace("{VIDEO_TITLE}", vidInfo.title) - + } html = html.replace("{VIDEO_DESCRIPTION}", vidInfo.description || "No Description.") diff --git a/static/mainStyle.css b/static/mainStyle.css index 13e838e..b65d17b 100644 --- a/static/mainStyle.css +++ b/static/mainStyle.css @@ -164,4 +164,19 @@ p { padding: 0; margin: 0; display: inline-block; +} + +main { + padding: 10px; +} + +.pfp { + width: 100%; + border-radius: 50%; + border: white 2px solid; + margin: 15px auto; +} + +hr { + margin: 20px auto; } \ No newline at end of file