diff --git a/ffmpegQueuePipe.sh b/ffmpegQueuePipe.sh index de01fb9..b55d0e7 100644 --- a/ffmpegQueuePipe.sh +++ b/ffmpegQueuePipe.sh @@ -8,12 +8,7 @@ trap "rm -f $pipe" EXIT [[ -p $pipe ]] || mkfifo $pipe while true; do - # can't just use "while read line" if we - # want this script to continue running. read line <$pipe - # now implementing a bit of security, - # feel free to improve it. - # we ensure that the command is a ffmpeg one. bash <<<"$line" done diff --git a/package.json b/package.json index 7e45729..ceccd22 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "tsdown": "latest" }, "dependencies": { + "@types/node": "^24.0.15", "connect-busboy": "^1.0.0", "express": "^5.1.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 342fd69..fe82b69 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + '@types/node': + specifier: ^24.0.15 + version: 24.0.15 connect-busboy: specifier: ^1.0.0 version: 1.0.0 @@ -149,6 +152,9 @@ packages: '@tybys/wasm-util@0.9.0': resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==} + '@types/node@24.0.15': + resolution: {integrity: sha512-oaeTSbCef7U/z7rDeJA138xpG3NuKc64/rZ2qmUFkFJmnMsAPaluIifqyWd8hSSMxyP9oie3dLAqYPblag9KgA==} + accepts@2.0.0: resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} engines: {node: '>= 0.6'} @@ -551,6 +557,9 @@ packages: unconfig@7.3.2: resolution: {integrity: sha512-nqG5NNL2wFVGZ0NA/aCFw0oJ2pxSf1lwg4Z5ill8wd7K4KX/rQbHlwbh+bjctXL5Ly1xtzHenHGOK0b+lG6JVg==} + undici-types@7.8.0: + resolution: {integrity: sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -678,6 +687,10 @@ snapshots: tslib: 2.8.1 optional: true + '@types/node@24.0.15': + dependencies: + undici-types: 7.8.0 + accepts@2.0.0: dependencies: mime-types: 3.0.1 @@ -1101,6 +1114,8 @@ snapshots: jiti: 2.4.2 quansync: 0.2.10 + undici-types@7.8.0: {} + unpipe@1.0.0: {} vary@1.1.2: {} diff --git a/src/index.ts b/src/index.ts index 2110654..498884f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,17 @@ import Express from "express"; import busboy from "connect-busboy"; import path from "path"; -import fs from "fs"; +import fs from "node:fs"; +import { exec } from "node:child_process"; +import util from "node:util"; +const execPromise = util.promisify(exec); + +let currentlyExecFfmpeg = false; const app = Express(); app.use(busboy()); app.use(Express.json()); - +//https://coomer.su/posts app.post("/uploadVideo", async (req, res) => { try { console.log("Starting upload"); @@ -14,6 +19,14 @@ app.post("/uploadVideo", async (req, res) => { const videoId = req.query.videoId; req.busboy.on("file", (fieldname, uploadingFile, fileInfo) => { + if (currentlyExecFfmpeg) { + res.send({ + status: "wait", + statusMessage: + "FFmpeg is currently processing another file. Please wait.", + }); + } + console.log(`Saving ${fileInfo.filename} as ${videoId}`); const videoExt = fileInfo.filename.split(".").at(-1); @@ -28,11 +41,23 @@ app.post("/uploadVideo", async (req, res) => { fileStream.on("close", () => { console.log(`Completed upload ${fileInfo.filename}`); const ffmpegCommand = `ffmpeg -i "${targetPath}" -c:v libx264 -crf 23 -preset medium -movflags +faststart -c:a aac -b:a 128k /opt/prod/storage/uploadsPart2/${videoId}-formatted.mp4`; - const wstream = fs.createWriteStream("/opt/prod/pipe/ffmpeg"); - wstream.write(`${ffmpegCommand}\n`); - wstream.write(`rm -f "${targetPath}"\n`); + currentlyExecFfmpeg = true; - res.send({ statusMessage: "Upload part 1 complete" }); + execPromise(ffmpegCommand) + .then(({ stdout, stderr }) => { + if (stderr && stderr.length > 0) { + console.log("FFmpeg stderr:", stderr); + } + }) + .catch((error) => { + console.log("FFmpeg caught error:", error); + }) + .finally(() => { + fs.unlinkSync(targetPath); + currentlyExecFfmpeg = false; + }); + + res.send({ status: "good", statusMessage: "Upload part 1 complete" }); }); }); req.pipe(req.busboy); diff --git a/start.sh b/start.sh index 072ac6f..75e5961 100644 --- a/start.sh +++ b/start.sh @@ -1,3 +1 @@ -./ffmpegQueuePipe.sh & - node dist/index.js