diff --git a/app/routes/index.ts b/app/routes/index.ts index b9063b5..f42eac7 100644 --- a/app/routes/index.ts +++ b/app/routes/index.ts @@ -11,10 +11,10 @@ ffmpeg.setFfprobePath(ffprobepath.path); import fs from "fs"; -import {extension} from "../types/lib"; +import {extension, videoExtensions} from "../types/lib"; import {db, MediaRow, getPath, deleteId} from "../types/db"; import {fileStorage} from "../types/multer"; -import {checkAuth, checkSharexAuth, createEmbedData, handleUpload} from "./middleware"; +import {checkAuth, checkSharexAuth, convertTo720p, createEmbedData, handleUpload} from "../types/middleware"; const upload = multer({ storage: fileStorage /**, fileFilter: fileFilter**/ }); //maybe make this a env variable? /**Middleware to grab media from media database */ @@ -72,7 +72,7 @@ router.get("/gifv/:file", async (req: Request, res: Response, next: NextFunction } }); -router.post("/", [checkAuth, upload.array("fileupload"), createEmbedData, handleUpload], (req: Request, res: Response) => { +router.post("/", [checkAuth, upload.array("fileupload"), convertTo720p, createEmbedData, handleUpload], (req: Request, res: Response) => { res.redirect("/"); }); @@ -82,16 +82,26 @@ router.post("/sharex", [checkSharexAuth, upload.single("fileupload"), createEmbe router.post("/:id(\\d+)/delete", [checkAuth], async (req: Request, res: Response) => { const path: any = await getPath(req.params.id); - fs.unlink(`uploads/${path.path}`, async (err) => { - if (err && err.errno == -4058) { - await deleteId("media", req.params.id).then(()=> { - return res.redirect("/"); - }); - } - await deleteId("media", req.params.id).then(()=> { - return res.redirect("/"); + + const nameAndExtension = extension(path.path); + + const filesToDelete = [path.path, "oembed-" + path.path + ".json"]; + + if (videoExtensions.includes(nameAndExtension[1]) || nameAndExtension[1] == ".gif") { + filesToDelete.push("720p-" + path.path); + } + + filesToDelete.forEach(path => { + fs.unlink(path, async (err) => { + console.log(`Deleting ${path}`); + if (err && err.errno == -4058) { + await deleteId("media", req.params.id); + } + await deleteId("media", req.params.id); }); }); + + return res.redirect("/"); }); export default router; \ No newline at end of file diff --git a/app/types/lib.ts b/app/types/lib.ts index d619ab6..bff8c84 100644 --- a/app/types/lib.ts +++ b/app/types/lib.ts @@ -16,4 +16,7 @@ export function extension(str: string){ export interface User { username: string; id?: string; -} \ No newline at end of file +} + +export const videoExtensions = [".mp4", ".mov", ".avi", ".flv", ".mkv", ".wmv", ".webm"]; +export const imageExtensions = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".tiff", ".webp"]; diff --git a/app/routes/middleware.ts b/app/types/middleware.ts similarity index 74% rename from app/routes/middleware.ts rename to app/types/middleware.ts index 65adabe..261c25c 100644 --- a/app/routes/middleware.ts +++ b/app/types/middleware.ts @@ -9,8 +9,8 @@ ffmpeg.setFfprobePath(ffprobepath.path); import fs from "fs"; import process from "process"; -import {extension} from "../types/lib"; -import {db, MediaParams} from "../types/db"; +import {extension, videoExtensions, imageExtensions} from "./lib"; +import {db, MediaParams} from "./db"; export const checkAuth: Middleware = (req, res, next) => { if (!req.user) { @@ -63,26 +63,33 @@ export const createEmbedData: Middleware = (req, res, next) => { } next(); }; + /** Converts video to gif and vice versa using ffmpeg */ export const convert: Middleware = (req, res, next) => { const files = req.files as Express.Multer.File[]; + for (const file in files) { const nameAndExtension = extension(files[file].originalname); - if (nameAndExtension[1] == ".mp4" || nameAndExtension[1] == ".webm" || nameAndExtension[1] == ".mkv" || nameAndExtension[1] == ".avi" || nameAndExtension[1] == ".mov") { + + if (videoExtensions.includes(nameAndExtension[1])) { console.log("Converting " + nameAndExtension[0] + nameAndExtension[1] + " to gif"); + + const startTime = Date.now(); ffmpeg() .input(`uploads/${nameAndExtension[0]}${nameAndExtension[1]}`) .inputFormat(nameAndExtension[1].substring(1)) .outputFormat("gif") .output(`uploads/${nameAndExtension[0]}.gif`) .on("end", function() { - console.log("Conversion complete"); + console.log(`Conversion complete, took ${Date.now() - startTime} to complete`); console.log(`Uploaded to uploads/${nameAndExtension[0]}.gif`); }) .on("error", (e) => console.log(e)) .run(); } else if (nameAndExtension[1] == ".gif") { console.log(`Converting ${nameAndExtension[0]}${nameAndExtension[1]} to mp4`); + + const startTime = Date.now(); ffmpeg(`uploads/${nameAndExtension[0]}${nameAndExtension[1]}`) .inputFormat("gif") .outputFormat("mp4") @@ -94,13 +101,50 @@ export const convert: Middleware = (req, res, next) => { .noAudio() .output(`uploads/${nameAndExtension[0]}.mp4`) .on("end", function() { - console.log("Conversion complete"); + console.log(`Conversion complete, took ${Date.now() - startTime} to complete`); console.log(`Uploaded to uploads/${nameAndExtension[0]}.mp4`); + next(); }) .run(); } } }; + +/**Creates a 720p copy of video for smaller file */ +export const convertTo720p: Middleware = (req, res, next) => { + const files = req.files as Express.Multer.File[]; + console.log("convert to 720p running"); + for (const file in files) { + const nameAndExtension = extension(files[file].originalname); + + //Skip if not a video + if (!videoExtensions.includes(nameAndExtension[1]) && nameAndExtension[1] !== ".gif") { + console.log(`${files[file].originalname} is not a video file`); + console.log(nameAndExtension[1]); + continue; + } + + console.log(`Creating 720p for ${files[file].originalname}`); + + const startTime = Date.now(); + + ffmpeg() + .input(`uploads/${nameAndExtension[0]}${nameAndExtension[1]}`) + .inputFormat(nameAndExtension[1].substring(1)) + .outputOptions("-vf", "scale=-1:720") + .output(`uploads/720p-${nameAndExtension[0]}${nameAndExtension[1]}`) + .on("end", function() { + console.log(`720p copy complete, took ${Date.now() - startTime} to complete`); + console.log(`Uploaded to uploads/720p-${nameAndExtension[0]}${nameAndExtension[1]}`); + next(); + }) + .on("error", (e) => console.log(e)) + .run(); + } + + next(); +}; + /**Middleware for handling uploaded files. Inserts it into the database */ export const handleUpload: Middleware = (req, res, next) => { if (!req.file && !req.files) { @@ -121,6 +165,7 @@ export const handleUpload: Middleware = (req, res, next) => { next(); }; + /**Inserts into media database */ function insertToDB (filename: string, expireDate: Date, username: string, next: NextFunction) { const params: MediaParams = [ diff --git a/app/views/gifv.ejs b/app/views/gifv.ejs index 043febc..14d8e4c 100644 --- a/app/views/gifv.ejs +++ b/app/views/gifv.ejs @@ -3,6 +3,8 @@ function extension(str){ let file = str.split('/').pop(); return [file.substr(0,file.lastIndexOf('.')),file.substr(file.lastIndexOf('.'),file.length).toLowerCase()] } + +const videoExtensions = ['.mp4', '.mov', '.avi', '.flv', '.mkv', '.wmv', '.webm']; %> @@ -15,23 +17,23 @@ function extension(str){ - + - - <% } else if (extension(url)[1] == ".mp4") { %> + + <% } else if (videoExtensions.includes(extension(url)[1])) { %> - + - + - + <% } else { %> @@ -47,8 +49,8 @@ function extension(str){ <% } %>
- <% if (extension(url)[1] == ".mp4") { %> - + <% if (videoExtensions.includes(extension(url)[1])) { %> + <% } else { %>