- Ya
- 26 Aprili 2026, 23:00 UTC
- Mwandishi
- kamo
- Ahadi ya
- 55d121c
Three coordinated fixes for the in-call audio path: 1. AbortError on remoteAudio.play() (visible in production console as "The play() request was interrupted by a new load request") was real: it meant zero audio at the speaker. Each session was reassigning the shared remote-audio element's srcObject in three places (prime → attach → ontrack), and every reassignment ran a load() that aborted the previous play() promise. Restructured SipJsSession to own ONE persistent MediaStream that is bound to the audio element in the constructor and never reassigned mid-call. Tracks are added to that stream as they negotiate (via getReceivers and pc.ontrack) instead of replacing the stream wholesale. attachRemoteAudio() and primeRemoteAudio() defensively re-bind to OUR stream only when a sibling session has stolen the binding (self-call loopback case), so the live session's audio actually reaches the speaker. 2. The connecting-state circle wasn't on the popup's true horizontal center because the Reject button still occupied its 60px slot in the flex row even after fading to opacity 0. Switched to absolute positioning: Answer button is anchored at translate(-50%, -50%) so its position never depends on Reject; Reject is anchored to the right edge at calc(50% + 24px) and slides toward center while fading out under isAccepting. 3. Outbound calls were silent during the 1-3 s ring period because Asterisk's early-media path doesn't always reach a browser SIP client as audible audio. Added a separate ringback Audio element in SoftphoneProvider that plays the same ringtone source while isConnecting && callDirection === 'outbound' && !isInCall. Routes through the speaker device (not the ringer device) and uses speakerVolume so it follows in-call audio preferences. Stops on Established / failed / cancelled. Primed during the same one-time audio-unlock click so it can play without user gesture every call.