Microphone settings for Nekto.me, self-listening, settings apply after page refresh
// ==UserScript==
// @name Disable Auto Mic Adjustment & Self-Listening for Nekto.me
// @name:ru Отключение автонастройки микрофона и самопрослушивания для Nekto.me
// @name:uk Відключення автоналаштувань мікрофона та самопрослуховування для Nekto.me
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Microphone settings for Nekto.me, self-listening, settings apply after page refresh
// @description:ru Настройки микрофона для Nekto.me, самопрослушивание, настройки применяются после обновления страницы
// @description:uk Налаштування мікрофона для Nekto.me, самопрослуховування, налаштування застосовуються після оновлення сторінки
// @author t3ry4
// @match *://*nekto.me/*
// @grant GM_registerMenuCommand
// @grant GM_unregisterMenuCommand
// @grant GM_setValue
// @grant GM_getValue
// @license MIT
// ==/UserScript==
(function() {
'use strict';
let globalStream = null;
let enableLoopback = GM_getValue("enableLoopback", false);
let settings = {
autoGainControl: GM_getValue("autoGainControl", false),
noiseSuppression: GM_getValue("noiseSuppression", true),
echoCancellation: GM_getValue("echoCancellation", false),
gainValue: GM_getValue("gainValue", 1.5)
};
let menuIDs = [];
function updateMenu() {
menuIDs.forEach(id => GM_unregisterMenuCommand(id));
menuIDs = [];
menuIDs.push(GM_registerMenuCommand(
`🎤 Self-Listening: ${enableLoopback ? "✅ ON" : "❌ OFF"}`,
() => {
enableLoopback = !enableLoopback;
GM_setValue("enableLoopback", enableLoopback);
updateMenu();
}
));
menuIDs.push(GM_registerMenuCommand(
`📢 Auto Gain Control: ${settings.autoGainControl ? "✅ ON" : "❌ OFF"}`,
() => {
settings.autoGainControl = !settings.autoGainControl;
GM_setValue("autoGainControl", settings.autoGainControl);
updateMenu();
}
));
menuIDs.push(GM_registerMenuCommand(
`🔇 Noise Suppression: ${settings.noiseSuppression ? "✅ ON" : "❌ OFF"}`,
() => {
settings.noiseSuppression = !settings.noiseSuppression;
GM_setValue("noiseSuppression", settings.noiseSuppression);
updateMenu();
}
));
menuIDs.push(GM_registerMenuCommand(
`🔁 Echo Cancellation: ${settings.echoCancellation ? "✅ ON" : "❌ OFF"}`,
() => {
settings.echoCancellation = !settings.echoCancellation;
GM_setValue("echoCancellation", settings.echoCancellation);
updateMenu();
}
));
menuIDs.push(GM_registerMenuCommand(
`🔊 Self-Listening Volume: ${settings.gainValue.toFixed(1)}`,
() => {
let newGain = parseFloat(prompt("Enter volume level (0.1 - 3.0):", settings.gainValue));
if (!isNaN(newGain) && newGain >= 0.1 && newGain <= 3.0) {
settings.gainValue = newGain;
GM_setValue("gainValue", settings.gainValue);
updateMenu();
} else {
alert("Invalid value! Enter a number between 0.1 and 3.0");
}
}
));
}
updateMenu();
navigator.mediaDevices.getUserMedia = (function(originalGetUserMedia) {
return function(constraints) {
if (constraints && constraints.audio) {
if (constraints.audio === true) {
constraints.audio = {};
}
constraints.audio.autoGainControl = settings.autoGainControl;
constraints.audio.noiseSuppression = settings.noiseSuppression;
constraints.audio.echoCancellation = settings.echoCancellation;
}
return originalGetUserMedia.call(navigator.mediaDevices, constraints).then(stream => {
globalStream = stream;
if (enableLoopback) {
enableSelfListening(stream);
}
return stream;
});
};
})(navigator.mediaDevices.getUserMedia);
function enableSelfListening(stream) {
if (!stream || stream.getAudioTracks().length === 0) {
return;
}
const audioContext = new window.AudioContext();
const source = audioContext.createMediaStreamSource(stream);
const gainNode = audioContext.createGain();
gainNode.gain.value = settings.gainValue;
source.connect(gainNode);
gainNode.connect(audioContext.destination);
}
})();