From 170479b585632dede50ee8158e57dbbf3fc64f38 Mon Sep 17 00:00:00 2001 From: waveringana Date: Sun, 11 May 2025 19:16:02 -0400 Subject: [PATCH] add processVideo env --- README.md | 32 ++++++++++++++---- app/app.ts | 2 ++ app/public/js/index.js | 5 ++- app/routes/index.ts | 56 +++++++++++++++++++++---------- app/services/ProgressManager.ts | 10 ++++++ app/views/index.ejs | 2 +- app/views/partials/_fileList.ejs | 9 ++++- bun.lockb | Bin 170718 -> 171520 bytes 8 files changed, 89 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 5a18d6d..865f99c 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ A media host specialized in producing visually appealing embeds for services lik $ export EBPASS=changeme $ export EBPORT=3000 $ export EBAPI_KEY=changeme # For ShareX support +$ export EB_PROCESS_VIDEO=true # Enable video processing $ npm install $ npm start @@ -57,22 +58,38 @@ Enabled at `/upload`. Requires authentication with key. `expire` key specifies d ### Configuration -This project uses environmental variables to configure functions. +This project uses environmental variables for configuration: -`EBPASS` configures the password for the admin account. +| Variable | Description | Default | +|----------|-------------|---------| +| `EBPASS` | Password for the admin account | required | +| `EBAPI_KEY` | Key for API uploading (ShareX) | required | +| `EBPORT` | Port the server runs on | required | +| `EB_PROCESS_VIDEO` | Enable video processing/optimization | `true` | +| `EB_ENCODER` | Video encoder to use (CPU, NVENC, QSV, etc.) | `CPU` | +| `EB_FFMPEG_PATH` | Path to ffmpeg binary | auto-detected or bundled | +| `EB_FFPROBE_PATH` | Path to ffprobe binary | auto-detected or bundled | +| `EB_RANDOMIZE_NAMES` | Randomize uploaded file names | `false` | -`EBAPI_KEY` configures the key for API uploading support typically used for ShareX. +#### Video Processing -`EBPORT` configures the port the server runs on. +When `EB_PROCESS_VIDEO` is enabled (which is the default), Embedder will: -`EB_FFMPEG_PATH` and `EB_FFPROBE_PATH` configures the path to the ffmpeg and ffprobe binaries respectively. If not set, it uses installed binaries set in the PATH. If none are detected, it will default to preinstalled binaries from the [node-ffmpeg-installer](https://www.npmjs.com/package/@ffmpeg-installer/ffmpeg) package. +1. Process uploaded videos to create optimized 720p versions +2. Show "Copy as GIFv" links for video files +3. Display a processing spinner while videos are being optimized -`EB_RANDOMIZE_NAMES` configures whether or not to randomize file names. If set to `true`, file names will be randomized. If not set or set to false, it will be `false`. +If disabled by setting `EB_PROCESS_VIDEO=false`, videos will be served directly without processing, which can be useful on systems with limited resources. ### Using Docker ```bash -docker run -d -p "3000:3000" -e EBPORT=3000 -e EBPASS=changeme -e EBAPI_KEY=changeme ghcr.io/waveringana/embedder:1.13 +docker run -d -p "3000:3000" \ + -e EBPORT=3000 \ + -e EBPASS=changeme \ + -e EBAPI_KEY=changeme \ + -e EB_PROCESS_VIDEO=true \ + ghcr.io/waveringana/embedder:1.13 ``` ### Docker Compose @@ -86,6 +103,7 @@ services: - EBPORT=3000 - EBPASS=changeme - EBAPI_KEY=changeme + - EB_PROCESS_VIDEO=true volumes: - ./db:/var/db - ./uploads:/uploads diff --git a/app/app.ts b/app/app.ts index 689414e..e008db2 100644 --- a/app/app.ts +++ b/app/app.ts @@ -92,6 +92,8 @@ function onListening() { const bind = typeof addr === "string" ? "pipe " + addr : "port " + addr.port; + const processVideo = process.env["EB_PROCESS_VIDEO"] === "true" ? true : false; + console.log("Process video: " + processVideo); console.log("Embedder version: " + version); console.log("Listening on " + bind); } diff --git a/app/public/js/index.js b/app/public/js/index.js index ba3609f..864e25c 100644 --- a/app/public/js/index.js +++ b/app/public/js/index.js @@ -24,7 +24,10 @@ class FileUploader { this.dropArea = document.getElementById('dropArea'); this.gallery = document.getElementById('gallery'); this.setupEventListeners(); - this.setupProgressUpdates(); // SSE logic for transcoding + // Only set up SSE if we're processing videos + if (document.body.dataset.processVideo === 'true') { + this.setupProgressUpdates(); + } } setupEventListeners() { diff --git a/app/routes/index.ts b/app/routes/index.ts index 7a0bf26..33c5b8a 100644 --- a/app/routes/index.ts +++ b/app/routes/index.ts @@ -26,6 +26,8 @@ import { processUploadedMedia, } from "../lib/middleware"; +const processVideo: boolean = process.env["EB_PROCESS_VIDEO"] !== "false"; + const upload = multer({ storage: fileStorage /**, fileFilter: fileFilter**/ }); //maybe make this a env variable? /**Middleware to grab media from media database */ @@ -65,6 +67,11 @@ const fetchMedia: Middleware = (req, res, next) => { const router = express.Router(); router.get('/progress-updates', (req, res) => { + if (!processVideo) { + res.status(404).send('Video processing is disabled'); + return; + } + console.log("SSE connection requested"); // Debug log res.setHeader('Content-Type', 'text/event-stream'); @@ -96,12 +103,12 @@ router.get( fetchMedia, (req: Request, res: Response) => { res.locals.filter = null; - res.render("index", { user: req.user }); + res.render("index", { user: req.user, processVideo }); } ); router.get("/media-list", fetchMedia, (req: Request, res: Response) => { - res.render("partials/_fileList", { user: req.user }); + res.render("partials/_fileList", { user: req.user, processVideo }); }); router.get( @@ -189,21 +196,36 @@ router.get("/oembed/:file", } ); -router.post( - "/", - [ - checkAuth, - upload.array("fileupload"), - handleUpload, - fetchMedia, - processUploadedMedia, - createEmbedData, - ], - (req: Request, res: Response) => { - return res.render("partials/_fileList", { user: req.user }); // Render only the file list partial - } -); - +if (processVideo) { + router.post( + "/", + [ + checkAuth, + upload.array("fileupload"), + handleUpload, + fetchMedia, + processUploadedMedia, + createEmbedData, + ], + (req: Request, res: Response) => { + return res.render("partials/_fileList", { user: req.user, processVideo }); // Render only the file list partial + } + ); +} else { + router.post( + "/", + [ + checkAuth, + upload.array("fileupload"), + handleUpload, + fetchMedia, + createEmbedData + ], + (req: Request, res: Response) => { + return res.render("partials/_fileList", { user: req.user, processVideo }); // Render only the file list partial + } + ); +} router.post( "/sharex", [checkSharexAuth, upload.single("fileupload"), createEmbedData, handleUpload], diff --git a/app/services/ProgressManager.ts b/app/services/ProgressManager.ts index 1c9d9f1..2603b8a 100644 --- a/app/services/ProgressManager.ts +++ b/app/services/ProgressManager.ts @@ -11,10 +11,12 @@ class ProgressManager { private static instance: ProgressManager; private emitter: EventEmitter; private activeJobs: Map; + private processVideo: boolean; private constructor() { this.emitter = new EventEmitter(); this.activeJobs = new Map(); + this.processVideo = process.env["EB_PROCESS_VIDEO"] === "true"; } static getInstance(): ProgressManager { @@ -25,19 +27,27 @@ class ProgressManager { } updateProgress(update: ProgressUpdate) { + if (!this.processVideo) return; + this.activeJobs.set(update.filename, update); this.emitter.emit('progress', update); } subscribeToUpdates(callback: (update: ProgressUpdate) => void) { + if (!this.processVideo) return; + this.emitter.on('progress', callback); } unsubscribeFromUpdates(callback: (update: ProgressUpdate) => void) { + if (!this.processVideo) return; + this.emitter.off('progress', callback); } getJobStatus(filename: string): ProgressUpdate | undefined { + if (!this.processVideo) return undefined; + return this.activeJobs.get(filename); } } diff --git a/app/views/index.ejs b/app/views/index.ejs index 1cb3564..f40a1dc 100644 --- a/app/views/index.ejs +++ b/app/views/index.ejs @@ -15,7 +15,7 @@ - +

Embedder

diff --git a/app/views/partials/_fileList.ejs b/app/views/partials/_fileList.ejs index 4761756..b18e570 100644 --- a/app/views/partials/_fileList.ejs +++ b/app/views/partials/_fileList.ejs @@ -23,6 +23,7 @@ function sanitizeId(filename) {
<% const sanitizedId = file.path.replace(/[^a-z0-9]/gi, '_'); %> + <% if (processVideo) { %>
Optimizing Video for Sharing... @@ -30,8 +31,12 @@ function sanitizeId(filename) {
+ <% } else { %> +
+ <% } %>
@@ -40,7 +45,9 @@ function sanitizeId(filename) { <%= file.username %>
<% } %> - Copy as GIFv + <% if (processVideo) { %> + Copy as GIFv + <% } %>
<% } else if (mediaType === 'image') { %> diff --git a/bun.lockb b/bun.lockb index f92a79b265328737e5556214fd5ab8435247ea2d..eb11124b1cfc412f95e73c923d216687f8876823 100755 GIT binary patch delta 33534 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 z z9plQ$nY#8&PlYD0(zWB%7l!$_u)%@@!I3j(Ix0LlOV5spLu7K6t{rQF2m^xy*Z~Vf zU|KdRn{z%9fdnErfw1a`GB8+8eyeEBnI;PHC?xh!oXH9H48(D!7964w16aV}gQ5`0 z*PLPu47T8O_EFxP(@l(lApo3DK;b=2jDf+NfuVta@W6|FhDHH6Sz+=kYdg-T3a}t5R5xc7oSbQ6&l#u)@h&6_E>nc0 zFbMC1BE&filMOY@S&fxIAq`50g-VbB02gPBizmOdwdec>6=MMvQ;ZsuGwtjdOD3pS8%{eEjK>WivxzNU(^Q8(T&=@9v zR5oW+ot)`l&)KaCb1Nu`o>zsK$O=v^ylRl-3n{2#)gXmF#2=H@ASEIrIFK)^LG(eA zhM+nmY8gR(w+n5?U0&6%hHb5x;%IqOml z1_mc^mj0jt2_!~P^l&O^LU_!RH|m-*hD^?MvFF^X3GqJDWJ6VR&Yzkvt3g#9xO`-^ zoSf-u&snGi2?}s=z`0fnl48IqjP}ZwHYDG&OfHl)=QP%VsAZhI zG1G!W2WB0p5}K_8bM{9qbEf+`lUKRhF)B=c>2A-NjG{157v`>y8s?l6bs?d^G`UdD zob$Xc#7IaPjgq`L+4W#{8)}$yn(M*z87i8yHtK;3K1FLz6lZWA)PtDE1gg(aeaiGx zZ}KZIJ4Wrvn%?%D(fSbMATc^qACiF~0d!d(7WW_fEI`!^Bj@ByAA43O1CXU_<*gZ) zO@8TP&-B`0a+bOsr>h~dQO$-740_;_4wN4^8p4t!D8YR;M7BoP2oftylQ*iFb5AlfpEq^;sV`I3x(Q zxr*kfk;bS#IWy3nHQEH~W6s$o3=Dpd28e<=r1E8YX)-x0$c|BC^2#84)c8R)jQBX> zOfZF|a!}g`9PCswd6FqoOfX$BovamR2P&My>=~UVuMD$iEj9yX$hB2A9A=Q1UP3l4Kg4qyjG66Y>+NYaDUP@l{piGl@GT5;N1KrDwC(rE#S zc*e;ajm$ZZT0mlf15|!6{j`{z6=}z5Z3z)%0ObP3=DyAl?67)D)-tTo5Ewuzz_^p3CiyAwvccDx7;{e z?I3j!3n+|OFWNCM_)T6LW6uhzmmp%<_8>9cSbJ7Tn*iihP6wDSLr)712S|znE9YG7 zz`zg$Zaf&Onlmy^UKwZ4>Fx*#LvTUGx!VyEzU<(}ouv~*H`C<89t#d9NQ^Oqq?ism zO@0+`$0_d2z~Bh3CP8ge4i`wV#x>c{+MMZ$%j8uFc8r>nUnbbIX1Ovj=uCbqYt1>$ z6;cH-gIYaI&s-<3O0?rta)T5@;ChKO$PE(bkOFI(8zi%{OfFP6=RD#DiB}GAdf;@2 zBo&UyhTi6!*6t9$K+2m+WFFIY_sOf0?U=r~Pkxnb$7$lhzz`13X@=hBj7uhGrr0y8 zOkSB{&spvXsaqkH`$5miTB&wSzda{srP?tDO0BIrsQNN+%X@9r?!>VigmpQNwEC$H3q+Iak4&v)2#e z2XM=c^SU1-R3J65s6QmpLz+dw{ty$`CmUK?aQH*4g0!Dr`9qumNeU_fkc7buiUh{Y z$(q^roR(BvSvB5QM|KS7hTa_l(Gg5iQn=A1=P z9wWGAw=Nix6u`NX^IkBlrS?(ToK-D^fx&F@S|e-Lm=FdAH&D&ax+sK!p$J?=D}_QV zh9vfgP>72m#lZx)9H?G9*SI%{}!L1_omWh6VwUa~RtuXV%#> z9Z#9Os?Lt{dkVZ@@U`Gbg*cRH@<&~B*7j6rXmRdOg_No6pftq!D-~ikq!=(sgYdw~ zl`}657KR&JEHK;ttjp3E7!0O2dNCSLPLSnbx|TLMtI>{8cJj(bd(Px^NRo#1PG(Nl zY_do78lnr#YMa5p5I0%3$(m_b#$>H#JI1QXna%c`Ycm-bOc@v&xIy(J=eJCVv%!(i zsgVVVY(`LIGsaBLY_aEDm<37VEFce~6^nPXAYK92N}O`pNZw?M$Oex+;YgmW)3O;D zLO`x#eU%L^l$xwr4RRP5!oXr}aF%K=1496)$inH*(p;#1ℜVB*hBKJ)BZ`Fo%OW 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 W`V0-G$J-BRGDYTY_npqPnGFE;x6--*