const express = require("express"), fs = require("fs"), path = require("path") var app = express() var PORT = process.env.PORT || 8080 var directory = process.env.FILES_DIR var pubDir = path.join(directory, 'public') function humanFileSize(bytes, si = false, dp = 1) { const thresh = si ? 1000 : 1024; if (Math.abs(bytes) < thresh) { return bytes + ' B'; } const units = si ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; let u = -1; const r = 10 ** dp; do { bytes /= thresh; ++u; } while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1); return bytes.toFixed(dp) + ' ' + units[u]; } if (!directory) { console.error("No directory specified! Please specify one using the environment variable FILES_DIR.") return } const videoFormats = ["mp4", "mkv"] app.use(express.static(directory)) app.use(express.static(pubDir)) app.listen(PORT, () => { console.log("Now listening on PORT: " + PORT) }) app.get("/watch/*", (req, res) => { res.setHeader("Content-Type", "text/html") var video = req.params[0] var absPath = path.join(directory, video) var html = fs.readFileSync(path.join(__dirname, 'resources/watch.html')).toString() html = html.replaceAll("{VID_PATH}", video) var vidTitle = video.substring(video.lastIndexOf('/') + 1, video.lastIndexOf('.')) var vidStats = fs.statSync(absPath) html = html.replaceAll("{TITLE}", vidTitle) html = html.replaceAll("{VID_INFO}", `Size: ${humanFileSize(vidStats.size)}`) html = html.replaceAll("{BACK}", "/" + video.substring(0, video.lastIndexOf("/"))) res.send(html) }) app.get("/video/*", (req, res) => { var video = req.params[0] var vidPath = path.join(directory, video) const range = req.headers.range const videoPath = vidPath; const videoSize = fs.statSync(videoPath).size const chunkSize = 1 * 1e6; const start = Number(range.replace(/\D/g, "")) const end = Math.min(start + chunkSize, videoSize - 1) const contentLength = end - start + 1; const headers = { "Content-Range": `bytes ${start}-${end}/${videoSize}`, "Accept-Ranges": "bytes", "Content-Length": contentLength, "Content-Type": "video/mkv" } res.writeHead(206, headers) const stream = fs.createReadStream(videoPath, { start, end }) stream.pipe(res) }) app.get("/*", (req, res) => { var file = req.params[0] var absPath = path.join(pubDir, file) if (file != '') { var baseHTML = fs.readFileSync(path.join(__dirname, 'resources/base.html')).toString() } else { var baseHTML = fs.readFileSync(path.join(__dirname, 'resources/root.html')).toString() } var baseStart = baseHTML.substring(0, baseHTML.indexOf('{CONTENT}')) var baseEnd = baseHTML.substring(baseHTML.indexOf('{CONTENT}') + 9, baseHTML.length) res.setHeader('Content-Type', 'text/html') res.setHeader("X-Accel-Buffering", "no") try { var dirContents = fs.readdirSync(absPath) var dirStats = fs.statSync(absPath) } catch (error) { res.send(baseStart.replace("{TITLE}", "404: not found!") + "