Releases: Kepners/pcnestspeaker-releases
Release list
v2.1.1
PC Nest Speaker 2.1.1
Same-version maintenance release on top of 2.1.0.
Fixed
- HTTP PCM drop recovery. Backpressure recovery now tolerates short Cast/Wi-Fi stalls before closing the receiver stream, waits longer for PCM receiver relaunch, and falls back to a full stream reconnect if direct relaunch fails. This targets the
Backpressure recovery failed: Execution of start app 4B876246 timed out after 10.0 sfailure seen on July 9, 2026. - Play while PC is locked. Settings now includes
Play while PC is locked, enabled by default. When enabled, locking Windows leaves the active stream running; when disabled, the app stops on lock and reconnects on unlock. - Startup and unlock reconnect. Successful speaker, group, and stereo starts are remembered for automatic reconnect on app startup/autoboot; streams stopped by PC lock can reconnect on unlock.
- App version display. The in-app footer no longer shows stale
v2.0.0; it now uses the packaged app version, withv2.1.1as the fallback. - Speakers tab layout corruption. The Low Latency button added in 2.1.0 was crammed into the Wall of Sound row's left control group, widening it and pushing the audio-output pills off the right edge. The button is removed from the Speakers tab; latency is controlled by Settings > Audio > Speed. The Wall of Sound row is no longer clipped.
Unchanged from 2.1.0
- Fast plain-audio custom receiver path for the lowest-latency Nest route.
- Google Home stereo pair = true stereo on two Minis via firmware-locked L/R.
- EQ presets and Speed profiles in Settings > Audio.
- L/R volume pairing, instant cached speaker list, reconnect-after-unlock, stale-FFmpeg init-segment fix.
Release State
- Public release page:
https://github.com/Kepners/pcnestspeaker-releases/releases/tag/v2.1.1. - Website installer route:
https://www.pcnestspeaker.app/download/windows/setupredirects to the GitHublatest/download/PC-Nest-Speaker-Setup.exeasset, so it serves the current release. - Setup EXE:
218924773bytes, SHA256715B783CD8B8B1D47EE0083F7F1ED59C86167EF30E4258AB5F45EF1C49901F19. - Portable EXE:
215743444bytes, SHA256B96008D9CF461C5119E096DDE169EDF9DC8CD106F6C699106E8BE539E98CBA9E. - Build commit:
950c0da. - Local build verification 2026-07-09: packaged
app.asarcontains the dynamicget-app-versionpath,v2.1.1footer fallback, and no stalev2.0.0 - A productfooter string. - Verified live 2026-07-09: website route download-back returned
218924773bytes with SHA256715B783CD8B8B1D47EE0083F7F1ED59C86167EF30E4258AB5F45EF1C49901F19. - Caveat: this same-version reissue has not had a clean-machine fresh-install test.
v2.1.0
PC Nest Speaker 2.1.0
Low-latency fast-receiver path restored and hardened, true stereo guidance, and new audio controls.
Highlights
- Fast receiver restored. The custom audio receiver (
4B876246) was re-broken by an MSE-first regression; it now uses the proven plain-<audio>path again — ~0.5 s startup on Nest Mini, the fastest reliable path. - True stereo on two Minis = Google Home stereo pair. Pair the two speakers in the Google Home app; the pair shows as one device and Google's firmware sample-locks Left/Right. Cast to the pair with the fast receiver for phase-perfect stereo at low latency. (Driving two separate speakers with the same stream causes audible comb-filter "phasing" and is not a stereo solution — see BRAIN.md principle 12.)
- ⚡ Low Latency button on the Speakers tab — one tap for the snappiest pause/play (best for video / YouTube).
- Speed setting (Fastest / Fast / Balanced / Stable) and EQ presets (Flat / Bass Boost / Loud & Clear / Voice / Warm) tuned for small speakers — now in Settings → Audio.
- L/R volume pairing — the volume slider sets both fast-pair speakers to the same level.
- Faster startup — the speaker list now appears instantly from a cache while a fresh scan refreshes in the background (was a 7–11 s wait).
- Reliability fixes: a stale-FFmpeg race that corrupted the stream header (and caused silent re-pairs) is fixed; the disruptive auto re-sync that chimed and stopped music is removed; reconnect-after-unlock restores the fast pair.
Notes
- Env-gated latency diagnostics remain off by default.
- The experimental per-member group fast path stays fenced behind
PCNEST_GROUP_FAST_CUSTOM=1; the recommended dual-Mini stereo path is a Google Home stereo pair.
Release State
- Public release page:
https://github.com/Kepners/pcnestspeaker-releases/releases/tag/v2.1.0. - Website installer route:
https://www.pcnestspeaker.app/download/windows/setup(302-redirects to the GitHublatest/download/PC-Nest-Speaker-Setup.exeasset, so it always serves the current release).
v2.0.0
PC Nest Speaker 2.0.0 - group audio baseline
Version 2.0.0 makes the proven Cast Audio Group path the default and ships the warm PC Nest Speaker colour system.
Highlights
- Cast Audio Groups now use the Default Media Receiver on the group itself, so the group leader opens one WebM/Opus HTTP stream and Google Cast handles native member sync.
- WebM/Opus HTTP audio defaults to 320k at 48 kHz stereo.
- Reissued build includes Stream Monitor wiring for the v2 HTTP WebM/Opus path: bitrate, data sent, connection state, and visualizer activity now come from actual bytes written to connected Cast clients.
- A subtle 1.05 signal lift is applied by default for a brighter perceived sound without changing the Windows volume model.
- The experimental per-speaker group receiver path is disabled by default and remains behind
PCNEST_GROUP_FAST_CUSTOM=1. - The app UI keeps the existing PC Nest Speaker logo treatment and applies the warm cream, pink, green, and ink palette.
- Footer and package metadata now use
v2.0.0andKepnersen on X.com.
Trial and licensing
- The 1-hour streaming trial remains in place.
- Trial state is still stored in encrypted, signed local usage data.
- Licence keys remain
XXXX-XXXX-XXXX-XXXXuppercase hex keys. - Licence activation still validates against
https://www.pcnestspeaker.app/api/validate-license. - A valid licence still bypasses trial expiry.
Customer build contents
The Windows release build is expected to include:
- FFmpeg
- MediaMTX
cast-helper.execast-daemon.exeaudioctl.exe- SoundVolumeView
- VB-Cable driver files
- Equalizer APO installer
- installer diagnostic helpers
Verification performed
- Renderer JavaScript syntax check passed.
- Main-process JavaScript syntax check passed.
- Usage tracker syntax check passed.
- Preload JavaScript syntax check passed.
- Static release-gate checks passed for 3600-second trial duration, packaged trial blocking, licence activation, production licence API URL, preload licence IPC, and renderer licence UI.
- Full Windows build completed for installer and portable artifacts.
- Packaged
app.asarwas checked for the colour-only UI, v2 footer, one-hour trial constants, and licence API wiring. - Reissued packaged
app.asarwas checked for the HTTP Stream Monitor stats wiring. - Unpacked build resources were checked for FFmpeg, MediaMTX, Python cast helpers, audioctl, SoundVolumeView, VB-Cable files, Equalizer APO, and installer tools.
- User clean-install test result accepted as release gate: loud, fast, and reporting
2.0.
Published release
- Published on 2026-05-18 as
v2.0.0. - Public release page:
https://github.com/Kepners/pcnestspeaker-releases/releases/tag/v2.0.0. - Website installer route:
https://www.pcnestspeaker.app/download/windows/setup. - Browser download filename:
PC-Nest-Speaker-Setup-2.0.0.exe. - Setup EXE:
218924631bytes, SHA25657E077551916639D3E9C02100E5C0303C76364915FCA6FFDE5B7BA8967138E28. - Portable EXE:
215743266bytes, SHA2566C7FBCA9A7B5DC281C3119E2B89C6B24ECE89D091ED978AC3E4D2AAB94C98B64. - Live route proof after Caddy reload:
HTTP 200,Content-Length: 218924631,Content-Disposition: attachment; filename="PC-Nest-Speaker-Setup-2.0.0.exe". - Full public-route download hash matched the local setup EXE hash.
v1.5.9 — group L/R sync fix
PC Nest Speaker 1.5.9
Fixes the long-standing L/R sync drift on Cast Audio Groups ("right speaker is faster than left" by ~2 s).
What was wrong
Pre-1.5.9 group flow: launch our custom Audio Receiver 4B876246 on each group member individually, send each the same WebM/Opus URL, and let each <audio> element pull the stream independently. Each Mini's <audio> element pre-rolled at its own pace → the playheads drifted apart over seconds.
The architectural reason was correct in the source comment: "Cast Groups can't run custom receivers — only individual devices can." So we routed around groups entirely and treated members as two independent sinks. Functionally it played audio on both, but the platform's sync mechanism never engaged.
What 1.5.9 changes
For Cast Audio Groups, route through the Default Media Receiver (CC1AD845) which can run on a group, and let the group's leader Mini handle native L/R fan-out:
- Start the WebM/Opus HTTP audio server on
:8766/audio.webm(unchanged) - Cast that URL to the group itself, not its members, via
pychromecast.media_controller.play_media(url, "audio/webm; codecs=\"opus\"", stream_type=LIVE) - The group's leader Mini fetches the URL once and broadcasts decoded audio to all members through Cast Audio's internal sync protocol — phase-aligned playout
Single Minis (non-group) continue to use the custom 4B876246 Audio Receiver path (it's working and gives us pcm-status diagnostics we still want for individual devices).
Trade-offs
| Single Mini path (unchanged) | Group path (new in 1.5.9) | |
|---|---|---|
| Receiver | Custom Audio Receiver 4B876246 |
Default Media Receiver CC1AD845 |
| Latency | ~1 s | ~1–1.5 s (DMR has its own jitter buffer; we'll measure) |
| L/R sync | N/A | Native, phase-aligned |
| Force-relaunch on cast | yes | no (DMR cycles naturally) |
| pcm-status diagnostics back to PC | yes | no |
| Pause/resume | custom IPC | standard Cast media controls |
If group-mode latency turns out worse than the per-member approach, we'll need a different fix — but that's a real measurement we can't make until the L/R drift is gone.
Files changed
src/main/electron-main.js— group path in the streaming dispatcherpackage.json— version bump
What you'll see in the log
[Group] "Study group" → DMR cast (native L/R sync via group leader)
[Group] Capture device: CABLE Output (...)
[AudioHttp] HTTP audio server listening on http://0.0.0.0:8766/audio.webm
[Group] HTTP server: http://192.168.50.49:8766/audio.webm
[Group] Casting URL to "Study group" via DMR…
[Group] ✓ "Study group" playing — leader handles L/R sync natively
Compared to 1.5.8 which showed [PCM] Launching second group member "Right speaker" and two separate receiver-status streams.
Confirmed unchanged from 1.5.8
- Plain
<audio src=>path on individual Minis - WebM/Opus 192k VBR encoding, 20 ms cluster size (1.5.3 tuning)
- Volume sync to all targets at fire-time (1.5.2 fix)
- Receiver page cache-bust meta tags (1.5.8)
- TV/Shield WebRTC + HLS paths
Known follow-ups
- v1.5.10: Pause/resume snappier — keep
<audio>element alive on pause instead of tearing down the HTTP connection (saves ~1 s on resume on individual Minis). DMR group path already has standard pause/resume primitives. - v1.5.11: Discovery 7.6 s → ~3 s — parallelise group-member resolution.
v1.5.8 — audio-restore hotfix (disable MSE, cache-bust receiver)
PC Nest Speaker 1.5.8 — audio-restore hotfix
Receiver-only change. MSE attempt is disabled. The dispatcher routes straight to the plain <audio src=> path that has worked since 1.5.0.
Why
Real-device testing of 1.5.6 and 1.5.7 on Nest Mini showed the receiver hanging forever at mse-fetch-start with no fallback ever firing — even after the 1.5.7 watchdogs were added. Most likely cause is the Cast Audio Chromium runtime caching the old (no-watchdog) receiver HTML despite force_relaunch, or the runtime not honoring setTimeout/AbortController.abort() during a hung fetch(). Either way, the user got no audio.
1.5.8 is purely about restoring playback. No latency improvement claims. Latency on 1.5.8 ≈ 1.5.5.
What's still in the code
connectHttpPcmMse() stays in receiver-audio.html for now. The dispatcher no longer calls it — it's unreachable. Will revisit once the research agent reports back on:
- Whether
XMLHttpRequest+responseType="arraybuffer"+onprogressworks for incremental chunk delivery on Cast Audio (wherefetch().body.getReader()doesn't), or - Whether to pivot to the owntone-server pattern — Google's built-in mirroring receiver
85CDB22F+ Cast RTP / Opus /targetDelay=400. That's the only open-source path proven to hit ~400 ms total latency on Cast Audio, but it's a 1–2 week transport rewrite.
If audio is still dead after upgrading
The Cast Audio runtime caches receiver HTML (HTTP Cache-Control: max-age=600 from GitHub Pages). To force a fresh fetch:
- Open the Google Home app, find the Nest Mini, hold the icon → "Restart". Or unplug it for 10 seconds.
- Cast again from PC Nest Speaker.
- The fresh receiver load will pick up the 1.5.8 receiver code.
Files changed
pcnestspeaker-receiver/receiver-audio.html— dispatcher routes straight to<audio>pathpackage.json— version bump
v1.5.7 — hotfix: guarantee MSE fallback (1.5.6 silent freeze)
PC Nest Speaker 1.5.7 — hotfix
1.5.6 introduced a regression: on Cast Audio, await fetch() can hang forever without ever resolving headers (the historical Cast Audio Chromium quirk noted in CLAUDE.md as "request opens, headers never resolve to JS"). The MSE path's first-byte watchdog was armed after fetch() returned, so when fetch hung the watchdog never armed, the function awaited indefinitely, the caller's catch never ran, and the <audio> fallback never fired → user got no audio at all.
Server-side log confirmed bytes were flowing on the socket (453 B init segment sent, bitrate climbed to ~228 kbps), but the JS fetch() Promise never resolved with the response object.
What 1.5.7 changes (receiver only)
Two layers of watchdog so the fallback to plain <audio> always fires:
- Inner — race
fetch()against a 2.5 s timeout that callspcmAbort.abort()and rejects. - Outer — master watchdog wraps the whole MSE attempt at 4 s. Even if
reader.read(),appendBuffer(), orsourceopenwere the hanging step instead offetch(), the master watchdog still trips fallback.
Even on a Cast Audio runtime where AbortController.abort() is itself broken, Promise.race rejects on schedule, the caller's catch block runs, disconnectHttpPcm() cleans MSE state, and the plain <audio> path takes over. Audio is restored within ~5 s of pressing Play in the worst case, vs. silence forever in 1.5.6.
What you'll see in the log
If MSE works on this runtime (best case):
mse-fetch-start → mse-fetch-headers → mse-first-byte → mse-canplay → mse-playing
mse-seek-probe { seek_works: true|false }
If MSE hangs (the 1.5.6 silent-failure case, now non-silent):
mse-fetch-start
mse-fallback-to-audio reason=fetch watchdog 2500ms ← NEW
audio-canplay → audio-playing ← same path as 1.5.5, audio plays
The reason= field tells us whether fetch() hangs, the master watchdog tripped, or some other step is the blocker. That's the diagnostic signal that replaces the silent freeze.
Plan B if MSE is fundamentally broken on Cast Audio
Replace fetch().body.getReader() with XMLHttpRequest + progress events. XHR2 has been on Chromium longer and the Cast Audio runtime is more likely to honor it. Will only attempt this if 1.5.7 logs confirm fetch() is the specific blocker (not the master watchdog tripping on something later).
Files changed
pcnestspeaker-receiver/receiver-audio.html— fetch race + master watchdogpackage.json— version bump
Desktop binaries unchanged from 1.5.6 functionally; rebuild for version-string parity.
v1.5.6 — receiver MSE+SourceBuffer (live-edge seek)
PC Nest Speaker 1.5.6
The receiver is the change. Desktop bytes are unchanged from 1.5.5 except the version string — the work all lives in receiver-audio.html on GitHub Pages, which the Cast SDK reloads on every cast (force-relaunch from 1.5.0 onwards).
What changed — receiver-side
MSE + SourceBuffer path (preferred, with <audio> fallback)
Problem. Plain <audio src=stream> on Cast Audio runs an opaque internal jitter buffer we can't read or write. Steady-state latency floored at ~1–1.5 s and currentTime writes against a live HTTP-chunked source are likely silent no-ops (per MDN, and confirmed by absence of a seek-probe in v1.5.4/1.5.5 logs because we never had a chance to fire one).
Fix. New connectHttpPcmMse() is now the preferred path:
MediaSource+addSourceBuffer('audio/webm; codecs="opus"')withmode='sequence'.fetch().body.getReader()pumps WebM clusters into the SourceBuffer.- A 250 ms drift loop calls
sb.remove(0, currentTime - 0.5s)to trim history andaudio.fastSeek(buffered.end - 0.2s)to push the playhead toward the live edge when we lag. - One-shot
mse-seek-probereports back whether the seek inside the MSE buffer actually moves the playhead.
Watchdog + automatic fallback
Cast Audio Chromium has historically had fetch().body.getReader() stalls (the existing CLAUDE.md notes this). 1.5.6's MSE path arms a 3.5 s first-byte watchdog. If no bytes arrive — or any of MediaSource.isTypeSupported, sourceopen, addSourceBuffer, fetch, or appendBuffer fail — the receiver tears down MSE and falls through to the plain <audio src> path that's been working since 1.5.0. So this is strictly additive: best case we cut 300–700 ms off latency, worst case we land on the same path as 1.5.5.
Why this approach (research summary)
Inspired by:
- shaka-player #9872 — production live
SourceBuffer.remove()+ seek-to-live pattern - w3c/media-source #291 — documents the
seekablewindow afterremove() - owntone-server cast.c — the only open-source path proven to hit ~400 ms total latency on Cast Audio. They use Google's built-in mirroring receiver
85CDB22Fwith Cast RTP / Opus /targetDelay=400. If MSE doesn't crack it, that's where 1.5.7 goes — but RTP is a 1–2 week rewrite, so we test cheaper options first.
What you'll see in the desktop log
Where 1.5.5 only emitted audio-src-set / audio-loadedmetadata / audio-canplay / audio-playing, 1.5.6 will additionally emit (when MSE works):
mse-attempt
mse-src-set
mse-sourceopen
mse-sb-added
mse-fetch-headers
mse-first-byte
mse-canplay
mse-playing
mse-seek-probe { seek_works: true|false, ... } ← the answer we've been waiting for
mse-drift-resync / mse-drift-catchup ← drift management firing
If MSE fails for any reason you'll see mse-fallback-to-audio reason=... followed by the same audio-* events as 1.5.5.
Files changed
pcnestspeaker-receiver/receiver-audio.html—connectHttpPcmMse()+ dispatcher + capabilities probe extended withmse_isTypeSupported_webm_opuspackage.json— version bump
Desktop binaries are unchanged from 1.5.5 functionally; rebuilding only so the version string and "About" dialog match the receiver.
v1.5.5 — discovery dispatch hotfix (1.5.4 was a no-op)
PC Nest Speaker 1.5.5
Hotfix for 1.5.4 — the discovery speedup didn't actually take effect.
What was wrong in 1.5.4
1.5.4 changed discover_speakers(timeout=) from 5s default to 3s default, but the CLI entry point at the bottom of cast-helper.py had its own hardcoded fallback:
timeout = int(sys.argv[2]) if len(sys.argv) > 2 else 5electron-main.js calls runPython(['discover']) with no timeout argument, so the CLI dispatcher always fell through to 5, never reaching the function default. Net effect: the documented 5s→3s change in 1.5.4 was a no-op. Logs in 1.5.4 still printed Scanning network (timeout: 5s).
What 1.5.5 does
- CLI dispatcher default
5→3(matches function default). - That's it. No other changes.
Confirming the fix
The discovery log line should now read Scanning network (timeout: 3s) and "Slow discovery" warnings should drop from ~7.6s into the ~5s range.
Everything else from 1.5.4 (receiver seek-probe + fastSeek(), group_cc.wait 5→3s) is unchanged and was already correct in the live receiver — the v1.5.4 release just didn't pull the cold-start savings the desktop side promised.
Files changed
src/main/cast-helper.py— CLI dispatch defaultpackage.json— version bump
v1.5.4 — pairing speed + seek-probe diagnostic
PC Nest Speaker 1.5.4
Pairing-speed pass + a receiver-side diagnostic to confirm whether Chromium on Cast Audio actually honors live-stream seeks.
What changed
Desktop — cast-helper.py (pairing speed)
| Knob | 1.5.3 | 1.5.4 | Effect |
|---|---|---|---|
discover_speakers(timeout=) |
5 s | 3 s | mDNS responses arrive in 1–2 s on a healthy LAN; the extra 2 s of "be safe" was a flat tax on every cold cast |
group_cc.wait(timeout=) |
5 s | 3 s | Group control sockets open in well under 1 s; reduces group-resolve stage |
Net: ~2–4 s shaved off pairing in the common case. If a slow device (Shield, distant Mini) misses the window, Refresh is one click.
Receiver — receiver-audio.html (seek-probe + fastSeek)
Why this is here: prior to 1.5.4 the drift management (TARGET_LAG / SOFT_LAG / HARD_LAG, see 1.5.3 notes) writes to audio.currentTime and audio.playbackRate to keep the receiver close to the live edge. Per MDN, Chromium-family browsers may treat live HTTP streams as non-seekable, in which case those writes are silent no-ops and the entire drift envelope is fiction.
1.5.4 adds:
- A one-shot seek-probe the first time lag exceeds 0.5 s. It records
seekable.start/end,buffered.end, the seek target, the seek method (fastSeekorcurrentTime), andcurrentTime100 ms later. The result is reported back to the desktop over the Cast custom namespace aspcm-status: seek-probe { … }so we can read the actual behavior on real Nest hardware, not assume. audio.fastSeek()is now used in the drift hard-correction path when available — it's the documented fast path for non-seekable / live media in WHATWG, where regularcurrentTimewrites can be ignored.
If the probe shows seek_works: false, the latency floor is structural — bury the drift code or replace it with a network-level catch-up. If seek_works: true, current code is correct and the floor is buffer-related (cluster size, decoder lookahead).
Files changed
src/main/cast-helper.py— discovery + group_cc timeout reductionspcnestspeaker-receiver/receiver-audio.html— seek-probe + fastSeek (already live on GitHub Pages)package.json— version bump
Confirmed unchanged from 1.5.3
- 192 kbps VBR Opus with
-application audio - 10 ms
frame_duration, 20 mscluster_time_limit - Volume fan-out to all group members
- WebM init segment captured + prepended for late-joining clients
- Force-relaunch of receiver page on every cast
Sources used
PC Nest Speaker 1.5.3 — responsive mode (4-knob latency tighten)
PC Nest Speaker 1.5.3
"Responsive mode" — coordinated 4-knob latency tighten across server and receiver.
What changed
Server (http-pcm-server.js)
| Knob | 1.5.2 | 1.5.3 | Effect |
|---|---|---|---|
-frame_duration |
20 ms | 10 ms | Halves Opus encoder lookahead (~10 ms latency). Per-frame overhead grows slightly; encoding efficiency at 192 k VBR drops ~3-5% — not perceptually audible |
-cluster_time_limit |
40 ms | 20 ms | WebM clusters now carry 2 × 10 ms frames instead of 2 × 20 ms. Receiver sees fresh data twice as often |
Receiver (receiver-audio.html)
| Knob | 1.5.2 | 1.5.3 | Effect |
|---|---|---|---|
TARGET_LAG |
0.30 s | 0.18 s | Direct subtract from steady-state pause/resume latency |
SOFT_LAG |
0.80 s | 0.50 s | playbackRate = 1.05 engages earlier — drift corrected before audible |
HARD_LAG |
1.50 s | 0.90 s | Hard-seek to live edge fires sooner |
Estimated total impact
~150–700 ms reduction on a typical pause/resume cycle, depending on how much drift had accumulated.
Trade-off — when 1.5.3 might NOT be the right choice
1.5.3 is tuned for clean home LAN. On a noisy Wi-Fi (interference, contention, distant access point) the smaller TARGET_LAG (180 ms) leaves less headroom for jitter — you'll hear more micro-glitches as drift management hard-seeks more often.
If 1.5.3 sounds glitchy where 1.5.2 was clean, it's a network problem, not a build regression. Tightening the envelope made us notice it. Two options if that happens:
- Stay on v1.5.2 for noisy networks
- Future: expose TARGET_LAG / HARD_LAG as a setting so users can pick "responsive" vs "stable" themselves
Confirmed unchanged from 1.5.1/1.5.2
- Audio quality bitrate: 192 kbps VBR with
-application audio(music-tuned) - Volume sync fan-out across all group members (1.5.2 fix)
- Force-relaunch of receiver page on every cast (so new receiver code lands)
- WebM init segment captured + prepended to each new client (the fix without which MSE/
<audio>silently parks data)
Files changed
src/main/http-pcm-server.js— FFmpeg args (frame_duration, cluster_time_limit)pcnestspeaker-receiver/receiver-audio.html— drift management constantspackage.json— version bump