we subbing now bois #73
@@ -3,6 +3,8 @@ Little nodejs + mongodb app that I hack together with ChatGPT and Cursor to keep
|
||||
|
||||
**Note:** The application interface is in French.
|
||||
|
||||
**Disclaimer:** This was a fun, experimental project built with “AI slop” (Cursor), so it may have security issues. For example, `python_video_server` uses the default token‑in‑URL approach to serve video files, which can leave user tokens in logs or browser history. There are ways to improve this, but at this point I’m blinder than Ray Charles.
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
@@ -2442,12 +2442,14 @@ window.onload = async function () {
|
||||
const hasLowFile = !!(m && m.video_file_low);
|
||||
const hasEmbed = !!(m && m.embed_src);
|
||||
const hasLegacy = !!(m && m.vod_link);
|
||||
const hasSubtitle = !!(m && m.subtitle_file);
|
||||
|
||||
if (hasVideo) badges.push({ text: 'Video', cls: 'bg-primary' });
|
||||
if (hasFile) badges.push({ text: 'Server file', cls: 'bg-dark' });
|
||||
if (hasLowFile) badges.push({ text: 'Low file', cls: 'bg-secondary' });
|
||||
if (hasEmbed) badges.push({ text: 'Embed', cls: 'bg-info text-dark' });
|
||||
if (hasLegacy) badges.push({ text: 'Legacy', cls: 'bg-secondary' });
|
||||
if (hasSubtitle) badges.push({ text: 'Subtitles', cls: 'bg-warning text-dark' });
|
||||
|
||||
const modeRaw = String(m?.player_mode || 'auto').toLowerCase();
|
||||
const mode = (modeRaw === 'video' || modeRaw === 'embed' || modeRaw === 'auto') ? modeRaw : 'auto';
|
||||
|
||||
@@ -15,7 +15,10 @@ export MONGO_DB_NAME="..." # optional; required if MO
|
||||
export JWT_SECRET="..."
|
||||
export VIDEO_FILES_DIR="/absolute/path/to/public/video" # optional (default: ./public/video)
|
||||
export VIDEO_SESSION_MAX_AGE_SECONDS="28800" # optional (default: 8h)
|
||||
|
||||
uvicorn python_video_server.server:app --host 0.0.0.0 --port 8000
|
||||
or
|
||||
python3 -m uvicorn python_video_server.server:app --host 0.0.0.0 --port 8000 --ssl-certfile python_video_server/certs/config/live/[site]/fullchain.pem --ssl-keyfile python_video_server/certs/config/live/[site]/privkey.pem
|
||||
```
|
||||
|
||||
## Extra environment variables (optional)
|
||||
|
||||
+9
-1
@@ -122,7 +122,15 @@ async function convertSrtToVtt(filePath) {
|
||||
const content = await fs.promises.readFile(filePath, "utf8");
|
||||
const normalized = content.replace(/\r\n/g, "\n");
|
||||
const body = normalized.replace(/(\d{2}:\d{2}:\d{2}),(\d{3})/g, "$1.$2");
|
||||
const vtt = `WEBVTT\n\n${body.trim()}\n`;
|
||||
const positioned = body.replace(
|
||||
/^(\d{2}:\d{2}:\d{2}\.\d{3}\s+-->\s+\d{2}:\d{2}:\d{2}\.\d{3})(.*)$/gm,
|
||||
(_match, timing, settings) => {
|
||||
const tail = String(settings || "");
|
||||
if (/\bline:/i.test(tail)) return `${timing}${tail}`;
|
||||
return `${timing}${tail} line:90%`;
|
||||
},
|
||||
);
|
||||
const vtt = `WEBVTT\n\n${positioned.trim()}\n`;
|
||||
const vttPath = filePath.replace(/\.srt$/i, ".vtt");
|
||||
await fs.promises.writeFile(vttPath, vtt, "utf8");
|
||||
try { await fs.promises.unlink(filePath); } catch (_) {}
|
||||
|
||||
Reference in New Issue
Block a user