add processVideo env
This commit is contained in:
parent
3605a3f3a5
commit
170479b585
8 changed files with 89 additions and 27 deletions
32
README.md
32
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -11,10 +11,12 @@ class ProgressManager {
|
|||
private static instance: ProgressManager;
|
||||
private emitter: EventEmitter;
|
||||
private activeJobs: Map<string, ProgressUpdate>;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<script src="https://unpkg.com/htmx.org@1.9.8"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body data-process-video="<%= processVideo %>">
|
||||
<section class="embedderapp">
|
||||
<header class="header">
|
||||
<h1>Embedder</h1>
|
||||
|
|
|
@ -23,6 +23,7 @@ function sanitizeId(filename) {
|
|||
<div class="video">
|
||||
<% const sanitizedId = file.path.replace(/[^a-z0-9]/gi, '_'); %>
|
||||
|
||||
<% if (processVideo) { %>
|
||||
<div id="spinner-<%= sanitizedId %>" class="spinner" style="display: <%= file.isProcessed ? 'none' : 'block' %>;">
|
||||
<div class="spinner-content">
|
||||
Optimizing Video for Sharing...
|
||||
|
@ -30,8 +31,12 @@ function sanitizeId(filename) {
|
|||
</div>
|
||||
|
||||
<div id="media-container-<%= sanitizedId %>" class="video-container" style="display: <%= file.isProcessed ? 'block' : 'none' %>;">
|
||||
<% } else { %>
|
||||
<div class="video-container">
|
||||
<% } %>
|
||||
<video class="image" autoplay loop muted playsinline>
|
||||
<source src="/uploads/720p-<%= file.path %>">
|
||||
<source src="/uploads/<%= file.path %>">
|
||||
</video>
|
||||
</div>
|
||||
|
||||
|
@ -40,7 +45,9 @@ function sanitizeId(filename) {
|
|||
<small class="username"><%= file.username %></small>
|
||||
<br>
|
||||
<% } %>
|
||||
<a href="/gifv/<%= file.path %>" onclick="copyA(event)">Copy as GIFv</a>
|
||||
<% if (processVideo) { %>
|
||||
<a href="/gifv/<%= file.path %>" onclick="copyA(event)">Copy as GIFv</a>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
<% } else if (mediaType === 'image') { %>
|
||||
|
|
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue