2025-10-11 13:52:03 -05:00

76 lines
2.7 KiB
JavaScript

import Express from "express";
import busboy from "connect-busboy";
import path from "path";
import fs from "node:fs";
import { exec } from "node:child_process";
import util from "node:util";
import * as Minio from "minio";
//#region src/index.ts
const execPromise = util.promisify(exec);
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = "0";
const minioClient = new Minio.Client({
endPoint: "garage-ikea.jdf2.org.local",
region: "garage",
useSSL: false,
accessKey: "GK35dcc0e32a7954e2ee725582",
secretKey: "0017fab8d149ee7215e1b3cecf6c3b13eb8acb8132db4b4042dacdf2801ab48f"
});
let currentlyExecFfmpeg = false;
const workingDir = "/opt/prod/storage";
const app = Express();
app.use(busboy());
app.use(Express.json());
app.post("/uploadVideo", async (req, res) => {
try {
console.log("Starting upload");
const videoId = req.query.videoId;
req.busboy.on("file", (fieldname, uploadingFile, fileInfo) => {
if (currentlyExecFfmpeg) {
console.log("Waiting");
res.send({
status: "wait",
statusMessage: "FFmpeg is currently processing another file. Please wait."
});
res.end();
return;
}
console.log(`Saving ${fileInfo.filename} as ${videoId}`);
const videoExt = fileInfo.filename.split(".").at(-1);
var targetPath = path.join(`${workingDir}/uploadsPart1`, `${videoId}.${videoExt}`);
const formattedPath = `${workingDir}/uploadsPart2/${videoId}-formatted.mp4`;
const fileStream = fs.createWriteStream(targetPath);
uploadingFile.pipe(fileStream);
fileStream.on("close", () => {
console.log(`Completed upload ${videoId}`);
const ffmpegCommand = `ffmpeg -y -loglevel error -i "${targetPath}" -c:v libx264 -crf 23 -preset medium -movflags +faststart -c:a aac -b:a 128k ${formattedPath}`;
currentlyExecFfmpeg = true;
execPromise(ffmpegCommand).then(async ({ stdout, stderr }) => {
if (stderr && stderr.length > 0) console.log("FFmpeg stderr:", stderr);
await minioClient.fPutObject("videos-garage", videoId, formattedPath);
console.log(`Size - Old: ${fs.statSync(targetPath).size / (1024 * 1024)} New: ${fs.statSync(formattedPath).size / (1024 * 1024)}`);
fs.unlinkSync(targetPath);
fs.unlinkSync(formattedPath);
console.log(await minioClient.presignedGetObject("videos-garage", videoId, 24 * 60 * 60));
console.log("");
}).catch((error) => {
console.log("FFmpeg caught error:", error);
}).finally(() => {
console.log(`Completed processing ${fileInfo.filename}`);
fs.unlinkSync(targetPath);
currentlyExecFfmpeg = false;
});
res.send({
status: "good",
statusMessage: "Upload part 1 complete"
});
});
});
req.pipe(req.busboy);
} catch (err) {
res.status(500).send(err);
}
});
app.listen(3001);
//#endregion