Sanad_lite/shell_scripts
Kassam Dakhlalah 9b7ef7d939 Device selection, cross-browser Live audio, and a rewritten README
Live Gemini could not use an external speaker or headset. An AudioContext
is bound to whichever output was default when it was created, and
getUserMedia({audio:true}) takes the system default input, so plugging a
device in afterwards left audio going to the old one — silently, with no
error to explain it.

  * Explicit Mic and Speaker pickers. Capture opens the chosen deviceId
    exactly and can be switched mid-session; playback is routed through a
    MediaStreamAudioDestinationNode into a hidden <audio> element so
    setSinkId() can move it to the chosen sink. Both lists refresh on
    devicechange and are remembered in localStorage.
  * Windows reports each device three times (default, communications, and
    the real one), so an Anker would have appeared three times with no way
    to tell them apart. The pseudo-devices are now collapsed.
  * Capture moved to an AudioWorklet (Blob-built, no extra file served)
    with the ScriptProcessor kept as a fallback.
  * A compatibility line reports what the browser actually supports, and
    the diagnostics line now shows the output sink and capture kind — the
    difference between "not listening" and "not speaking" without a
    debugger.

Verified in both engines with Playwright (chromium PASS, firefox PASS: no
page errors, personas and device lists populated, test tone plays) and
against real hardware, where setSinkId matched the selection and a named
microphone opened by deviceId. Two engine-specific bugs fell out of that
run and are fixed here: reading AudioContext.prototype.audioWorklet invokes
the getter and throws in both browsers, which aborted init and left the tab
empty, and the init steps are now isolated so one failure cannot take the
rest down.

Also in this commit:

  * README rewritten against what the code does today — the voice-fidelity
    rationale and its three gates, why words used to cut off, the Live tab
    and why the browser talks to Google directly, personas, device
    selection, recordings search/filter, sign-in history, a current API
    list, the cPanel production setup, and the known limits.
  * shell_scripts/start_cpanel.sh — the launcher that actually keeps the
    site up (HTTP health check, not a TCP probe) was only on the host.
  * data/live_personas.json — the persona library (G1, R1, Agibot, T800)
    existed only on the server; it is user-written content worth keeping.
  * .gitignore covers runtime state (logins, generated WAVs, .env, backups).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 23:33:28 +04:00
..
2026-05-13 11:30:29 +04:00
2026-05-13 11:30:29 +04:00
2026-05-13 11:30:29 +04:00