console-snippet.js (2274B)
1 // StereoMic — quick-test version. Paste into Vesktop/web-Discord DevTools console 2 // (Cmd/Ctrl+Opt+I), then LEAVE and REJOIN voice. Feed a stereo source into your input. 3 // This is the same logic as the plugin (stereoMic/index.ts), for testing before you build. 4 (() => { 5 if (window.__stereoMic) { console.log("[StereoMic] already active (reload to re-apply)"); return; } 6 window.__stereoMic = true; 7 const BITRATE = 320000; // Opus avg bitrate. Max 510000. 8 9 function munge(sdp, tag) { 10 if (!sdp || !/opus/i.test(sdp)) return sdp; 11 const m = sdp.match(/a=rtpmap:(\d+)\s+opus\/48000\/2/i); 12 if (!m) return sdp; 13 const pt = m[1], lines = sdp.split(/\r?\n/); 14 let touched = false; 15 for (let i = 0; i < lines.length; i++) { 16 if (lines[i].startsWith(`a=fmtp:${pt} `)) { 17 let p = lines[i].slice(`a=fmtp:${pt} `.length); 18 const set = (k, v) => { p = new RegExp(`${k}=[^;]*`).test(p) 19 ? p.replace(new RegExp(`${k}=[^;]*`), `${k}=${v}`) : p + `;${k}=${v}`; }; 20 set("stereo", 1); set("sprop-stereo", 1); set("maxaveragebitrate", BITRATE); 21 lines[i] = `a=fmtp:${pt} ${p}`; touched = true; 22 } 23 } 24 if (touched) console.log("[StereoMic] munged " + tag + " (pt " + pt + ")"); 25 return lines.join("\r\n"); 26 } 27 28 for (const name of ["setLocalDescription", "setRemoteDescription"]) { 29 const orig = RTCPeerConnection.prototype[name]; 30 RTCPeerConnection.prototype[name] = function (desc, ...r) { 31 try { 32 if (desc && desc.sdp) { 33 const sdp = munge(desc.sdp, name); 34 desc = (typeof desc.toJSON === "function") ? { type: desc.type, sdp } : Object.assign({}, desc, { sdp }); 35 } 36 } catch (e) { console.warn("[StereoMic] munge err", e); } 37 return orig.call(this, desc, ...r); 38 }; 39 } 40 41 const md = navigator.mediaDevices, gum = md.getUserMedia.bind(md); 42 md.getUserMedia = function (c) { 43 if (c && c.audio) { 44 const a = (typeof c.audio === "object") ? Object.assign({}, c.audio) : {}; 45 a.channelCount = 2; a.echoCancellation = false; a.noiseSuppression = false; a.autoGainControl = false; 46 c = Object.assign({}, c, { audio: a }); 47 } 48 return gum(c); 49 }; 50 console.log("[StereoMic] console patch active — leave & rejoin voice."); 51 })();