From 59221530dfe15425518cb39e2475b75bedb8bd66 Mon Sep 17 00:00:00 2001
From: prlanzarin <prlanzarin@inf.ufrgs.br>
Date: Wed, 9 Sep 2020 17:03:27 +0000
Subject: [PATCH] Add a client-side mute via the sender track corresponding to
 the mute state

The mic mute is done client side via the track`s enabled flag, which generates silent when false. This still tracks the server/freeswitch mute state, so server-side mutes will be reproduced in the client
---
 .../imports/ui/components/audio/service.js    |  2 ++
 .../ui/services/audio-manager/index.js        | 34 ++++++++++++++++++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/bigbluebutton-html5/imports/ui/components/audio/service.js b/bigbluebutton-html5/imports/ui/components/audio/service.js
index 0c4d5a6c3c..d80176adc7 100755
--- a/bigbluebutton-html5/imports/ui/components/audio/service.js
+++ b/bigbluebutton-html5/imports/ui/components/audio/service.js
@@ -51,12 +51,14 @@ const toggleMuteMicrophone = () => {
       extraInfo: { logType: 'user_action' },
     }, 'microphone unmuted by user');
     makeCall('toggleVoice');
+    AudioManager.unmute();
   } else {
     logger.info({
       logCode: 'audiomanager_mute_audio',
       extraInfo: { logType: 'user_action' },
     }, 'microphone muted by user');
     makeCall('toggleVoice');
+    AudioManager.mute();
   }
 };
 
diff --git a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
index 19f1a12ac8..e48dd76ca7 100755
--- a/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
+++ b/bigbluebutton-html5/imports/ui/services/audio-manager/index.js
@@ -11,6 +11,7 @@ import { tryGenerateIceCandidates } from '/imports/utils/safari-webrtc';
 import { monitorAudioConnection } from '/imports/utils/stats';
 import AudioErrors from './error-codes';
 
+
 const ENABLE_NETWORK_MONITORING = Meteor.settings.public.networkMonitoring.enableNetworkMonitoring;
 
 const MEDIA = Meteor.settings.public.media;
@@ -283,8 +284,17 @@ class AudioManager {
 
   onVoiceUserChanges(fields) {
     if (fields.muted !== undefined && fields.muted !== this.isMuted) {
+      let muteState;
       this.isMuted = fields.muted;
-      const muteState = this.isMuted ? 'selfMuted' : 'selfUnmuted';
+
+      if (this.isMuted) {
+        muteState = 'selfMuted';
+        this.mute();
+      } else {
+        muteState = 'selfUnmuted';
+        this.unmute();
+      }
+
       window.parent.postMessage({ response: muteState }, '*');
     }
 
@@ -566,6 +576,28 @@ class AudioManager {
       this.autoplayBlocked = true;
     }
   }
+
+  mute () {
+    const bridge = (this.useKurento && this.isListenOnly) ? this.listenOnlyBridge : this.bridge;
+    const peer = bridge.getPeerConnection();
+    peer.getSenders().forEach(sender => {
+      const { track } = sender;
+      if (track && track.kind === 'audio') {
+        track.enabled = false;
+      }
+    });
+  }
+
+  unmute () {
+    const bridge = (this.useKurento && this.isListenOnly) ? this.listenOnlyBridge : this.bridge;
+    const peer = bridge.getPeerConnection();
+    peer.getSenders().forEach(sender => {
+      const { track } = sender;
+      if (track && track.kind === 'audio') {
+        track.enabled = true;
+      }
+    });
+  }
 }
 
 const audioManager = new AudioManager();
-- 
GitLab