Co-authored-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com> Co-committed-by: Priyanshubhartistm <bhartipriyanshustm@gmail.com>
This commit was merged in pull request #3.
This commit is contained in:
@@ -1,44 +1,78 @@
|
||||
import express from "express"
|
||||
import ffmpeg from "fluent-ffmpeg"
|
||||
import {PassThrough} from "stream"
|
||||
import express from "express";
|
||||
import ffmpeg from "fluent-ffmpeg";
|
||||
import { PassThrough } from "stream";
|
||||
import NodeCache from "node-cache";
|
||||
import ffmpegInstaller from "@ffmpeg-installer/ffmpeg";
|
||||
|
||||
const app = express()
|
||||
const PORT = process.env.PORT || 3100
|
||||
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
|
||||
|
||||
app.get("/thumbnail", async (req, res) => {
|
||||
const videoUrl = req.query.url
|
||||
const app = express();
|
||||
const PORT = process.env.PORT || 3100;
|
||||
|
||||
const thumbnailCache = new NodeCache({
|
||||
stdTTL: 3600,
|
||||
checkperiod: 600,
|
||||
useClones: false
|
||||
});
|
||||
|
||||
app.get("/thumbnail", (req, res) => {
|
||||
const videoUrl = req.query.url?.trim();
|
||||
|
||||
if (!videoUrl) {
|
||||
return res.status(400).json({error: "Missing 'url' query parameter"})
|
||||
return res.status(400).json({ error: "Missing 'url' query parameter" });
|
||||
}
|
||||
|
||||
const cachedImage = thumbnailCache.get(videoUrl);
|
||||
if (cachedImage) {
|
||||
res.setHeader("Content-Type", "image/jpeg");
|
||||
res.setHeader("Cache-Control", "public, max-age=86400");
|
||||
return res.send(cachedImage);
|
||||
}
|
||||
|
||||
try {
|
||||
const passthrough = new PassThrough()
|
||||
const passthrough = new PassThrough();
|
||||
let imageBuffer = Buffer.alloc(0);
|
||||
|
||||
passthrough.on("data", (chunk) => {
|
||||
imageBuffer = Buffer.concat([imageBuffer, chunk]);
|
||||
});
|
||||
|
||||
passthrough.on("end", () => {
|
||||
if (imageBuffer.length > 0) {
|
||||
thumbnailCache.set(videoUrl, imageBuffer);
|
||||
}
|
||||
});
|
||||
|
||||
ffmpeg(videoUrl)
|
||||
.seekInput(1)
|
||||
.frames(1)
|
||||
.format("image2")
|
||||
.outputOptions("-vcodec", "mjpeg")
|
||||
.on("error", err => {
|
||||
.on("error", (err) => {
|
||||
console.error("ffmpeg error:", err.message);
|
||||
if (!res.headersSent) {
|
||||
res.status(500).json({error: "Failed to generate thumbnail"})
|
||||
res.status(500).json({ error: "Failed to generate thumbnail" });
|
||||
}
|
||||
})
|
||||
.pipe(passthrough, {end: true})
|
||||
.pipe(passthrough, { end: true });
|
||||
|
||||
res.setHeader("Content-Type", "image/jpeg")
|
||||
res.setHeader("Cache-Control", "public, max-age=86400")
|
||||
passthrough.pipe(res)
|
||||
} catch {
|
||||
res.status(500).json({error: "Failed to process video"})
|
||||
res.setHeader("Content-Type", "image/jpeg");
|
||||
res.setHeader("Cache-Control", "public, max-age=86400");
|
||||
|
||||
passthrough.pipe(res);
|
||||
|
||||
} catch (err) {
|
||||
console.error("Error:", err);
|
||||
if (!res.headersSent) {
|
||||
res.status(500).json({ error: "Failed to process video" });
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
app.get("/health", (_req, res) => {
|
||||
res.json({status: "ok"})
|
||||
})
|
||||
res.json({ status: "ok" });
|
||||
});
|
||||
|
||||
app.listen(PORT, () => {
|
||||
console.log(`Video thumbnail service running on port ${PORT}`)
|
||||
})
|
||||
console.log(`Video thumbnail service running on port ${PORT}`);
|
||||
});
|
||||
Reference in New Issue
Block a user