zebra-report: zebra-audio music mode (disable voice isolation)
This commit is contained in:
parent
cb0e5454b1
commit
d22c43a2e3
1 changed files with 44 additions and 5 deletions
|
|
@ -88,6 +88,9 @@
|
|||
<div class="dot" id="dot-path"></div>
|
||||
<span id="path-status" class="status-line">path: —</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="note"><input type="checkbox" id="music-mode"> music mode — raw mic, no echo/noise cancellation (for playing audio through it)</label>
|
||||
</div>
|
||||
<p class="note">
|
||||
both partners type the same code and hit call. audio is end-to-end
|
||||
encrypted (DTLS-SRTP), peer-to-peer when the network allows, relayed through
|
||||
|
|
@ -173,14 +176,44 @@ async function refreshTurnCred(){
|
|||
}
|
||||
|
||||
/* ---- audio ---- */
|
||||
let micStream = null, audioCtx = null;
|
||||
let micStream = null, audioCtx = null, musicMode = false;
|
||||
/* voice mode = echo-cancel + noise-suppress + auto-gain (clean speech).
|
||||
* music mode = all of that OFF so music/audio passes through un-mangled. */
|
||||
function micConstraints(){
|
||||
return musicMode
|
||||
? { echoCancellation:false, noiseSuppression:false, autoGainControl:false }
|
||||
: { echoCancellation:true, noiseSuppression:true, autoGainControl:true };
|
||||
}
|
||||
function tagTrack(t){ if (t) t.contentHint = musicMode ? 'music' : 'speech'; }
|
||||
async function setSenderBitrate(sender){
|
||||
if (!sender) return;
|
||||
try {
|
||||
const p = sender.getParameters();
|
||||
if (!p.encodings || !p.encodings.length) p.encodings = [{}];
|
||||
p.encodings[0].maxBitrate = musicMode ? 160000 : 40000; /* bits/s */
|
||||
await sender.setParameters(p);
|
||||
} catch(_){}
|
||||
}
|
||||
async function getMic(){
|
||||
if (micStream) return micStream;
|
||||
micStream = await navigator.mediaDevices.getUserMedia({
|
||||
audio: { echoCancellation:true, noiseSuppression:true, autoGainControl:true }, video:false
|
||||
});
|
||||
micStream = await navigator.mediaDevices.getUserMedia({ audio: micConstraints(), video:false });
|
||||
tagTrack(micStream.getAudioTracks()[0]);
|
||||
return micStream;
|
||||
}
|
||||
/* switch voice<->music mid-call: re-acquire the mic and hot-swap the track on
|
||||
* the live connection (no renegotiation), preserving mute state */
|
||||
async function applyMicMode(){
|
||||
const ns = await navigator.mediaDevices.getUserMedia({ audio: micConstraints(), video:false });
|
||||
const nt = ns.getAudioTracks()[0];
|
||||
tagTrack(nt); nt.enabled = !muted;
|
||||
if (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); }
|
||||
}
|
||||
if (micStream) micStream.getTracks().forEach(t=>t.stop());
|
||||
micStream = ns;
|
||||
meterFor(micStream, 'meter-mic');
|
||||
}
|
||||
function meterFor(stream, fillId){
|
||||
if (!audioCtx) audioCtx = new (window.AudioContext||window.webkitAudioContext)();
|
||||
const src = audioCtx.createMediaStreamSource(stream);
|
||||
|
|
@ -214,7 +247,8 @@ function setPath(msg, cls){ const e=$('path-status'); e.textContent=msg; e.class
|
|||
async function ensurePC(){
|
||||
if (pc) return pc;
|
||||
pc = new RTCPeerConnection(rtcConfig);
|
||||
for (const tr of micStream.getTracks()) pc.addTrack(tr, micStream);
|
||||
for (const tr of micStream.getTracks()) { tagTrack(tr); pc.addTrack(tr, micStream); }
|
||||
setSenderBitrate(pc.getSenders().find(s=>s.track && s.track.kind==='audio'));
|
||||
pc.ontrack = (ev) => {
|
||||
const stream = ev.streams[0] || new MediaStream([ev.track]);
|
||||
$('remote-audio').srcObject = stream;
|
||||
|
|
@ -353,6 +387,11 @@ $('btn-call').addEventListener('click', startCall);
|
|||
$('btn-hangup').addEventListener('click', hangup);
|
||||
$('btn-mute').addEventListener('click', toggleMute);
|
||||
$('rdv-code').addEventListener('keydown', e=>{ if(e.key==='Enter'){ e.preventDefault(); startCall(); } });
|
||||
$('music-mode').addEventListener('change', async (e)=>{
|
||||
musicMode = e.target.checked;
|
||||
logLine('', 'mic mode: '+(musicMode?'MUSIC — raw, no voice isolation':'VOICE — echo/noise cancel'));
|
||||
if (micStream){ try { await applyMicMode(); } catch(err){ logLine('err','mic mode switch failed: '+err.message); } }
|
||||
});
|
||||
logLine('', 'ready — type a rendezvous code and call. mic stays muted to the room until connected.');
|
||||
})();
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue