diff --git a/src/calladapter.cpp b/src/calladapter.cpp
index 23854a758f39c8ec0a25ac1a15ee4387df306eb2..2797a82d2923ea9a8baa68bc3dbb560c66546a9b 100644
--- a/src/calladapter.cpp
+++ b/src/calladapter.cpp
@@ -331,6 +331,7 @@ CallAdapter::connectCallModel(const QString& accountId)
             auto& callModel = accInfo.callModel;
             auto call = callModel->getCall(confId);
             const auto convInfo = LRCInstance::getConversationFromCallId(confId);
+            bool currentMuted = false;
             if (!convInfo.uid.isEmpty()) {
                 // Convert to QML
                 QVariantList map;
@@ -350,6 +351,7 @@ CallAdapter::connectCallModel(const QString& accountId)
                     if (bestName == accInfo.profileInfo.uri) {
                         bestName = tr("me");
                         data["isLocal"] = true;
+                        currentMuted = participant["audioMuted"] == "true";
                         if (participant["videoMuted"] == "true")
                             data["avatar"] = accInfo.profileInfo.avatar;
                     } else {
@@ -366,6 +368,19 @@ CallAdapter::connectCallModel(const QString& accountId)
                     data["bestName"] = bestName;
                     map.push_back(QVariant(data));
                 }
+
+                // Link local mute to conference mute
+                auto* convModel = LRCInstance::getCurrentConversationModel();
+                const auto convInfo = convModel->getConversationForUID(convUid_);
+                if (!convInfo.uid.isEmpty()) {
+                    auto call = LRCInstance::getCallInfoForConversation(convInfo);
+                    if (call) {
+                        if (currentMuted != call->audioMuted) {
+                            muteThisCallToggle();
+                            updateCallOverlay(convInfo);
+                        }
+                    }
+                }
                 emit updateParticipantsInfos(map, accountId, confId);
             }
         });
@@ -700,6 +715,68 @@ CallAdapter::setModerator(const QString& uri, const bool state)
     } catch (...) {}
 }
 
+void
+CallAdapter::muteParticipant(const QString& uri, const bool state) {
+
+    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+    auto* convModel = LRCInstance::getCurrentConversationModel();
+    const auto conversation = convModel->getConversationForUID(LRCInstance::getCurrentConvUid());
+    auto confId = conversation.confId;
+    if (confId.isEmpty())
+        confId = conversation.callId;
+    try {
+        const auto call = callModel->getCall(confId);
+        callModel->muteParticipant(confId, uri, state);
+    } catch (...) {}
+}
+
+bool
+CallAdapter::isMuted(const QString& uri) const
+{
+    auto* convModel = LRCInstance::getCurrentConversationModel();
+    const auto convInfo = convModel->getConversationForUID(convUid_);
+    auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+    auto confId = convInfo.confId.isEmpty() ? convInfo.callId : convInfo.confId;
+    try {
+        auto call = callModel->getCall(confId);
+        if (call.participantsInfos.size() == 0) {
+            return false;
+        } else {
+            for (const auto& participant : call.participantsInfos) {
+                if (participant["uri"] == uri)
+                    return participant["audioMuted"] == "true";
+            }
+        }
+        return false;
+    } catch (...) {
+    }
+    return false;
+}
+
+bool
+CallAdapter::isCurrentMuted() const
+{
+    auto* convModel = LRCInstance::getCurrentConversationModel();
+    const auto convInfo = convModel->getConversationForUID(convUid_);
+    if (!convInfo.uid.isEmpty()) {
+        auto* callModel = LRCInstance::getAccountInfo(accountId_).callModel.get();
+        try {
+            auto call = callModel->getCall(convInfo.callId);
+            if (call.participantsInfos.size() == 0) {
+                return false;
+            } else {
+                auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
+                for (const auto& participant : call.participantsInfos) {
+                    if (participant["uri"] == accInfo.profileInfo.uri)
+                        return participant["audioMuted"] == "true";
+                }
+            }
+            return false;
+        } catch (...) {
+        }
+    }
+    return true;
+}
 
 int
 CallAdapter::getCurrentLayoutType() const
diff --git a/src/calladapter.h b/src/calladapter.h
index a2a0da421575c3ce65897b8df4d9401972ee7a65..af6a3a25526f92eeb0edda6e35b0370040483174 100644
--- a/src/calladapter.h
+++ b/src/calladapter.h
@@ -68,6 +68,9 @@ public:
     Q_INVOKABLE void videoPauseThisCallToggle();
     Q_INVOKABLE bool isRecordingThisCall();
     Q_INVOKABLE QVariantList getConferencesInfos();
+    Q_INVOKABLE void muteParticipant(const QString& uri, const bool state);
+    Q_INVOKABLE bool isMuted(const QString& uri) const;
+    Q_INVOKABLE bool isCurrentMuted() const;
 
 signals:
     void callStatusChanged(int index, const QString& accountId, const QString& convUid);
diff --git a/src/mainview/components/CallOverlay.qml b/src/mainview/components/CallOverlay.qml
index 05bbe0dabb57462a1d72b62bc0b9b66fff310c5a..d2c8bae009a25880a2b4c6e819db46e3c364e428 100644
--- a/src/mainview/components/CallOverlay.qml
+++ b/src/mainview/components/CallOverlay.qml
@@ -74,7 +74,7 @@ Rectangle {
     function closePotentialMediaHandlerPicker() {
         MediaHandlerPickerCreation.closeMediaHandlerPicker()
     }
-    
+
     function handleParticipantsInfo(infos) {
         videoCallOverlay.updateMenu()
         var isModerator = CallAdapter.isCurrentModerator()
diff --git a/src/mainview/components/ParticipantContextMenu.qml b/src/mainview/components/ParticipantContextMenu.qml
index e508dabf9c3b4ea2daf98b3b3b0ed381c5e354d6..5c9f4985ac3dcc0e0cbcbac55b04b22cda9094b4 100644
--- a/src/mainview/components/ParticipantContextMenu.qml
+++ b/src/mainview/components/ParticipantContextMenu.qml
@@ -37,6 +37,8 @@ Item {
     property var showMinimize: false
     property var showSetModerator: false
     property var showUnsetModerator: false
+    property var showMute: false
+    property var showUnmute: false
 
     function openMenu(){
         ContextMenuGenerator.initMenu()
@@ -74,6 +76,21 @@ Item {
                                                   CallAdapter.setModerator(uri, false)
                                              })
 
+        if (showMute)
+            ContextMenuGenerator.addMenuItem(qsTr("Mute participant"),
+                                             "qrc:/images/icons/mic_off-24px.svg",
+                                             function (){
+                                                  CallAdapter.muteParticipant(uri, true)
+                                             })
+
+        if (showUnmute)
+            ContextMenuGenerator.addMenuItem(qsTr("Unmute participant"),
+                                             "qrc:/images/icons/mic-24px.svg",
+                                             function (){
+                                                  CallAdapter.muteParticipant(uri, false)
+                                             })
+
+
         root.height = ContextMenuGenerator.getMenu().height
         root.width = ContextMenuGenerator.getMenu().width
         ContextMenuGenerator.getMenu().open()
diff --git a/src/mainview/components/ParticipantOverlay.qml b/src/mainview/components/ParticipantOverlay.qml
index fc3cb6d8acb69c1f71d26dcac7ab6347aed6d58b..38e19e753d8abefad534418cf49fc701a1d3f07d 100644
--- a/src/mainview/components/ParticipantOverlay.qml
+++ b/src/mainview/components/ParticipantOverlay.qml
@@ -158,6 +158,7 @@ Rectangle {
                         var isModerator = CallAdapter.isModerator(uri)
                         var isHost = CallAdapter.isCurrentHost()
                         var participantIsHost = CallAdapter.participantIsHost(uri)
+                        var isMuted = CallAdapter.isMuted(uri)
                         injectedContextMenu.showHangup = !root.isLocal && showEndCall
                         injectedContextMenu.showMaximize = showMaximized
                         injectedContextMenu.showMinimize = showMinimized
@@ -167,6 +168,8 @@ Rectangle {
                         injectedContextMenu.y = mousePos.y - injectedContextMenu.height
                         injectedContextMenu.showSetModerator = (isHost && !participantIsHost && !isModerator)
                         injectedContextMenu.showUnsetModerator = (isHost && !participantIsHost && isModerator)
+                        injectedContextMenu.showMute = !isMuted
+                        injectedContextMenu.showUnmute = isMuted && root.isLocal
                         injectedContextMenu.openMenu()
                     }
                 }