From 83b91bb1226da65362349bd7f6be319816be5a03 Mon Sep 17 00:00:00 2001 From: bytedream Date: Sat, 31 Oct 2026 03:57:25 +0100 Subject: [PATCH] add video thumbnail generation for opengraph --- astro.config.mjs | 3 + flake.nix | 1 + package-lock.json | 182 ----------------------- package.json | 1 - src/app/website/video/VideoPlayer.svelte | 5 +- src/pages/video/[name].astro | 11 +- src/pages/video/[name]/thumbnail.jpg.ts | 26 ++++ src/util/video.ts | 136 +++++++++++++---- 8 files changed, 149 insertions(+), 216 deletions(-) create mode 100644 src/pages/video/[name]/thumbnail.jpg.ts diff --git a/astro.config.mjs b/astro.config.mjs index 5406b87..6a9326c 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -7,6 +7,8 @@ import svelte, { vitePreprocess } from '@astrojs/svelte'; import node from '@astrojs/node'; +import { tmpdir } from 'node:os'; + // https://astro.build/config export default defineConfig({ output: 'server', @@ -35,6 +37,7 @@ export default defineConfig({ ADMIN_PASSWORD: envField.string({ context: 'server', access: 'secret', optional: true }), ADMIN_COOKIE: envField.string({ context: 'server', access: 'secret', default: 'muelleel' }), + CACHE_PATH: envField.string({ context: 'server', access: 'secret', default: tmpdir() }), UPLOAD_PATH: envField.string({ context: 'server', access: 'secret', optional: true }), VIDEO_PATH: envField.string({ context: 'server', access: 'secret', optional: true }), diff --git a/flake.nix b/flake.nix index 9fe86a0..bd7d211 100644 --- a/flake.nix +++ b/flake.nix @@ -58,6 +58,7 @@ runtimeInputs = [ pkgs.nodejs_26 pkgs.curl + pkgs.ffmpeg-headless ]; text = '' if [ ! -d node_modules ] || [ package-lock.json -nt node_modules/.package-lock.json ]; then diff --git a/package-lock.json b/package-lock.json index f8e8502..669fb22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,6 @@ "bcrypt": "^6.0.0", "daisyui": "^5.7.50", "drizzle-orm": "^0.45.4", - "music-metadata": "^12.3.2", "mysql2": "^3.24.6", "nanostores": "^1.5.5", "pino": "^10.4.0", @@ -427,16 +426,6 @@ "node": ">=6.9.0" } }, - "node_modules/@borewit/text-codec": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.3.tgz", - "integrity": "sha512-49CycTz1aAZmvFcwkeFyhud1HUmRIB5Tabf7ALV+VA4Iu85MTfz2cUwzPagMFAdVBvrWdkCxG67I30tUwwpKsw==", - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/@bruits/satteri-darwin-arm64": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/@bruits/satteri-darwin-arm64/-/satteri-darwin-arm64-0.10.5.tgz", @@ -2800,30 +2789,6 @@ "vite": "^5.2.0 || ^6 || ^7 || ^8" } }, - "node_modules/@tokenizer/inflate": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.6.0.tgz", - "integrity": "sha512-+0RDxhBkyT9xMnGdJAwmats9yxRLR8ypJrQgrnLqOu4Gv/aHlnxYgdGVy2QTwvBl6IF/w2Hr+ZNirH+iMUbVZA==", - "license": "MIT", - "dependencies": { - "debug": "^4.4.3", - "strtok3": "^10.6.2", - "token-types": "^6.1.2" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, - "node_modules/@tokenizer/token": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", - "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", - "license": "MIT" - }, "node_modules/@tybys/wasm-util": { "version": "0.10.4", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.4.tgz", @@ -3749,19 +3714,6 @@ "node": ">= 18" } }, - "node_modules/content-type": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-3.1.1.tgz", - "integrity": "sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA==", - "license": "MIT", - "engines": { - "node": ">=22" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/cookie": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", @@ -4641,24 +4593,6 @@ "flat-cache": "^6.1.23" } }, - "node_modules/file-type": { - "version": "22.3.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-22.3.0.tgz", - "integrity": "sha512-PrPedgnnWl5bWz3JHgar0QSzRvzeyFh7dZ9JpYOgcPZu4KALS9zw4MMa6qXRYyjeBsAlpaWB2boLuG991+0HIQ==", - "license": "MIT", - "dependencies": { - "@tokenizer/inflate": "^0.6.0", - "strtok3": "^10.6.3", - "token-types": "^6.1.2", - "uint8array-extras": "^1.6.0" - }, - "engines": { - "node": ">=22" - }, - "funding": { - "url": "https://github.com/sindresorhus/file-type?sponsor=1" - } - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -4969,26 +4903,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -5540,19 +5454,6 @@ "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", "license": "CC0-1.0" }, - "node_modules/media-typer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-2.0.0.tgz", - "integrity": "sha512-kOy3OxT2HH39N70UnKgu4NWDZjLOz8W/mfyvniHjRH/DrL3f2pOfvWQ4p60offbbtDAnXWp0v9LfMIqMec269Q==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/meshoptimizer": { "version": "0.18.1", "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.18.1.tgz", @@ -5740,37 +5641,6 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, - "node_modules/music-metadata": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/music-metadata/-/music-metadata-12.3.2.tgz", - "integrity": "sha512-U+Wu8c/7xa8wP331oVuRTAJSHcEWQIkLjpuyRJG+CAIszGYhpr5CRDv6PqkkVHDoX3ndjmdJlB6S49AaLq8SbQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - }, - { - "type": "buymeacoffee", - "url": "https://buymeacoffee.com/borewit" - } - ], - "license": "MIT", - "dependencies": { - "@borewit/text-codec": "^0.2.2", - "@tokenizer/token": "^0.3.0", - "content-type": "^3.1.1", - "debug": "^4.4.3", - "file-type": "^22.2.0", - "media-typer": "^2.0.0", - "strtok3": "^10.6.2", - "token-types": "^6.1.2", - "uint8array-extras": "^1.6.0", - "win-guid": "^0.2.1" - }, - "engines": { - "node": ">=22" - } - }, "node_modules/mysql2": { "version": "3.24.6", "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.24.6.tgz", @@ -7293,22 +7163,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/strtok3": { - "version": "10.6.3", - "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.6.3.tgz", - "integrity": "sha512-MD8mENgyXMr2mDaDfzP3RWYDSyYQxIIou7HhCiCJiBekrsoDtUG0id3vYnjDfY9ndOEbazFXe13Qw6u/1AB8ew==", - "license": "MIT", - "dependencies": { - "@tokenizer/token": "^0.3.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/suf-log": { "version": "2.5.3", "resolved": "https://registry.npmjs.org/suf-log/-/suf-log-2.5.3.tgz", @@ -7641,24 +7495,6 @@ "node": ">=0.6" } }, - "node_modules/token-types": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz", - "integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==", - "license": "MIT", - "dependencies": { - "@borewit/text-codec": "^0.2.1", - "@tokenizer/token": "^0.3.0", - "ieee754": "^1.2.1" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" - } - }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -7754,18 +7590,6 @@ "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", "license": "MIT" }, - "node_modules/uint8array-extras": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.6.0.tgz", - "integrity": "sha512-8iAasVS4wUx0gPLjH8Xtz2PeDzTSiy8QiLGu2DT3X5GU+egFEQhpnbtkehbAwjvDcxIERmCYcysiODFmE3Ud0Q==", - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ultrahtml": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.7.0.tgz", @@ -8169,12 +7993,6 @@ "node": ">= 8" } }, - "node_modules/win-guid": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/win-guid/-/win-guid-0.2.1.tgz", - "integrity": "sha512-gEIQU4mkgl2OPeoNrWflcJFJ3Ae2BPd4eCsHHA/XikslkIVms/nHhvnvzIZV7VLmBvtFlDOzLt9rrZT+n6D67A==", - "license": "MIT" - }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/package.json b/package.json index 627367c..cd56ce8 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "bcrypt": "^6.0.0", "daisyui": "^5.7.50", "drizzle-orm": "^0.45.4", - "music-metadata": "^12.3.2", "mysql2": "^3.24.6", "nanostores": "^1.5.5", "pino": "^10.4.0", diff --git a/src/app/website/video/VideoPlayer.svelte b/src/app/website/video/VideoPlayer.svelte index 3304459..f7caa6c 100644 --- a/src/app/website/video/VideoPlayer.svelte +++ b/src/app/website/video/VideoPlayer.svelte @@ -8,13 +8,14 @@ src: string; type?: string; title?: string; + poster?: string; } - let { src, type, title }: Props = $props(); + let { src, type, title, poster }: Props = $props(); - +