screentinker/tizen/js
ScreenTinker cf1124d687
Some checks are pending
CI / Unit tests (node --test) (push) Waiting to run
CI / OpenAPI spec lint (push) Waiting to run
CI / Android unit tests (Kotlin schedule evaluator vectors) (push) Waiting to run
CI / Boot smoke + version check (push) Waiting to run
Mute reaches YouTube items — it never did, and failed opposite ways per player
Muting was implemented three times and agreed nowhere. A YouTube item is a
cross-origin iframe, so `el.muted` reaches nothing; only the IFrame API can
touch it. Both browser-family players got this wrong, in opposite directions:

  web    playerVars.mute was `userHasInteracted ? 0 : 1` — autoplay policy and
         NOTHING else. An item an operator muted in the admin console played
         WITH SOUND, a wall follower blared alongside its leader, and the
         real-time device:mute-changed toggle only ever touched `<video>`.
         onReady then unmuted unconditionally, and the click-to-unmute overlay
         appeared on deliberately-muted items and undid the operator's setting.

  tizen  the embed URL hardcoded `mute=1`, so YouTube there was PERMANENTLY
         silent: the per-item flag was never read and nothing could unmute it.
         device:mute-changed did nothing at all, because it dereferenced a
         <video> that is null for a YouTube item.

Android was already correct and is unchanged — it is the reference here.

The rule now lives once, in server/lib/media-mute.js, served to the web player
from its single source the same way schedule-eval.js is, and mirrored in Tizen
(which ships inside the .wgt and cannot import it). The ORDER is the substance:
a wall follower is always silent (one wall, one audio source) > autoplay policy,
which is a hard constraint rather than a preference because unmuted playback
without a gesture is refused outright and costs the VIDEO > a live operator
toggle, who is looking at the screen > the item's stored flag.

shouldOfferUnmute() exists so the prompt only appears when a gesture is the ONLY
thing in the way. Prompting on a muted item trains viewers to click a button
that undoes an operator's decision.

Tizen gains enablejsapi + a postMessage bridge so a live toggle flips the embed
without reloading it — reloading would restart the video from zero every time
someone touched the control.

11 new tests pinning each precedence step separately; 1055 pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL
2026-08-05 10:50:59 -05:00
..
app.js Mute reaches YouTube items — it never did, and failed opposite ways per player 2026-08-05 10:50:59 -05:00
device-control.js Tizen player: real Samsung B2B fleet control (#125), folding in #126 2026-06-18 13:28:08 -05:00
pip-overlay.js PiP overlay MVP: push image/web overlays to a device or group (#109) (#127) 2026-06-18 14:54:44 -05:00
player.js Mute reaches YouTube items — it never did, and failed opposite ways per player 2026-08-05 10:50:59 -05:00
schedule-eval.js feat(scheduling): per-item schedule blocks (#74 dayparting, #75 auto-expire) 2026-06-11 15:46:41 -05:00
socket.io.min.js feat(tizen): Samsung Tizen TV web player (.wgt) 2026-06-09 19:01:58 -05:00
transitions.js feat: transition engine — GL wipes across web, Tizen & Android (+ image↔video) (#204) 2026-07-20 16:45:32 -05:00