Compact HE-AAC audio saves: server lane with fdkaac, shrink saved songs from Saved videos

This commit is contained in:
Jonathan Sykes
2026-10-18 17:28:47 +08:00
parent eef9fbf05f
commit b48d36b3dd
12 changed files with 342 additions and 22 deletions

View File

@@ -128,8 +128,19 @@ JSON shapes mirror the Tauri Rust bridge exactly — don't change one side alone
- **Broken**: `POST /api/media/:id/redownload` (now-playing ⚠ Broken button). When a
client falls back from a cached copy (`/api/streams?nocache=1`) the server also
re-validates its copy and refetches it if it fails — never trusts one device's error.
- Ops: `curl https://worship.hesed.sbs/api/media/stats`; files under
`/app/data/media` in the container.
- **Still-picture songs**: a fast still-check lane (keyframe scene scores, or 1 fps =
our own looped encode) marks `still=1`, writes `<id>.<gen>.jpg` + `audio_sha256`. Saves
send `?still=1` → the device stores `<id>.m4a` + OPFS `art/<id>.jpg` and plays it as
audio with the picture; online, still songs also play audio + `/api/media/:id/art`.
- **Compact audio (HE-AAC)**: `<id>.<gen>.he.m4a`, ~48 kbps HE-AAC v1 from **fdkaac**
(Debian contrib — ffmpeg's encoder is LC only), one niced lane, made for every copy and
moved to the front when a device asks (`prepare?audio=he` → `working` until ready).
Columns `he_size` (NULL = not made, 0 = failed/not smaller) + `he_sha256`. Devices ask
for it with Settings → "Save songs as compact audio" or Saved videos → Shrink
(`shrinkSaved` swaps the file in place; `ytpCompactSaves` remembers which ones).
Saved `.m4a` files of YouTube ids are never offered to P2P (not the server's file).
- Ops: `curl https://worship.hesed.sbs/api/media/stats` (`compactAudio`, `compactQueued`); files under
`$MEDIA_DIR` (`/app/bulk/media` on prod) in the container.
## Lyrics · chapters · bookmarks (`server/notes.js`, `frontend/lyrics-core.js`)
- **Shared per video** (every user sees the same copy): `video_notes` holds the live