Skip to content

Repository files navigation

WebMDR

Noise control for Sony headphones, in your browser.
No app, no account, no server: a static web page that talks to your headphones over Bluetooth.

Open WebMDR · Status · Known issues · Contributing

CI MIT License

Independent project; not affiliated with or endorsed by Sony. "WebMDR" is a working name, not a claim of trademark clearance.

What it does

  • Switch between Noise cancelling, Ambient sound and Off.
  • Set the Ambient level (live while you drag) and Voice passthrough.
  • Follow changes you make with the headphone buttons.
  • Show the firmware version the headphones report.

Every change is confirmed by reading the setting back from the headphones. If that can't be confirmed, the page says so instead of pretending it worked.

Use it

  1. Pair the headphones with your computer in the system Bluetooth settings.
  2. Open https://abnormal749.github.io/WebMDR/ in desktop Chrome. Other Chromium browsers such as Edge may work but are untested.
  3. Click Connect and pick your headphones.

Turn on Advanced (top right) for connection details, read-only/passive session modes and the protocol log. The log stays in the page: nothing is uploaded or stored.

The page only works while it is open; closing it disconnects.

Supported headphones

The protocol is chosen from the Bluetooth service the headphones expose, never from their name.

Protocol Tested in WebMDR Expected to work (listed by upstream, untested here)
Sony V2 WH-1000XM5 (firmware 2.5.1) WH-1000XM6, WF-1000XM4, WF-1000XM5, WF-1000XM6, WH-CH720N, ULT WEAR, LinkBuds S, newer WH-1000XM4 units
Sony V1 none WH-1000XM3, older WH-1000XM4 units

On V1 headphones the page asks you to enable the untested controls explicitly. If your model isn't in the tested column, a hardware report is the most useful contribution you can make.

Status

Last updated 2026-09-28.

Milestone State Evidence
Frame codec, session, noise-control logic Done Unit tests with a fake transport and fake time
Connect, initialize, read state Done on XM5 H-003, replayed in CI
Change settings, confirmed by read-back Done on XM5 NC / Ambient / Off, levels 1–20, voice passthrough (H-003, H-004)
Adopt headphone-button changes; handle power-off Done on XM5 H-005
Published site Done Tested from the GitHub Pages origin (H-005, H-006)
V1 protocol and other V2 models Code done Needs hardware reports
Firmware version display Done on XM5 Firmware 2.5.1 read in H-007/H-008

Hardware results are recorded in the evidence record. Unit tests are never counted as hardware validation.

Known issues and limitations

  • Reconnecting after a headphone power cycle can fail on macOS with Chrome 154. Page cleanup works, but an orphaned native RFCOMM channel can block the next open. Bluetooth disconnect/reconnect alone was unreliable. The optional local mode below recovered without restarting Chrome; the static website cannot perform this native handoff. Exact test results and limits.
  • The model can't be detected. Web Serial hides the Bluetooth name, and no reviewed Sony command returns the model, so the page shows the protocol and firmware instead.
  • Only one headset model has been tested. Some V2 models may use a different noise-control code; on those, the page stops at "not ready" without changing anything.
  • Browsers: desktop Chrome on macOS is tested. Windows, Linux and Android Chrome 138+ have the API but are untested. Safari and Firefox have no Web Serial.
  • Not tested: audio playback during a session, multipoint connections, sleep.
  • No background control: closing the page ends the control session. The optional recovery companion only assists failed connections.

Optional local recovery on macOS

The local companion enables refresh recovery for the tested Chrome/XM5 issue. It requires Node 24 and Xcode Command Line Tools:

npm ci
npm run build
npm run local:recovery -- --device "WH-1000XM5"

Open http://127.0.0.1:5173/WebMDR/ directly in Chrome and authorize the configured headset. Keep the terminal running. After a headset restart, wait for it to reconnect to the Mac, then refresh the page. The page reconnects and reads current state without replaying settings.

  • Recovery took 21–27 seconds in local tests. It briefly interrupts audio and pauses Chrome, with an independent 20-second resume watchdog.
  • If multiple Chrome processes are running, add --chrome-pid PID for the intended main browser process. Use only one authorized headset for local mode.
  • A failed recovery stops after one attempt. Check the terminal before pressing Reconnect again. Ctrl-C stops the companion.

The companion binds only to loopback, accepts authenticated same-origin requests, and installs no background service. This workaround is available only in local mode; it does not change Chrome or Bluetooth pairing. See H-008 for evidence and limits.

Contributing

Contributions are welcome, especially hardware reports for models other than the WH-1000XM5. See CONTRIBUTING.md for setup, the rules protocol code follows, and how to test with real headphones.

npm ci
npm run dev       # local server at http://localhost:5173
npm run verify    # type-check, tests, production build, dist checks (same as CI)

How it works

Static HTTPS page → Web Serial → Bluetooth RFCOMM → Sony control service
src/ui/          page and DOM (the only code that touches the DOM)
src/app/         controller: connection phases, one in-flight change, confirmation
src/features/    noise-control state, merging edits
src/protocol/    frame codec, session (ACKs, sequencing, timeouts), V1/V2 layouts, profiles
src/transport/   Web Serial port selection, open/close
test/            unit tests, fake transport, captured sessions replayed in CI

A browser write, a protocol ACK and a confirmed setting are treated as three different outcomes. The session runs one transaction at a time and lets ACKs bypass the queue. An ambiguous timeout is reported as "unknown" and never retried blindly. The technical review explains why.

Documentation

Document Contents
CONTRIBUTING.md Setup, workflow, pull-request checklist
CHANGELOG.md Changes in each release
AGENTS.md Protocol and architecture contract (for humans and coding agents)
docs/hardware-test.md Step-by-step test with real headphones
docs/device-matrix.md Hardware evidence records H-001 to H-008
docs/technical-review.md Frame format, session design, reasons for each rule
docs/sources.md Sources reviewed and what each supports
docs/reuse-manifest.md Every file adapted from third-party code

Privacy

The page has no backend and loads no third-party scripts; a strict content-security policy is applied to the build. Protocol data stays in the page. The protocol log is kept in memory only and shown only under Advanced.

License and credits

WebMDR is released under the MIT License.

The frame format and command layouts are adapted from Sony Device Center (MIT) at commit dea38969b501a4a167f330dff104414531e80eae. Its notice ships in THIRD_PARTY_NOTICES.txt and in the deployed site, and every adapted file is listed in the reuse manifest. No Gadgetbridge (AGPLv3) code is used; it was read for protocol facts only.

About

Noise control for Sony headphones in the browser, over Web Serial and Bluetooth. No app, no server.

Topics

Resources

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages