VoIP.info Guide

Browser webphones: microphone permission and audible-call checks

Trace browser calling through secure origin, capture policy, device selection, SIP session, remote media and playback before changing the network.

Reviewed 2026-10-16Current SIP.js release, migration, repository, Simple User, mobile and security-policy documentation plus MDN, W3C and Asterisk references reviewed October 8, 2026; no package, application, browser, mobile wrapper, PBX, permission, notification path, media path or call was inspected or laboratory-testedIntermediateDocumentation based · not lab tested

Choose the application boundary

A browser webphone needs a user interface, a limited SIP identity, call routing and a support owner as well as a signaling library. The current SIP.js Simple User guide demonstrates explicit connect and register operations, hold and unhold, and DTMF through SIP INFO. The repository separately describes broader transfer, RFC 2833 DTMF and multi-session capabilities. Choose SimpleUser, SessionManager or the full API deliberately rather than treating a demo, navigation label or repository feature list as one finished phone contract.

Keep the browser release, application build, SIP library package, selected API layer and PBX version in the acceptance record. SIP.js 0.21.2 remains labelled Latest, but the repository's published security-policy table names 0.19.x as supported; preserve that unresolved policy boundary instead of inventing support for the selected package. A library capability is not a tested service, emergency plan or guarantee of incoming-call availability.

Sangoma's browser client is an application tied to supported Sangoma PBX systems, not just a WebRTC library. The Sangoma Phone guide separates direct or UCP-launched browser access from the installed desktop client, and keeps optional queue, transcription and chat claims attached to their PBX permission, module and subscription requirements.

Diagnose capture before changing SIP

Microphone capture uses navigator.mediaDevices.getUserMedia in a secure context and requires permission. Record the API and error name: NotAllowedError can reflect a permission denial or policy restriction; NotFoundError indicates no matching input; NotReadableError points to a device-access failure; OverconstrainedError identifies requirements that no candidate satisfies. A prompt the user ignores can leave the promise pending, so a waiting screen should offer a clear cancel path instead of claiming the request failed.

First check the actual origin, requested audio constraints and browser or operating-system permission. Changing a SIP password or RTP rule does not repair a blocked microphone request.

Inspect embedding policy separately

An embedded client has a parent-document boundary. The microphone Permissions-Policy default allowlist is self; a cross-origin frame needs deliberate delegation within the parent policy and frame permissions. A policy block can reject capture without showing a user prompt. Inspect the returned parent headers, frame origin and allow policy before asking the user to keep accepting permissions.

A policy that permits capture does not grant user consent. Policy support also varies across browsers: use the exact supported browser and embedding arrangement for acceptance, rather than treating one header as universal enforcement.

Treat a device list as permission-scoped

enumerateDevices does not inventory every physical device unconditionally. Its results omit devices excluded by policy or permission, and its documented requirements include a secure context, an active document and visible document state. Default capture devices appear first. A missing non-default headset entry is therefore not sufficient evidence that the headset is absent or broken.

Record the selected input and the application state when the list was obtained. Repeat selection after the intended permission flow, then check a short conversation with the actual headset. Keep device identifiers out of public incident reports.

Input enumeration and output selection are also different interfaces. The wrong-audio-device diagnostic preserves the browser's permission-scoped input list, user-mediated non-default output choice, remote media attachment and audible result without treating a SIP session as playback proof.

Separate receiving media from playing sound

SIP.js leaves substantial media handling to the application. Its full-API guide attaches remote receiver tracks to a MediaStream and assigns that stream to the media element. Session establishment, an attached stream and audible playback are separate observations. Capture session state and the remote-track attachment before resetting a silent call.

HTMLMediaElement.play returns a promise. Script-started playback can be rejected with NotAllowedError when browser policy prevents it; a call timer or received track does not override that policy. Handle the result, expose an explicit action to start sound when needed, and make the visible playback state follow the actual result. A fulfilled promise proves playback started, not that the correct headset produced intelligible conversation.

Accept a complete browser calling path

Use a contained endpoint and record each stage: page identity and capture permission; selected microphone; WSS connection; SIP authentication and routing; negotiated media; attached remote track; playback result; and an intelligible conversation in both directions. Asterisk documents separate HTTP/WebSocket, PJSIP transport, endpoint, auth and AoR responsibilities. Follow Asterisk WebRTC integration for that server boundary.

Include an incoming call, permission denial and retry, headset reconnection, hangup cleanup, an idle interval and the intended closed-tab or sleeping-device fallback. These are proposed acceptance cases, not results obtained for this guide. No browser, microphone, headset, client, PBX, protected session, emergency route or live call was tested.

Keep browser SIP libraries distinct

The JsSIP guide now sits beside SIP.js as a separate implementation choice. Neither library supplies the finished phone experience, credentials, PBX policy, background wake-up, media rendering or operational lifecycle by itself, and their APIs or version claims are not interchangeable.

Treat Wave Web 1.0.35.7 as a UCM-delivered browser client

Grandstream lists Wave Web 1.0.35.7 as built into the UCM6300 series. SSO, AI-derived data, call notes, retention behavior and WhatsApp calling therefore depend on the server and integration state as well as browser permissions and session behavior. A matching Wave family label does not make the browser path equivalent to Desktop or mobile.

Keep mobile browser compatibility inside the foreground boundary

SIP.js documents Chrome and Firefox on Android as WebRTC-capable and compatible with its web applications. That does not establish background registration, push wake-up, locked-screen ringing, iOS behavior or survival after the page is suspended or closed. Record the exact browser, operating system, application state and fallback route, then test the intended idle and network-change cases rather than transferring a foreground compatibility statement into a mobile-service promise.

Preserve INVITE handling and ringtone playback as different states

Use the browser no-ring diagnostic when an incoming call may have reached the application but produced no audible alert. onInvite, visible controls, play() or AudioContext outcome, answer and remote media remain separate evidence.

Keep Webex browser calling inside its documented scope

Cisco documents meetings and free Call on Webex in supported browsers. The Webex App guide does not extend that statement to every Unified CM, Webex Calling or hosted-provider desktop feature.

Sources & applicability

Primary references for the technical details above. Operational examples and planning checklists are VoIP.info editorial guidance.

Examples require adaptation to your topology. No live PBX or hardware testing is claimed.