Run SHA-256 as WebAssembly with JS fallback; note ffmpeg.wasm as deferred

This commit is contained in:
Claude
2026-10-02 11:10:51 +00:00
parent 883c9e7ba0
commit 0d92accd1d
10 changed files with 189 additions and 9 deletions

View File

@@ -36,7 +36,7 @@ JSON shapes mirror the Tauri Rust bridge exactly — don't change one side alone
sends the `File` itself); cover images go to `PUT /api/admin/uploads/:id/art`. The multipart
`POST /api/admin/uploads` parses the whole body in memory — scripts with small files only.
- Videos over `transcode.maxSeconds` are never re-encoded (lane would be tied up for hours).
- Deferred ideas (Cloudflare Worker fetch, Android device download): `docs/deferred-ideas.md`.
- Deferred ideas (Cloudflare Worker fetch, Android device download, ffmpeg.wasm client editing): `docs/deferred-ideas.md`.
## Save to device + "On other devices"
- `exportToDevice(video)` (app.js, helpers in `frontend/export.js`): puts the file in Photos / Files / Downloads.
@@ -76,6 +76,15 @@ JSON shapes mirror the Tauri Rust bridge exactly — don't change one side alone
`ignoreSearch` against the plain-URL precache. A new build = new URLs, so old ones simply get evicted.
`/fonts` and `/icons` are cached 30 days.
## SHA-256 in WebAssembly (`frontend/sha256.js`)
- `Sha256.create()` runs its block function as WebAssembly (`frontend/wasm/sha256.c` → `scripts/build-sha256-wasm.sh`
→ generated `frontend/sha256-wasm.js`, base64, ~2 KB) and falls back to pure JS if WebAssembly is missing, the CSP
refuses it, or the load-time self-test ("abc") fails. ~150 MB/s vs ~65 MB/s in JS (Node/Chromium; phones are slower
but the ratio holds). It is synchronous on purpose (callers aren't async) — fine because the module is under 4 KB.
- Needs `'wasm-unsafe-eval'` in index.html's CSP `script-src`. Workers pull the blob in with `importScripts('/sha256-wasm.js')`
from inside sha256.js; the file is in the SW `SHELL` list. After editing the C file, re-run the build script and commit both.
`Sha256.engine()` says which one is active; `create({js:true})` forces JS (tests).
## Server media cache (`server/media-cache.js`)
- Every played (`/api/streams`, LOW priority, ≤ `MEDIA_AUTO_MAX_SECONDS`, default 3 h) or saved
(`/api/download`, HIGH, ≤ 3 h) video gets ONE copy: `$MEDIA_DIR/<id>.<gen>.mp4`