IsmaelMartinez / teams-for-linux

Unofficial Microsoft Teams for Linux client
GNU General Public License v3.0
2.93k stars 239 forks source link

Disable mic autogain #664

Closed dagmoller closed 1 year ago

dagmoller commented 1 year ago

Is your feature request related to a problem? Please describe. Yes, needed to disable mic autogain.

Describe the solution you'd like Create an startup option (ex: --disable-autogain)

Additional context Just import the contents of this js file at browser session: https://raw.githubusercontent.com/joeywatts/disable-autogain-control-extension/master/disableAutogain.js

IsmaelMartinez commented 1 year ago

I think adding extensions will do the trick.

See https://www.electronjs.org/docs/latest/api/extensions#:~:text=Electron%20supports%20a%20subset%20of,support%20some%20other%20extension%20capabilities.

and https://github.com/IsmaelMartinez/teams-for-linux/issues/310

jijojosephk commented 1 year ago

@dagmoller Is it a feature in web app that's not working in teams-for-linux ?

jijojosephk commented 1 year ago

Can you try this plugin in chrome and see if it fixes the problem? If it is, then we can implement the same.

https://github.com/joeywatts/disable-autogain-control-extension/tree/master

jijojosephk commented 1 year ago

Or may be this:

image

stdevel commented 1 year ago

Can you try this plugin in chrome and see if it fixes the problem? If it is, then we can implement the same.

https://github.com/joeywatts/disable-autogain-control-extension/tree/master

This addon does the trick for using the PWA (on any chromish browser) on my machines. Is there any chance to also include this in the teams-for-linux package?

jijojosephk commented 1 year ago

We can try it. May not be adding the extension but what's done in the code.

dagmoller commented 1 year ago

Try this patch..

diff --git a/app/mainAppWindow/index.js b/app/mainAppWindow/index.js
index ff7c2b0..5d05201 100644
--- a/app/mainAppWindow/index.js
+++ b/app/mainAppWindow/index.js
@@ -136,6 +136,86 @@ function onDidFinishLoad() {
                        tryAgainLink = document.getElementById('try-again-link');
                        tryAgainLink && tryAgainLink.click()
                `);
+       window.webContents.executeJavaScript(`
+                       (function() {
+                           function setLegacyChromeConstraint(constraint, name, value) {
+                               if (constraint.mandatory && name in constraint.mandatory) {
+                                   constraint.mandatory[name] = value;
+                                   return;
+                               }
+                               if (constraint.optional) {
+                                   const element = constraint.optional.find(opt => name in opt);
+                                   if (element) {
+                                       element[name] = value;
+                                       return;
+                                   }
+                               }
+                               // 'mandatory' options throw errors for unknown keys, so avoid that by
+                               // setting it under optional.
+                               if (!constraint.optional) {
+                                   constraint.optional = [];
+                               }
+                               constraint.optional.push({ [name]: value });
+                           }
+                           function setConstraint(constraint, name, value) {
+                               if (constraint.advanced) {
+                                   const element = constraint.advanced.find(opt => name in opt);
+                                   if (element) {
+                                       element[name] = value;
+                                       return;
+                                   }
+                               }
+                               constraint[name] = value;
+                           }
+                           function disableAutogain(constraints) {
+                               console.log("Automatically unsetting gain!", constraints);
+                               if (constraints && constraints.audio) {
+                                   if (typeof constraints.audio !== "object") {
+                                       constraints.audio = {};
+                                   }
+                                   if (constraints.audio.optional || constraints.audio.mandatory) {
+                                       setLegacyChromeConstraint(constraints.audio, "googAutoGainControl", false);
+                                       setLegacyChromeConstraint(constraints.audio, "googAutoGainControl2", false);
+                                   } else {
+                                       setConstraint(constraints.audio, "autoGainControl", false);
+                                   }
+                               }
+                           }
+
+                           function patchFunction(object, name, createNewFunction) {
+                               if (name in object) {
+                                   var original = object[name];
+                                   object[name] = createNewFunction(original);
+                               }
+                           }
+
+                           patchFunction(navigator.mediaDevices, "getUserMedia", function (original) {
+                               return function getUserMedia(constraints) {
+                                   disableAutogain(constraints);
+                                   return original.call(this, constraints);
+                               };
+                           });
+                           function patchDeprecatedGetUserMedia(original) {
+                               return function getUserMedia(constraints, success, error) {
+                                   disableAutogain(constraints);
+                                   return original.call(this, constraints, success, error);
+                               };
+                           }
+                           patchFunction(navigator, "getUserMedia", patchDeprecatedGetUserMedia);
+                           patchFunction(navigator, "mozGetUserMedia", patchDeprecatedGetUserMedia);
+                           patchFunction(navigator, "webkitGetUserMedia", patchDeprecatedGetUserMedia);
+                           patchFunction(MediaStreamTrack.prototype, "applyConstraints", function (original) {
+                               return function applyConstraints(constraints) {
+                                   disableAutogain(constraints);
+                                   return original.call(this, constraints);
+                               };
+                           });
+                           console.log(
+                               "Disable Autogain by Joey Watts!",
+                               navigator.mediaDevices.getUserMedia
+                           );
+                       })();
+               `);
        customCSS.onDidFinishLoad(window.webContents, config);
 }
jijojosephk commented 1 year ago

I'm working on it. Will be added as a preload script.

jijojosephk commented 1 year ago

@dagmoller @stdevel you may test version 1.1.10 when it's released.

jijojosephk commented 1 year ago

pre-release 1.1.10 ready.

dagmoller commented 1 year ago

Not working...

dagmoller commented 1 year ago

To work, this code must be loaded after page load... at "onDidFinishLoad"

jijojosephk commented 1 year ago

Did you use the flag --disableAutogain ?

dagmoller commented 1 year ago

Did you use the flag --disableAutogain ?

yes... # /home/aguirre/_apps/teams-for-linux/teams-for-linux --spellCheckerLanguages="pt-BR" --chromeUserAgent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" --disableAutogain

jijojosephk commented 1 year ago

@dagmoller can you check the latest commit?

jijojosephk commented 1 year ago

You may try 1.1.11

dagmoller commented 1 year ago

You may try 1.1.11

Not working... :( I have made some tests here, and only works if calling the code directly from onDidFinishLoad(). In the same way that chrome plugin do.

To confirm if is working, search for "Disable Autogain by Joey Watts!" in development tools console!

This patch works...

diff --git a/app/mainAppWindow/index.js b/app/mainAppWindow/index.js
index ff7c2b0..5d05201 100644
--- a/app/mainAppWindow/index.js
+++ b/app/mainAppWindow/index.js
@@ -136,6 +136,86 @@ function onDidFinishLoad() {
                        tryAgainLink = document.getElementById('try-again-link');
                        tryAgainLink && tryAgainLink.click()
                `);
+       window.webContents.executeJavaScript(`
+                       (function() {
+                           function setLegacyChromeConstraint(constraint, name, value) {
+                               if (constraint.mandatory && name in constraint.mandatory) {
+                                   constraint.mandatory[name] = value;
+                                   return;
+                               }
+                               if (constraint.optional) {
+                                   const element = constraint.optional.find(opt => name in opt);
+                                   if (element) {
+                                       element[name] = value;
+                                       return;
+                                   }
+                               }
+                               // 'mandatory' options throw errors for unknown keys, so avoid that by
+                               // setting it under optional.
+                               if (!constraint.optional) {
+                                   constraint.optional = [];
+                               }
+                               constraint.optional.push({ [name]: value });
+                           }
+                           function setConstraint(constraint, name, value) {
+                               if (constraint.advanced) {
+                                   const element = constraint.advanced.find(opt => name in opt);
+                                   if (element) {
+                                       element[name] = value;
+                                       return;
+                                   }
+                               }
+                               constraint[name] = value;
+                           }
+                           function disableAutogain(constraints) {
+                               console.log("Automatically unsetting gain!", constraints);
+                               if (constraints && constraints.audio) {
+                                   if (typeof constraints.audio !== "object") {
+                                       constraints.audio = {};
+                                   }
+                                   if (constraints.audio.optional || constraints.audio.mandatory) {
+                                       setLegacyChromeConstraint(constraints.audio, "googAutoGainControl", false);
+                                       setLegacyChromeConstraint(constraints.audio, "googAutoGainControl2", false);
+                                   } else {
+                                       setConstraint(constraints.audio, "autoGainControl", false);
+                                   }
+                               }
+                           }
+
+                           function patchFunction(object, name, createNewFunction) {
+                               if (name in object) {
+                                   var original = object[name];
+                                   object[name] = createNewFunction(original);
+                               }
+                           }
+
+                           patchFunction(navigator.mediaDevices, "getUserMedia", function (original) {
+                               return function getUserMedia(constraints) {
+                                   disableAutogain(constraints);
+                                   return original.call(this, constraints);
+                               };
+                           });
+                           function patchDeprecatedGetUserMedia(original) {
+                               return function getUserMedia(constraints, success, error) {
+                                   disableAutogain(constraints);
+                                   return original.call(this, constraints, success, error);
+                               };
+                           }
+                           patchFunction(navigator, "getUserMedia", patchDeprecatedGetUserMedia);
+                           patchFunction(navigator, "mozGetUserMedia", patchDeprecatedGetUserMedia);
+                           patchFunction(navigator, "webkitGetUserMedia", patchDeprecatedGetUserMedia);
+                           patchFunction(MediaStreamTrack.prototype, "applyConstraints", function (original) {
+                               return function applyConstraints(constraints) {
+                                   disableAutogain(constraints);
+                                   return original.call(this, constraints);
+                               };
+                           });
+                           console.log(
+                               "Disable Autogain by Joey Watts!",
+                               navigator.mediaDevices.getUserMedia
+                           );
+                       })();
+               `);
        customCSS.onDidFinishLoad(window.webContents, config);
 }
jijojosephk commented 1 year ago

I'm getting that. The patch is to override navigator properties, so it should work with DOMContentLoaded.

image

jijojosephk commented 1 year ago

Also getting this when a call starts

image

jijojosephk commented 1 year ago

I see your user agent is set by yourself. Can you let it load the default based on the chromium version the electron builder uses ? Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.199 Safari/537.36

jijojosephk commented 1 year ago

Also getting this when a call starts

image

This shows the code is working. You may suggest how to test this.

jijojosephk commented 1 year ago

I think the code is working.

image

dagmoller commented 1 year ago

Ow, sorry... I forgot to update my shortcut... now is working... thanks...

jijojosephk commented 1 year ago

Closing as the fix confirmed working in 1.1.11

stdevel commented 1 year ago

It's not working for me with version 1.2.3 (Flatpak):

$ flatpak list|grep -i teams
teams-for-linux com.github.IsmaelMartinez.teams_for_linux   1.2.3   stable  flathub system

Is there anything I need to enable/disable first? Did a fresh install and disabled automatic noise reduction, but it still raises the mic loudness.

jijojosephk commented 1 year ago

Did you use the flag --disableAutogain ?

adriandelgg commented 2 months ago

Did you use the flag --disableAutogain ?

@IsmaelMartinez, How exactly do you use the flag? Would it be --disableAutogain or --disableAutogain true?

IsmaelMartinez commented 2 months ago

I don't remember but I think the 1st option will work. The second option I think it needs = in between