Listen for file changes and update progress continuously
This commit is contained in:
parent
a9b0c2a602
commit
cd124f916e
106
index.js
106
index.js
@ -8,6 +8,9 @@ import levenshtein from "js-levenshtein";
|
||||
import cookieParser from "cookie-parser";
|
||||
import { fileURLToPath } from "url";
|
||||
import sqlite3 from "sqlite3";
|
||||
import fs from "fs/promises";
|
||||
|
||||
const PORT = 8000;
|
||||
|
||||
let sessions = [];
|
||||
let videoQueue = [];
|
||||
@ -59,6 +62,35 @@ function dirname() {
|
||||
return path.dirname(fileURLToPath(import.meta.url));
|
||||
}
|
||||
|
||||
function authorized() {
|
||||
return async (req, res, next) => {
|
||||
const token = (() => {
|
||||
if (req.cookies && "token" in req.cookies) {
|
||||
return req.cookies["token"];
|
||||
} else if ("token" in req.query) {
|
||||
return req.query["token"];
|
||||
} else if (req.method === "post" && "token" in req.body) {
|
||||
return req.body["token"];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
if (token === null) {
|
||||
return res.status(400).json({ ok: false, error: "unauthorized" });
|
||||
}
|
||||
const session = sessions.find(session => session.token === token);
|
||||
if (session === undefined) {
|
||||
return res.status(400).json({ ok: false, error: "unauthorized" });
|
||||
}
|
||||
const user = await dbGet("SELECT * FROM users WHERE id = ?", session.userId);
|
||||
if (user === undefined) {
|
||||
throw new Error("error: session with invalid userId");
|
||||
}
|
||||
req.user = user;
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
const app = express();
|
||||
app.use(cors());
|
||||
app.use(express.json());
|
||||
@ -142,35 +174,6 @@ app.get("/api/search", async (req, res) => {
|
||||
return res.status(200).json({ ok: true, videos, total });
|
||||
});
|
||||
|
||||
function authorized() {
|
||||
return async (req, res, next) => {
|
||||
const token = (() => {
|
||||
if (req.cookies && "token" in req.cookies) {
|
||||
return req.cookies["token"];
|
||||
} else if ("token" in req.query) {
|
||||
return req.query["token"];
|
||||
} else if (req.method === "post" && "token" in req.body) {
|
||||
return req.body["token"];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
})();
|
||||
if (token === null) {
|
||||
return res.status(400).json({ ok: false, error: "unauthorized" });
|
||||
}
|
||||
const session = sessions.find(session => session.token === token);
|
||||
if (session === undefined) {
|
||||
return res.status(400).json({ ok: false, error: "unauthorized" });
|
||||
}
|
||||
const user = await dbGet("SELECT * FROM users WHERE id = ?", session.userId);
|
||||
if (user === undefined) {
|
||||
throw new Error("error: session with invalid userId");
|
||||
}
|
||||
req.user = user;
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
app.get("/api/logout", authorized(), (req, res) => {
|
||||
sessions = sessions.filter(session => session.userId !== req.user.id);
|
||||
return res.status(200).json({ ok: true });
|
||||
@ -198,7 +201,7 @@ app.post("/api/upload-video", authorized(), fileUpload({ limits: { fileSize: 2 *
|
||||
return res.status(400).json({ ok: false, error: "invalid video file" });
|
||||
}
|
||||
|
||||
const duration = parseFloat(durationResult.data.match(/duration=([.\d]+)/)[1]);
|
||||
const duration = parseFloat(durationResult.data.match(/duration=([.\d]+)/)[1]) * 1_000_000;;
|
||||
|
||||
const queueItem = {
|
||||
videoId: id,
|
||||
@ -210,7 +213,8 @@ app.post("/api/upload-video", authorized(), fileUpload({ limits: { fileSize: 2 *
|
||||
|
||||
videoQueue.push(queueItem);
|
||||
|
||||
const uploadProcess = childProcess.spawn("ffmpeg", ["-i", tempPath, "-b:v", "1M", "-b:a", "192k", "-loglevel", "error", newPath]);
|
||||
const progressPath = path.join(dirname(), "tmp", "progress", `${id}.txt`)
|
||||
const uploadProcess = childProcess.spawn("ffmpeg", ["-i", tempPath, "-b:v", "1M", "-b:a", "192k", "-progress", progressPath, "-loglevel", "error", newPath]);
|
||||
const thumbnailProcess = childProcess.spawn("ffmpeg", ["-i", tempPath, "-ss", "00:00:01.000", "-vframes", "1", "-loglevel", "error", thumbnailPath]);
|
||||
|
||||
uploadProcess.stderr.on("data", data => queueItem.errors.push(data.toString()));
|
||||
@ -263,6 +267,42 @@ app.use((err, req, res, next) => {
|
||||
res.status(500).json({ ok: false, error: "server error" })
|
||||
});
|
||||
|
||||
app.listen(8000, () => {
|
||||
async function main() {
|
||||
(async () => {
|
||||
const progressPath = path.join(dirname(), "tmp", "progress");
|
||||
|
||||
await fs.mkdir(progressPath, { recursive: true });
|
||||
|
||||
const watch = fs.watch(progressPath, { recursive: true });
|
||||
|
||||
for await (const event of watch) {
|
||||
const videoId = event.filename.replace(".txt", "");
|
||||
const queueItem = videoQueue.find(item => item.videoId === videoId);
|
||||
|
||||
if (!queueItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fs.readFile(path.join(progressPath, event.filename), "utf-8")
|
||||
.then(string => {
|
||||
const index = string.lastIndexOf("out_time_ms=");
|
||||
if (index === -1) return;
|
||||
|
||||
const length = parseInt(string.slice(index).match(/out_time_ms=(\d+)/)[1]);
|
||||
|
||||
for (const i in videoQueue) {
|
||||
if (videoQueue[i].videoId !== videoId) continue;
|
||||
|
||||
videoQueue[i].progress = length;
|
||||
}
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log("app at http://localhost:8000/");
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
main();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user