mirror of
https://github.com/theoleuthardt/werkzeugkiste.git
synced 2026-06-13 09:37:53 +00:00
Merge branch 'main' into feat/video-to-audio
This commit is contained in:
commit
7494e89661
5 changed files with 200 additions and 0 deletions
|
|
@ -3,6 +3,10 @@ FROM node:18-alpine AS base
|
|||
|
||||
# Install system dependencies
|
||||
RUN apk add --no-cache libc6-compat libreoffice ttf-liberation ffmpeg
|
||||
RUN apk add --update --no-cache python3 py3-pip \
|
||||
&& ln -sf python3 /usr/bin/python \
|
||||
&& pip3 install --no-cache --upgrade pip setuptools \
|
||||
RUN pip3 install --no-cache watchdog gradio rembg
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import { tmzConvert } from "./src/routes/tmzconvert.route";
|
|||
import { generateQRCode } from "./src/routes/generateqrcode.route";
|
||||
import { wordCounter } from "./src/routes/wordcounter.route";
|
||||
import { videoToAudio } from "./src/routes/videotoaudio.route";
|
||||
import { removeBG } from "./src/routes/removebg.route";
|
||||
|
||||
const app = Fastify({ logger: true });
|
||||
|
||||
|
|
@ -27,6 +28,7 @@ app.register(tmzConvert);
|
|||
app.register(generateQRCode);
|
||||
app.register(wordCounter);
|
||||
app.register(videoToAudio);
|
||||
app.register(removeBG);
|
||||
|
||||
const PORT = process.env.PORT || 4000;
|
||||
app.listen({ port: Number(PORT), host: "0.0.0.0" }, () => {
|
||||
|
|
|
|||
78
backend/src/routes/removebg.route.ts
Normal file
78
backend/src/routes/removebg.route.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { FastifyInstance, FastifyReply, FastifyRequest } from "fastify";
|
||||
import { promises as fs } from "fs";
|
||||
import * as path from "path";
|
||||
import { randomUUID } from "crypto";
|
||||
import { spawn } from "child_process";
|
||||
|
||||
export async function removeBG(app: FastifyInstance) {
|
||||
app.post(
|
||||
"/api/remove-bg",
|
||||
async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
const tmpDir = path.join(process.cwd(), "tmp");
|
||||
const sessionId = randomUUID();
|
||||
const inputPath = path.join(tmpDir, `input-${sessionId}.png`);
|
||||
const outputPath = path.join(tmpDir, `output-${sessionId}.png`);
|
||||
|
||||
try {
|
||||
const parts = request.parts();
|
||||
await fs.mkdir(tmpDir, { recursive: true });
|
||||
|
||||
let fileBuffer: Buffer | null = null;
|
||||
|
||||
for await (const part of parts) {
|
||||
if (part.type === "file") {
|
||||
fileBuffer = await part.toBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
if (!fileBuffer) {
|
||||
return reply.status(400).send({ error: "No file uploaded!" });
|
||||
}
|
||||
|
||||
await fs.writeFile(inputPath, fileBuffer);
|
||||
console.log("Received file, buffer length:", fileBuffer.length);
|
||||
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const pythonProcess = spawn("rembg", ["i", inputPath, outputPath]);
|
||||
|
||||
pythonProcess.stderr.on("data", (data) => {
|
||||
console.log(`ffmpeg stderr: ${data}`);
|
||||
});
|
||||
|
||||
pythonProcess.on("close", (code) => {
|
||||
if (code === 0) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(new Error(`rembg process exited with code ${code}`));
|
||||
}
|
||||
});
|
||||
|
||||
pythonProcess.on("error", (err) => {
|
||||
reject(err);
|
||||
});
|
||||
});
|
||||
|
||||
const outputImageBuffer = await fs.readFile(outputPath);
|
||||
await Promise.all([fs.unlink(inputPath), fs.unlink(outputPath)]);
|
||||
|
||||
reply
|
||||
.header("Content-Type", "image/png")
|
||||
.header("Content-Disposition", `attachment; filename="converted.png"`)
|
||||
.status(200)
|
||||
.send(outputImageBuffer);
|
||||
} catch (error) {
|
||||
try {
|
||||
await Promise.all([
|
||||
fs.unlink(inputPath).catch(() => {}),
|
||||
fs.unlink(outputPath).catch(() => {}),
|
||||
]);
|
||||
} catch (cleanupError) {
|
||||
console.error("Cleanup error:", cleanupError);
|
||||
}
|
||||
|
||||
console.error("Convert error:", error);
|
||||
reply.status(500).send({ error: "Error while converting!" });
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue