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 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.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(directory, 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!") + "

404: not found!

" + baseEnd) return } res.write(baseStart.replace("{TITLE}", '/' + file)) res.write(`

${dirContents.length} Files

`) if (file != '') { res.write('Parent Directory
') } var dirs = [] var ogFolder = file for (let index = 0; index < dirContents.length; index++) { const file = dirContents[index]; var userPath = path.join(ogFolder, file) var fileStats = fs.statSync(path.join(absPath, file)) if (!fileStats.isDirectory()) { var fileExtension = file.substring(file.lastIndexOf('.') + 1, ) if (videoFormats.includes(fileExtension)) { res.write(`
  • ${file} | ${humanFileSize(fileStats.size)}
  • `) } else { res.write(`
  • ${file} | ${humanFileSize(fileStats.size)}
  • `) } } else { dirs.push(file) } } for (let index = 0; index < dirs.length; index++) { const file = dirs[index]; var fileStats = fs.statSync(path.join(absPath, file)) res.write(`
  • ./${file}/
  • `) } // res.write(`./${file}/
    `) res.write(baseEnd) res.end() }) process.on('uncaughtException', (err, origin) => { fs.writeSync( process.stderr.fd, `Caught exception: ${err}\n` + `Exception origin: ${origin}`, ); });