diff --git a/materialious/package-lock.json b/materialious/package-lock.json index 14c8dcd7..bcb568b8 100644 --- a/materialious/package-lock.json +++ b/materialious/package-lock.json @@ -1,12 +1,12 @@ { "name": "materialious", - "version": "1.2.3", + "version": "1.3.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "materialious", - "version": "1.2.3", + "version": "1.3.1", "dependencies": { "@capacitor-community/electron": "^5.0.1", "@capacitor/android": "6.1.2", @@ -14,6 +14,7 @@ "@capacitor/browser": "^6.0.2", "@capacitor/cli": "6.1.2", "@capacitor/core": "^6.1.2", + "@ffmpeg/ffmpeg": "^0.12.10", "beercss": "^3.6.13", "fuse.js": "^7.0.0", "he": "^1.2.0", @@ -32,7 +33,6 @@ }, "devDependencies": { "@capacitor/assets": "^3.0.5", - "@ffmpeg/ffmpeg": "^0.12.10", "@ffmpeg/util": "^0.12.1", "@sveltejs/adapter-auto": "^3.2.4", "@sveltejs/adapter-static": "^3.0.1", @@ -2613,7 +2613,6 @@ "version": "0.12.10", "resolved": "https://registry.npmjs.org/@ffmpeg/ffmpeg/-/ffmpeg-0.12.10.tgz", "integrity": "sha512-lVtk8PW8e+NUzGZhPTWj2P1J4/NyuCrbDD3O9IGpSeLYtUZKBqZO8CNj1WYGghep/MXoM8e1qVY1GztTkf8YYQ==", - "dev": true, "dependencies": { "@ffmpeg/types": "^0.12.2" }, @@ -2625,7 +2624,6 @@ "version": "0.12.2", "resolved": "https://registry.npmjs.org/@ffmpeg/types/-/types-0.12.2.tgz", "integrity": "sha512-NJtxwPoLb60/z1Klv0ueshguWQ/7mNm106qdHkB4HL49LXszjhjCCiL+ldHJGQ9ai2Igx0s4F24ghigy//ERdA==", - "dev": true, "engines": { "node": ">=16.x" } diff --git a/materialious/package.json b/materialious/package.json index 01aaf2fb..52b8b170 100644 --- a/materialious/package.json +++ b/materialious/package.json @@ -13,7 +13,6 @@ }, "devDependencies": { "@capacitor/assets": "^3.0.5", - "@ffmpeg/ffmpeg": "^0.12.10", "@ffmpeg/util": "^0.12.1", "@sveltejs/adapter-auto": "^3.2.4", "@sveltejs/adapter-static": "^3.0.1", @@ -46,6 +45,7 @@ "@capacitor/browser": "^6.0.2", "@capacitor/cli": "6.1.2", "@capacitor/core": "^6.1.2", + "@ffmpeg/ffmpeg": "^0.12.10", "beercss": "^3.6.13", "fuse.js": "^7.0.0", "he": "^1.2.0", @@ -62,4 +62,4 @@ "svelte-persisted-store": "^0.11.0", "vidstack": "^1.12.9" } -} \ No newline at end of file +} diff --git a/materialious/src/lib/videoDownload.ts b/materialious/src/lib/videoDownload.ts index ab66e459..60c3abb3 100644 --- a/materialious/src/lib/videoDownload.ts +++ b/materialious/src/lib/videoDownload.ts @@ -1,5 +1,3 @@ -import { FFmpeg } from '@ffmpeg/ffmpeg'; - interface MediaQuality { bandwidth: string; videoUrl: string; @@ -129,7 +127,9 @@ export async function mergeMediaFromDASH( merging?: (progress: number) => void, } ) { - const ffmpeg = new FFmpeg(); + const FFmpeg = await import('@ffmpeg/ffmpeg'); + + const ffmpeg = new FFmpeg.FFmpeg(); ffmpeg.on('progress', ({ progress }) => { if (progressCallbacks?.merging) { @@ -138,6 +138,7 @@ export async function mergeMediaFromDASH( }); await ffmpeg.load({ + classWorkerURL: await toBlobURL('/ffmpeg/ffmpeg-worker.js', 'text/javascript'), coreURL: await toBlobURL('/ffmpeg/ffmpeg-core.js', 'text/javascript'), wasmURL: await toBlobURL('/ffmpeg/ffmpeg-core.wasm', 'application/wasm'), workerURL: await toBlobURL('/ffmpeg/ffmpeg-core.worker.js', 'text/javascript') diff --git a/materialious/src/routes/(app)/watch/[slug]/+page.ts b/materialious/src/routes/(app)/watch/[slug]/+page.ts index 6e30867d..c8ea771b 100644 --- a/materialious/src/routes/(app)/watch/[slug]/+page.ts +++ b/materialious/src/routes/(app)/watch/[slug]/+page.ts @@ -51,11 +51,12 @@ export async function load({ params, url }) { } catch { } } + let downloadQualitiesDash; if ( - typeof import.meta.env.VITE_DEFAULT_DOWNLOAD_ENABLED !== 'undefined' && - import.meta.env.VITE_DEFAULT_DOWNLOAD_ENABLED.toString() === 'true' && - typeof video.hlsUrl === 'undefined' && get(playerDashStore) + import.meta.env.VITE_DEFAULT_DOWNLOAD_ENABLED && + import.meta.env.VITE_DEFAULT_DOWNLOAD_ENABLED.toString().toLowerCase() === 'true' && + !video.liveNow && get(playerDashStore) ) { downloadQualitiesDash = listCombinedQualities(video.dashUrl); } diff --git a/materialious/static/ffmpeg/ffmpeg-worker.js b/materialious/static/ffmpeg/ffmpeg-worker.js new file mode 100644 index 00000000..09244422 --- /dev/null +++ b/materialious/static/ffmpeg/ffmpeg-worker.js @@ -0,0 +1,146 @@ +(function () { + "use strict"; + const R = "./ffmpeg-core.js"; + var E; + (function (t) { + t.LOAD = "LOAD", t.EXEC = "EXEC", t.WRITE_FILE = "WRITE_FILE", t.READ_FILE = "READ_FILE", t.DELETE_FILE = "DELETE_FILE", t.RENAME = "RENAME", t.CREATE_DIR = "CREATE_DIR", t.LIST_DIR = "LIST_DIR", t.DELETE_DIR = "DELETE_DIR", t.ERROR = "ERROR", t.DOWNLOAD = "DOWNLOAD", t.PROGRESS = "PROGRESS", t.LOG = "LOG", t.MOUNT = "MOUNT", t.UNMOUNT = "UNMOUNT" + })(E || (E = {})); + const a = new Error("unknown message type"), + f = new Error("ffmpeg is not loaded, call `await ffmpeg.load()` first"), + u = new Error("failed to import ffmpeg-core.js"); + let r; + const O = async ({ + coreURL: t, + wasmURL: n, + workerURL: e + }) => { + const o = !r; + try { + t || (t = R), importScripts(t) + } catch { + if (t || (t = R.replace("/umd/", "/esm/")), self.createFFmpegCore = (await import(t)).default, !self.createFFmpegCore) throw u + } + const s = t, + c = n || t.replace(/.js$/g, ".wasm"), + b = e || t.replace(/.js$/g, ".worker.js"); + return r = await self.createFFmpegCore({ + mainScriptUrlOrBlob: `${s}#${btoa(JSON.stringify({ wasmURL: c, workerURL: b }))}` + }), r.setLogger(i => self.postMessage({ + type: E.LOG, + data: i + })), r.setProgress(i => self.postMessage({ + type: E.PROGRESS, + data: i + })), o + }, l = ({ + args: t, + timeout: n = -1 + }) => { + r.setTimeout(n), r.exec(...t); + const e = r.ret; + return r.reset(), e + }, m = ({ + path: t, + data: n + }) => (r.FS.writeFile(t, n), !0), D = ({ + path: t, + encoding: n + }) => r.FS.readFile(t, { + encoding: n + }), S = ({ + path: t + }) => (r.FS.unlink(t), !0), I = ({ + oldPath: t, + newPath: n + }) => (r.FS.rename(t, n), !0), L = ({ + path: t + }) => (r.FS.mkdir(t), !0), N = ({ + path: t + }) => { + const n = r.FS.readdir(t), + e = []; + for (const o of n) { + const s = r.FS.stat(`${t}/${o}`), + c = r.FS.isDir(s.mode); + e.push({ + name: o, + isDir: c + }) + } + return e + }, A = ({ + path: t + }) => (r.FS.rmdir(t), !0), w = ({ + fsType: t, + options: n, + mountPoint: e + }) => { + const o = t, + s = r.FS.filesystems[o]; + return s ? (r.FS.mount(s, n, e), !0) : !1 + }, k = ({ + mountPoint: t + }) => (r.FS.unmount(t), !0); + self.onmessage = async ({ + data: { + id: t, + type: n, + data: e + } + }) => { + const o = []; + let s; + try { + if (n !== E.LOAD && !r) throw f; + switch (n) { + case E.LOAD: + s = await O(e); + break; + case E.EXEC: + s = l(e); + break; + case E.WRITE_FILE: + s = m(e); + break; + case E.READ_FILE: + s = D(e); + break; + case E.DELETE_FILE: + s = S(e); + break; + case E.RENAME: + s = I(e); + break; + case E.CREATE_DIR: + s = L(e); + break; + case E.LIST_DIR: + s = N(e); + break; + case E.DELETE_DIR: + s = A(e); + break; + case E.MOUNT: + s = w(e); + break; + case E.UNMOUNT: + s = k(e); + break; + default: + throw a + } + } catch (c) { + self.postMessage({ + id: t, + type: E.ERROR, + data: c.toString() + }); + return + } + s instanceof Uint8Array && o.push(s.buffer), self.postMessage({ + id: t, + type: n, + data: s + }, o) + } +})(); \ No newline at end of file diff --git a/materialious/vite.config.ts b/materialious/vite.config.ts index efaa6e6e..a61abf32 100644 --- a/materialious/vite.config.ts +++ b/materialious/vite.config.ts @@ -1,6 +1,5 @@ import { sveltekit } from '@sveltejs/kit/vite'; import { SvelteKitPWA } from '@vite-pwa/sveltekit'; -import { fileURLToPath, URL } from 'node:url'; import { vite as vidstack } from 'vidstack/plugins'; import { defineConfig } from 'vite'; @@ -35,12 +34,7 @@ export default defineConfig({ vidstack(), sveltekit() ], - resolve: { - alias: { - '@': fileURLToPath(new URL('./src', import.meta.url)) - } - }, optimizeDeps: { exclude: ['@ffmpeg/ffmpeg', '@ffmpeg/util'] - } + }, });