summaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-08-24 15:57:41 +0200
committerChristophe Besson <cbesson@gmail.com>2026-08-24 15:57:41 +0200
commitc5585beab3d6adefaa2ef9444946dd3816960a7c (patch)
treea321e540c2db0458716d526e4a045fca123937b2 /docs
parent317f09328ed8bf20148b707470c9b0fe82e59575 (diff)
downloadmeshbay-c5585beab3d6adefaa2ef9444946dd3816960a7c.tar.gz
fix(node,hub): HEVC transcode fallback, live-add progress, per-group TMDB toggle
Three bugs found live testing the Videos app against a real HEVC/EAC3 show, plus a design change requested afterward: - Streaming always did "-c:v copy", which faithfully reports a source's real hev1 codec string but is unplayable in a browser with no HEVC decoder (most Chrome/Linux builds). The node now transcodes to H264 whenever the probed codec is browser-incompatible (media_probe.py's new BROWSER_INCOMPATIBLE_VIDEO_CODECS), with a `transcode_incompatible_video` node.toml opt-out for operators who know their viewers already decode it. - Dropping a whole season into an already-watched folder gave no scanning indicator and no progress bar: IndexProgress was only ever updated by the two bulk scan paths, never by the real-time per-file watchdog path (_schedule_update/_debounce/_update_entry). That path now accounts a "burst" the same way, without double-counting a file rewritten mid-debounce. - A stray literal "0" rendered in the video detail modal when there was no TMDB match (`meta.confidence` is 0, and `0 && x` renders "0" in JSX/htm, not nothing) — `confident` is now a real boolean. - Whether TMDB is used at all moves from a node-wide setting to per-group (OP_TMDB_ENABLED/tmdb_enabled/tmdb_enabled_ack, scoped like OP_VIDEO_ROOT): an operator running a real media-library group alongside test/demo groups on one node wants outbound TMDB traffic for the one that needs it, not all of them. The custom API token and query language stay node-wide, one shared credential/cache (tmdb_config/OP_TMDB_CONFIG, unchanged reasoning). MNP_VERSION 0.6 -> 0.7, additive. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LAmyXtc6dAADsH23ydXQpY
Diffstat (limited to 'docs')
-rw-r--r--docs/mediacenter.md60
1 files changed, 51 insertions, 9 deletions
diff --git a/docs/mediacenter.md b/docs/mediacenter.md
index 66232f8..0df115b 100644
--- a/docs/mediacenter.md
+++ b/docs/mediacenter.md
@@ -362,6 +362,25 @@ seen; the file appears in the index immediately with size/hash only, and an
`index_sync` delta fills in the technical/parsed fields once ready — no
scan is blocked waiting for it.
+**Bug found live, 2026-08-24**: an operator moved a whole show's season into
+an already-watched shared folder and saw no scanning indicator and no
+progress bar at all — files just appeared one at a time, exactly as if
+nothing were tracking the add. Root cause: `IndexProgress` (`scanning`/
+`scanned_bytes`/`total_bytes`) was only ever touched by the two *bulk* scan
+paths — the initial walk and the periodic reconcile backstop, both of which
+know their file list upfront. The real-time watchdog path
+(`_schedule_update`/`_debounce`/`_update_entry`, one file at a time, each
+independently debounced) never touched it at all — an omission, not a race:
+dropping in ten files this way always gave zero feedback, indexing or not.
+Fixed by accounting a "burst" the same real-time path creates: a file's size
+is added to `total_bytes` the moment its debounce timer is first scheduled
+(not on every re-trigger of the same path — a cancelled-and-rescheduled
+timer must not double-count), and to `scanned_bytes` once its hash actually
+finishes; `scanning` flips back off only once no debounce timers are pending
+*and* no hash is still running, not just when the last timer fires — the
+in-flight hash of a large file is the entire reason to show progress in the
+first place.
+
### 5.3 Thumbnail delivery — reuse the chunk path
Since `thumb_hash` is a blake3 exactly like a file's own `id`, the cleanest
@@ -471,20 +490,22 @@ made a revisit's fetch fast enough to *be* synchronous.
### 5.5 Node-wide config, not per-group
-TMDB is one operator's budget and one credential, not a per-group concern,
-so it does not belong in `group_settings` keyed by a real `group_id`. The
-existing precedent for node-wide operator state stored in that same table is
-already established (`desktop-client-v1.md` §6.3: *"the precedent exists:
+The TMDB credential and query language are one operator's budget and one
+shared cache, not a per-group concern, so they do not belong in
+`group_settings` keyed by a real `group_id`. The existing precedent for
+node-wide operator state stored in that same table is already established
+(`desktop-client-v1.md` §6.3: *"the precedent exists:
`roster.get_member("", user_id)` already authorizes the operator
-node-wide"*) — so `tmdb_enabled` and an optional `tmdb_api_token` land in
+node-wide"*) — so an optional `tmdb_api_token` and `tmdb_language` land in
`group_settings` under the sentinel `group_id=""`, changed by a signed
operator op (`OP_TMDB_CONFIG`, same shape as `OP_MEMBER_UPLOAD`/
`OP_APPS_ENABLED`), and broadcast in `node_status` (the node-wide channel,
as opposed to the per-group `handshake_ack`) so every connected client,
-across every group, sees whether TMDB is on without reconnecting. Absent
-means the shipped default token, present with a token means "use this one
-instead" — the same "absent means the old behaviour" discipline
-`member_upload`/`apps_enabled` already follow.
+across every group, sees the current token/language state without
+reconnecting. Absent means the shipped default token, present with a token
+means "use this one instead" — the same "absent means the old behaviour"
+discipline `member_upload`/`apps_enabled` already follow. (Whether TMDB is
+used *at all* used to live here too — moved per-group, below.)
**Added 2026-08-24**: a third field, `tmdb_language` (e.g. `"fr-FR"`),
travels the same way — one node-wide setting, not a per-viewer request.
@@ -521,6 +542,27 @@ same — a second, English-forced details fetch only when a checked field
(`overview`, `poster_path`, `genres`) comes back empty, merged field by
field so a good localized field is never overwritten by the fallback.
+**Whether TMDB is used at all, moved per-group, 2026-08-24**: an operator
+running one real media-library group alongside several test/demo groups on
+the same node found every group sharing one on/off switch meant there was
+no way to spend TMDB quota and make outbound requests for the group that
+actually needed it without doing the same for groups that didn't. Split
+into its own signed op, `OP_TMDB_ENABLED`/`tmdb_enabled`/`tmdb_enabled_ack`,
+scoped to `self._group_id` exactly like `OP_VIDEO_ROOT` — stored in
+`group_settings` under the real `group_id` this time, not the `""`
+sentinel, and surfaced in the per-group `handshake_ack` (`tmdb_enabled`,
+already there — it simply reads a per-group value now) rather than
+`node_status`. `tmdb_config`/`OP_TMDB_CONFIG` keep their name and shape for
+the token/language, which stay node-wide for the reasoning above; only the
+on/off switch moved. `TmdbClient` itself lost its own notion of "enabled"
+entirely — every call site in `webrtc_server.py` (`_do_media_meta_request`,
+`_do_season_meta_request`, `_do_tmdb_search_request`) now checks
+`self._group_ctx().get("tmdb_enabled", True)` before ever calling it, and a
+group with it off degrades exactly like "no client configured" already
+did — zero confidence, empty search results, never an error, since a
+member's Videos tab already has to handle "no TMDB match" as the ordinary
+case (§4.1).
+
### 5.6 `ALLOWED_APPS`
`webrtc_server.py:1629` — add `"video"` to the frozenset. `DEFAULT_APPS`