720p for gifv files

This commit is contained in:
ana 2023-07-31 02:52:34 +00:00
parent 511d340c45
commit 551d51c48d
5 changed files with 93 additions and 30 deletions

View file

@ -11,10 +11,10 @@ ffmpeg.setFfprobePath(ffprobepath.path);
import fs from "fs"; import fs from "fs";
import {extension} from "../types/lib"; import {extension, videoExtensions} from "../types/lib";
import {db, MediaRow, getPath, deleteId} from "../types/db"; import {db, MediaRow, getPath, deleteId} from "../types/db";
import {fileStorage} from "../types/multer"; 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? const upload = multer({ storage: fileStorage /**, fileFilter: fileFilter**/ }); //maybe make this a env variable?
/**Middleware to grab media from media database */ /**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("/"); 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) => { router.post("/:id(\\d+)/delete", [checkAuth], async (req: Request, res: Response) => {
const path: any = await getPath(req.params.id); const path: any = await getPath(req.params.id);
fs.unlink(`uploads/${path.path}`, async (err) => {
if (err && err.errno == -4058) { const nameAndExtension = extension(path.path);
await deleteId("media", req.params.id).then(()=> {
return res.redirect("/"); const filesToDelete = [path.path, "oembed-" + path.path + ".json"];
});
} if (videoExtensions.includes(nameAndExtension[1]) || nameAndExtension[1] == ".gif") {
await deleteId("media", req.params.id).then(()=> { filesToDelete.push("720p-" + path.path);
return res.redirect("/"); }
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; export default router;

View file

@ -16,4 +16,7 @@ export function extension(str: string){
export interface User { export interface User {
username: string; username: string;
id?: string; id?: string;
} }
export const videoExtensions = [".mp4", ".mov", ".avi", ".flv", ".mkv", ".wmv", ".webm"];
export const imageExtensions = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".svg", ".tiff", ".webp"];

View file

@ -9,8 +9,8 @@ ffmpeg.setFfprobePath(ffprobepath.path);
import fs from "fs"; import fs from "fs";
import process from "process"; import process from "process";
import {extension} from "../types/lib"; import {extension, videoExtensions, imageExtensions} from "./lib";
import {db, MediaParams} from "../types/db"; import {db, MediaParams} from "./db";
export const checkAuth: Middleware = (req, res, next) => { export const checkAuth: Middleware = (req, res, next) => {
if (!req.user) { if (!req.user) {
@ -63,26 +63,33 @@ export const createEmbedData: Middleware = (req, res, next) => {
} }
next(); next();
}; };
/** Converts video to gif and vice versa using ffmpeg */ /** Converts video to gif and vice versa using ffmpeg */
export const convert: Middleware = (req, res, next) => { export const convert: Middleware = (req, res, next) => {
const files = req.files as Express.Multer.File[]; const files = req.files as Express.Multer.File[];
for (const file in files) { for (const file in files) {
const nameAndExtension = extension(files[file].originalname); 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"); console.log("Converting " + nameAndExtension[0] + nameAndExtension[1] + " to gif");
const startTime = Date.now();
ffmpeg() ffmpeg()
.input(`uploads/${nameAndExtension[0]}${nameAndExtension[1]}`) .input(`uploads/${nameAndExtension[0]}${nameAndExtension[1]}`)
.inputFormat(nameAndExtension[1].substring(1)) .inputFormat(nameAndExtension[1].substring(1))
.outputFormat("gif") .outputFormat("gif")
.output(`uploads/${nameAndExtension[0]}.gif`) .output(`uploads/${nameAndExtension[0]}.gif`)
.on("end", function() { .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`); console.log(`Uploaded to uploads/${nameAndExtension[0]}.gif`);
}) })
.on("error", (e) => console.log(e)) .on("error", (e) => console.log(e))
.run(); .run();
} else if (nameAndExtension[1] == ".gif") { } else if (nameAndExtension[1] == ".gif") {
console.log(`Converting ${nameAndExtension[0]}${nameAndExtension[1]} to mp4`); console.log(`Converting ${nameAndExtension[0]}${nameAndExtension[1]} to mp4`);
const startTime = Date.now();
ffmpeg(`uploads/${nameAndExtension[0]}${nameAndExtension[1]}`) ffmpeg(`uploads/${nameAndExtension[0]}${nameAndExtension[1]}`)
.inputFormat("gif") .inputFormat("gif")
.outputFormat("mp4") .outputFormat("mp4")
@ -94,13 +101,50 @@ export const convert: Middleware = (req, res, next) => {
.noAudio() .noAudio()
.output(`uploads/${nameAndExtension[0]}.mp4`) .output(`uploads/${nameAndExtension[0]}.mp4`)
.on("end", function() { .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`); console.log(`Uploaded to uploads/${nameAndExtension[0]}.mp4`);
next();
}) })
.run(); .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 */ /**Middleware for handling uploaded files. Inserts it into the database */
export const handleUpload: Middleware = (req, res, next) => { export const handleUpload: Middleware = (req, res, next) => {
if (!req.file && !req.files) { if (!req.file && !req.files) {
@ -121,6 +165,7 @@ export const handleUpload: Middleware = (req, res, next) => {
next(); next();
}; };
/**Inserts into media database */ /**Inserts into media database */
function insertToDB (filename: string, expireDate: Date, username: string, next: NextFunction) { function insertToDB (filename: string, expireDate: Date, username: string, next: NextFunction) {
const params: MediaParams = [ const params: MediaParams = [

View file

@ -3,6 +3,8 @@ function extension(str){
let file = str.split('/').pop(); let file = str.split('/').pop();
return [file.substr(0,file.lastIndexOf('.')),file.substr(file.lastIndexOf('.'),file.length).toLowerCase()] return [file.substr(0,file.lastIndexOf('.')),file.substr(file.lastIndexOf('.'),file.length).toLowerCase()]
} }
const videoExtensions = ['.mp4', '.mov', '.avi', '.flv', '.mkv', '.wmv', '.webm'];
%> %>
<!DOCTYPE html> <!DOCTYPE html>
@ -15,23 +17,23 @@ function extension(str){
<meta property="og:description" content="Click to view the GIF"></meta> <meta property="og:description" content="Click to view the GIF"></meta>
<meta property="og:site_name" content="embedder"></meta> <meta property="og:site_name" content="embedder"></meta>
<meta property="og:type" content="article"></meta> <meta property="og:type" content="article"></meta>
<meta property="og:image" content="<%= host %>/uploads/<%= extension(url)[0] %>.gif"></meta> <meta property="og:image" content="<%= host %>/uploads/720p-<%= extension(url)[0] %>.gif"></meta>
<meta property="og:image:width" content="<%= width %>"></meta> <meta property="og:image:width" content="<%= width %>"></meta>
<meta property="og:image:height" content="<%= height %>"></meta> <meta property="og:image:height" content="<%= height %>"></meta>
<meta property="og:image:type" content="image/gif"></meta> <meta property="og:image:type" content="image/gif"></meta>
<meta property="og:url" content="<%= host %>/uploads/<%= extension(url)[0] %>.gif"></meta> <meta property="og:url" content="<%= host %>/uploads/720p-<%= extension(url)[0] %>.gif"></meta>
<% } else if (extension(url)[1] == ".mp4") { %> <% } else if (videoExtensions.includes(extension(url)[1])) { %>
<meta name="twitter:card" content="player"> <meta name="twitter:card" content="player">
<link rel="alternate" type="application/json+oembed" href="<%= host %>/uploads/oembed-<%= extension(url)[0]+extension(url)[1] %>.json"></link> <link rel="alternate" type="application/json+oembed" href="<%= host %>/uploads/oembed-<%= extension(url)[0]+extension(url)[1] %>.json"></link>
<meta property="og:title" content="<%= extension(url)[0] %>.mp4"></meta> <meta property="og:title" content="<%= extension(url)[0]+extension(url)[1] %>"></meta>
<meta property="og:description" content="Click to view the GIFv"></meta> <meta property="og:description" content="Click to view the GIFv"></meta>
<meta property="og:site_name" content="embedder"></meta> <meta property="og:site_name" content="embedder"></meta>
<meta property="og:type" content="article"></meta> <meta property="og:type" content="article"></meta>
<meta property="og:video" content="<%= host %>/uploads/<%= extension(url)[0] %>.mp4"></meta> <meta property="og:video" content="<%= host %>/uploads/720p-<%= extension(url)[0]+extension(url)[1] %>"></meta>
<meta property="og:video:width" content="<%= width %>"></meta> <meta property="og:video:width" content="<%= width %>"></meta>
<meta property="og:video:height" content="<%= height %>"></meta> <meta property="og:video:height" content="<%= height %>"></meta>
<meta property="og:video:type" content="video/mp4"></meta> <meta property="og:video:type" content="video/mp4"></meta>
<meta property="og:url" content="<%= host %>/uploads/<%= extension(url)[0] %>.mp4"></meta> <meta property="og:url" content="<%= host %>/uploads/720p-<%= extension(url)[0]+extension(url)[1] %>.mp4"></meta>
<% } else { %> <% } else { %>
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:card" content="summary_large_image">
<link rel="alternate" type="application/json+oembed" href="<%= host %>/uploads/oembed-<%= extension(url)[0]+extension(url)[1] %>.json"></link> <link rel="alternate" type="application/json+oembed" href="<%= host %>/uploads/oembed-<%= extension(url)[0]+extension(url)[1] %>.json"></link>
@ -47,8 +49,8 @@ function extension(str){
<% } %> <% } %>
</head> </head>
<body> <body>
<% if (extension(url)[1] == ".mp4") { %> <% if (videoExtensions.includes(extension(url)[1])) { %>
<video autoplay loop muted playsinline class="image" width="100%"><source src="/uploads/<%= extension(url)[0] %>.mp4"></video> <video autoplay loop muted playsinline class="image" width="100%"><source src="/uploads/720p-<%= extension(url)[0]+extension(url)[1] %>"></video>
<% } else { %> <% } else { %>
<img src="/uploads/<%= extension(url)[0] + extension(url)[1] %>" class="image" width="100%"> <img src="/uploads/<%= extension(url)[0] + extension(url)[1] %>" class="image" width="100%">
<% } %> <% } %>

View file

@ -15,7 +15,10 @@
function extension(string) { function extension(string) {
return string.slice((string.lastIndexOf(".") - 2 >>> 0) + 2); return string.slice((string.lastIndexOf(".") - 2 >>> 0) + 2);
} }
%>
const videoExtensions = ['.mp4', '.mov', '.avi', '.flv', '.mkv', '.wmv', '.webm'];
const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.tiff', '.webp'];
%>
</head> </head>
<body> <body>
<section class="embedderapp"> <section class="embedderapp">
@ -69,10 +72,10 @@
<li id="<%= file.path %>" class="show"> <li id="<%= file.path %>" class="show">
<form action="<%= file.url %>" method="post"> <form action="<%= file.url %>" method="post">
<div class="view"> <div class="view">
<% if (extension(file.path) == ".mp4" || extension(file.path) == ".mov" || extension(file.path) == "webp") { %> <% if (videoExtensions.includes(extension(file.path))) { %>
<div class="video"> <div class="video">
<video class="image" autoplay loop muted playsinline loading="lazy"> <video class="image" autoplay loop muted playsinline loading="lazy">
<source src="/uploads/<%= file.path %>" loading="lazy"> <source src="/uploads/720p-<%= file.path %>" loading="lazy">
</video> </video>
<div class="overlay"> <div class="overlay">
<% if(user.username == "admin" && file.username != "admin") { %> <% if(user.username == "admin" && file.username != "admin") { %>
@ -84,7 +87,7 @@
</div> </div>
<% } else if (extension(file.path) == ".gif") { %> <% } else if (extension(file.path) == ".gif") { %>
<div class="video"> <div class="video">
<img class="image" src="/uploads/<%=file.path %>" width="100%" onclick="copyURI(event);" loading="lazy"> <img class="image" src="/uploads/720p-<%=file.path %>" width="100%" onclick="copyURI(event);" loading="lazy">
<div class="overlay"> <div class="overlay">
<% if(user.username == "admin" && file.username != "admin") { %> <% if(user.username == "admin" && file.username != "admin") { %>
<small class="username"><%= file.username %></small> <small class="username"><%= file.username %></small>
@ -93,7 +96,7 @@
<a href="/gifv/<%=file.path %>" onclick="copyA(event)">Copy as GIFv</a> <a href="/gifv/<%=file.path %>" onclick="copyA(event)">Copy as GIFv</a>
</div> </div>
</div> </div>
<% } else if (extension(file.path) == ".jpg" || extension(file.path) == ".jpeg" || extension(file.path) == ".png" || extension(file.path) == ".gif" || extension(file.path) == ".webp" ) { %> <% } else if (imageExtensions.includes(extension(file.path))) { %>
<div class="video"> <div class="video">
<img class="image" src="/uploads/<%=file.path %>" width="100%" onclick="copyURI(event)" loading="lazy"> <img class="image" src="/uploads/<%=file.path %>" width="100%" onclick="copyURI(event)" loading="lazy">
<% if(user.username == "admin" && file.username != "admin") { %> <% if(user.username == "admin" && file.username != "admin") { %>