zebra-spaces: applyConstraints + log effective mic settings — surfaces hidden filtering
When a PulseAudio monitor source is selected as the mic and music mode is toggled on, Firefox can silently apply its default audio-processing pipeline (EC/NS/AGC) regardless of the getUserMedia constraints. The broadcast then sounds 'cleaned up' instead of letting the source pass through transparently. Two fixes: - call track.applyConstraints(micConstraints()) after getUserMedia/replace. Some UAs honour applyConstraints when they silently ignored the initial request. Belt-and-suspenders. - log track.getSettings() so we can see what the UA actually applied — ec/ns/agc/channels/sampleRate. If applyConstraints didn't stick, the log shows it instead of failing silently.
This commit is contained in:
parent
1294e96f01
commit
3f43379e00
1 changed files with 22 additions and 3 deletions
|
|
@ -946,10 +946,28 @@ async function refreshMicList(){
|
|||
} catch(e){ logLine('err','could not list inputs: '+e.message); }
|
||||
}
|
||||
function tagTrack(t){ if (t) t.contentHint = musicMode ? 'music' : 'speech'; }
|
||||
/* Firefox sometimes ignores the EC/NS/AGC constraints at getUserMedia time
|
||||
* for non-mic sources (e.g. PulseAudio monitor) and applies its default
|
||||
* processing pipeline anyway. applyConstraints() after the fact tends to
|
||||
* stick. Log the actual settings so we can see what the UA ended up with —
|
||||
* silent disagreement between requested and effective constraints is what
|
||||
* makes music-mode-on-a-monitor-source sound 'cleaned up'. */
|
||||
async function enforceMicConstraints(track){
|
||||
if (!track) return;
|
||||
try { await track.applyConstraints(micConstraints()); } catch(e){ logLine('', 'applyConstraints rejected: '+e.message); }
|
||||
try {
|
||||
const s = track.getSettings();
|
||||
logLine('', 'mic track settings: '+JSON.stringify({
|
||||
ec: s.echoCancellation, ns: s.noiseSuppression, agc: s.autoGainControl,
|
||||
ch: s.channelCount, hz: s.sampleRate, dev: (s.deviceId||'').slice(0,8)
|
||||
}));
|
||||
} catch(_){}
|
||||
}
|
||||
async function getMic(){
|
||||
if (micStream) return micStream;
|
||||
micStream = await navigator.mediaDevices.getUserMedia({ audio: micConstraints(), video:false });
|
||||
tagTrack(micStream.getAudioTracks()[0]);
|
||||
const t = micStream.getAudioTracks()[0];
|
||||
tagTrack(t); await enforceMicConstraints(t);
|
||||
return micStream;
|
||||
}
|
||||
async function setSenderBitrate(sender){
|
||||
|
|
@ -998,6 +1016,7 @@ async function applyMicMode(){
|
|||
const ns = await navigator.mediaDevices.getUserMedia({ audio: micConstraints(), video:false });
|
||||
const nt = ns.getAudioTracks()[0];
|
||||
tagTrack(nt); nt.enabled = !muted;
|
||||
await enforceMicConstraints(nt);
|
||||
async function swap(pc){
|
||||
const sender = pc.getSenders().find(s=>s.track && s.track.kind==='audio') || pc.getSenders()[0];
|
||||
if (sender){ try { await sender.replaceTrack(nt); } catch(_){} setSenderBitrate(sender); }
|
||||
|
|
@ -1707,8 +1726,8 @@ logLine('', 'ready — pick a handle, type a rendezvous code, enter the space');
|
|||
|
||||
<footer style="margin:2.2rem auto 0;font-size:0.65rem;color:#999;line-height:1.7;word-break:break-all;font-family:monospace">
|
||||
<span id="pi-seal" style="color:#777;cursor:default;user-select:none" title="">page integrity</span> · built <span class="stamp-date">2026-06-02</span><br>
|
||||
md5 <span class="stamp-md5">fe091219cd9ca42891eba2c5eeee35f3</span><br>
|
||||
sha256 <span class="stamp-sha">e5e7f467ae1a8badf689cbe653fe1b5607aff0eff1c92ce70be61eca616ae57a</span><br>
|
||||
md5 <span class="stamp-md5">4004c2acd2095e3db1654df18fb745cc</span><br>
|
||||
sha256 <span class="stamp-sha">0485fb4623fab71d8e956a80eac72d3c85d7326d8bae94f629121b105cd9944d</span><br>
|
||||
<span style="color:#bbb">hashes are of this page with these two fields zeroed — to verify, blank them and re-hash</span><br>
|
||||
<span style="color:#bbb">one self-contained file — <strong>save a copy</strong> and verify against these hashes; point at your own servers with ?signal= and ?turncred=, or <a href="host-your-own.html" style="color:#999">host your own community</a></span>
|
||||
</footer>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue