diff --git a/src/app/callparticipantsmodel.cpp b/src/app/callparticipantsmodel.cpp
index 2a02a98e7ccb816e1e3de8a4b6a3b007874c22ad..1fd8ace59b2b25a674b2205cf056195b3fb153b0 100644
--- a/src/app/callparticipantsmodel.cpp
+++ b/src/app/callparticipantsmodel.cpp
@@ -98,6 +98,9 @@ CallParticipantsModel::data(const QModelIndex& index, int role) const
     case Role::HandRaised:
         return QVariant::fromValue(
             participant.item.value(lrc::api::ParticipantsInfosStrings::HANDRAISED));
+    case Role::VoiceActivity:
+        return QVariant::fromValue(
+            participant.item.value(lrc::api::ParticipantsInfosStrings::VOICEACTIVITY));
     }
     return QVariant();
 }
diff --git a/src/app/callparticipantsmodel.h b/src/app/callparticipantsmodel.h
index 6fa88be319b7052564c8a8894cf669f060b60d33..b3e1d69bd90d1252ebe02dff4d31b2727539b9c6 100644
--- a/src/app/callparticipantsmodel.h
+++ b/src/app/callparticipantsmodel.h
@@ -45,6 +45,7 @@
     X(IsModerator) \
     X(IsLocal) \
     X(IsContact) \
+    X(VoiceActivity) \
     X(HandRaised)
 
 namespace CallParticipant {
diff --git a/src/app/mainview/components/OngoingCallPage.qml b/src/app/mainview/components/OngoingCallPage.qml
index 3674ddc6fb42d09ba40ece3da5e5d13b6f79ebe7..e15bb3b0c1e786189a1bd75116fdfe6e8119378c 100644
--- a/src/app/mainview/components/OngoingCallPage.qml
+++ b/src/app/mainview/components/OngoingCallPage.qml
@@ -175,7 +175,7 @@ Rectangle {
                 id: participantsLayer
                 anchors.fill: parent
                 anchors.centerIn: parent
-                anchors.margins: 3
+                anchors.margins: 1
                 visible: participantsLayer.count !== 0
                 participantsSide: callOverlay.participantsSide
 
diff --git a/src/app/mainview/components/ParticipantOverlay.qml b/src/app/mainview/components/ParticipantOverlay.qml
index 4ce7c5087d05c9e6810c705a7d94b81f5e5afe72..1adbc5968425bfec9cc88a74fefd69665cad8909 100644
--- a/src/app/mainview/components/ParticipantOverlay.qml
+++ b/src/app/mainview/components/ParticipantOverlay.qml
@@ -56,6 +56,7 @@ Item {
     property bool participantIsModeratorMuted: false
     property bool participantHandIsRaised: false
     property bool videoMuted: true
+    property bool voiceActive: false
     property bool isLocalMuted: true
 
     property bool meHost: CallAdapter.isCurrentHost()
@@ -90,9 +91,21 @@ Item {
         }
     }
 
+    Rectangle {
+        z: -1
+        color: JamiTheme.buttonTintedBlue
+        radius: 10
+        visible:voiceActive
+        width: participantIsActive ? mediaDistRender.contentRect.width + 2 : undefined
+        height: participantIsActive ? mediaDistRender.contentRect.height + 2 : undefined
+        anchors.centerIn: participantIsActive ? parent : undefined
+        anchors.fill: participantIsActive ? undefined : parent
+    }
+
     VideoView {
         id: mediaDistRender
         anchors.fill: parent
+        anchors.margins: 2
         rendererId: root.sinkId
         crop: !participantIsActive
 
@@ -118,39 +131,33 @@ Item {
             }
         }
 
-        overlayItems: Rectangle {
+        overlayItems: Item {
             id: overlayRect
 
-            width: participantIsActive ? mediaDistRender.contentRect.width : undefined
-            height: participantIsActive ? mediaDistRender.contentRect.height : undefined
+            width: participantIsActive ? mediaDistRender.contentRect.width - 2 : undefined
+            height: participantIsActive ? mediaDistRender.contentRect.height - 2 : undefined
             anchors.centerIn: participantIsActive ? parent : undefined
             anchors.fill: participantIsActive ? undefined : parent
-            color: "transparent"
 
-            Item {
-                anchors.fill: parent
+            HoverHandler {
+                onPointChanged: {
+                    participantRect.opacity = 1
+                    fadeOutTimer.restart()
+                }
 
-                HoverHandler {
-                    onPointChanged: {
+                onHoveredChanged: {
+                    if (overlayMenu.hovered) {
                         participantRect.opacity = 1
                         fadeOutTimer.restart()
+                        return
                     }
-
-                    onHoveredChanged: {
-                        if (overlayMenu.hovered) {
-                            participantRect.opacity = 1
-                            fadeOutTimer.restart()
-                            return
-                        }
-                        participantRect.opacity = hovered ? 1 : 0
-                    }
+                    participantRect.opacity = hovered ? 1 : 0
                 }
             }
 
-            Rectangle {
+            Item {
                 id: participantRect
                 anchors.fill: parent
-                color: "transparent"
                 opacity: 0
 
                 // Participant buttons for moderation
@@ -182,11 +189,10 @@ Item {
                 // - In another participant, if i am not moderator, the mute state is isLocalMuted || participantIsModeratorMuted
                 // - In another participant, if i am moderator, the mute state is isLocalMuted
                 // - In my video, the mute state is isLocalMuted
-                Rectangle {
+                Item {
                     id: participantIndicators
                     width: participantRect.width
                     height: shapeHeight
-                    color: "transparent"
                     anchors.bottom: parent.bottom
 
                     Shape {
diff --git a/src/app/mainview/components/ParticipantsLayer.qml b/src/app/mainview/components/ParticipantsLayer.qml
index c8a1b01f7ebb88eb497addb29f9a9d2de462762a..f939deb8797b11e40f09fb2c4875f1363e1fad86 100644
--- a/src/app/mainview/components/ParticipantsLayer.qml
+++ b/src/app/mainview/components/ParticipantsLayer.qml
@@ -19,8 +19,8 @@
 
 import QtQuick
 
-import QtQuick.Layouts 1.15
-import QtQuick.Controls 2.15
+import QtQuick.Layouts
+import QtQuick.Controls
 
 import net.jami.Adapters 1.1
 import net.jami.Models 1.1
@@ -55,6 +55,8 @@ Item {
         id: callVideoMedia
 
         ParticipantOverlay {
+            id: overlay
+
             anchors.fill: parent
             anchors.leftMargin: leftMargin_
 
@@ -71,6 +73,7 @@ Item {
             videoMuted: videoMuted_
             participantIsActive: active_
             isLocalMuted: audioLocalMuted_
+            voiceActive: voiceActive_
             participantIsModeratorMuted: audioModeratorMuted_
             participantHandIsRaised: isHandRaised_
 
diff --git a/src/app/mainview/components/ParticipantsLayoutHorizontal.qml b/src/app/mainview/components/ParticipantsLayoutHorizontal.qml
index 10bc6874903a81dfbe3274a35b7f6ac2cb00cbc2..645728ad4e02e23ca5812dac0df49bc00ac741f7 100644
--- a/src/app/mainview/components/ParticipantsLayoutHorizontal.qml
+++ b/src/app/mainview/components/ParticipantsLayoutHorizontal.qml
@@ -120,6 +120,7 @@ SplitView {
                 property bool audioLocalMuted_: AudioLocalMuted
                 property bool audioModeratorMuted_: AudioModeratorMuted
                 property bool isHandRaised_: HandRaised
+                property bool voiceActive_: VoiceActivity
             }
         }
     }
@@ -307,6 +308,7 @@ SplitView {
                             property bool audioLocalMuted_: AudioLocalMuted
                             property bool audioModeratorMuted_: AudioModeratorMuted
                             property bool isHandRaised_: HandRaised
+                            property bool voiceActive_: VoiceActivity
                         }
                     }
                 }
diff --git a/src/app/mainview/components/ParticipantsLayoutVertical.qml b/src/app/mainview/components/ParticipantsLayoutVertical.qml
index 307a167c7d7b51ed953d87be40a494bb7281c74d..8138ea19099596b115dadea1fa43ffd994703587 100644
--- a/src/app/mainview/components/ParticipantsLayoutVertical.qml
+++ b/src/app/mainview/components/ParticipantsLayoutVertical.qml
@@ -215,6 +215,7 @@ SplitView {
                             property bool audioLocalMuted_: AudioLocalMuted
                             property bool audioModeratorMuted_: AudioModeratorMuted
                             property bool isHandRaised_: HandRaised
+                            property bool voiceActive_: VoiceActivity
                         }
                     }
                 }
@@ -288,6 +289,7 @@ SplitView {
                 property bool audioLocalMuted_: AudioLocalMuted
                 property bool audioModeratorMuted_: AudioModeratorMuted
                 property bool isHandRaised_: HandRaised
+                property bool voiceActive_: VoiceActivity
             }
         }
     }
diff --git a/src/libclient/api/callparticipantsmodel.h b/src/libclient/api/callparticipantsmodel.h
index bd92e278f6a8d02441b03217c2d701e7d0bda2ba..c51cb10197f4d07fadbeb02985ee4ba82f23b15e 100644
--- a/src/libclient/api/callparticipantsmodel.h
+++ b/src/libclient/api/callparticipantsmodel.h
@@ -52,6 +52,7 @@ const QString AUDIOLOCALMUTED = "audioLocalMuted";
 const QString AUDIOMODERATORMUTED = "audioModeratorMuted";
 const QString ISMODERATOR = "isModerator";
 const QString HANDRAISED = "handRaised";
+const QString VOICEACTIVITY = "voiceActivity";
 const QString STREAMID = "sinkId"; // TODO update
 const QString BESTNAME = "bestName";
 const QString ISLOCAL = "isLocal";
@@ -81,6 +82,7 @@ struct ParticipantInfos
         audioModeratorMuted = infos[ParticipantsInfosStrings::AUDIOMODERATORMUTED] == "true";
         isModerator = infos[ParticipantsInfosStrings::ISMODERATOR] == "true";
         handRaised = infos[ParticipantsInfosStrings::HANDRAISED] == "true";
+        voiceActivity = infos[ParticipantsInfosStrings::VOICEACTIVITY] == "true";
 
         if (infos[ParticipantsInfosStrings::STREAMID].isEmpty())
             sinkId = callId + uri + device;
@@ -107,6 +109,7 @@ struct ParticipantInfos
     bool islocal {false};
     bool isContact {false};
     bool handRaised {false};
+    bool voiceActivity {false};
 
     bool operator==(const ParticipantInfos& other) const
     {
@@ -115,7 +118,7 @@ struct ParticipantInfos
                && audioModeratorMuted == other.audioModeratorMuted && avatar == other.avatar
                && bestName == other.bestName && isContact == other.isContact
                && islocal == other.islocal && videoMuted == other.videoMuted
-               && handRaised == other.handRaised;
+               && handRaised == other.handRaised && voiceActivity == other.voiceActivity;
     }
 };
 
diff --git a/src/libclient/callparticipantsmodel.cpp b/src/libclient/callparticipantsmodel.cpp
index 3ae412abbffd97519f0bd165c69406b940b6ca2e..523a38ec9b1baf4c2324a019d163d3cee5205fa9 100644
--- a/src/libclient/callparticipantsmodel.cpp
+++ b/src/libclient/callparticipantsmodel.cpp
@@ -115,7 +115,9 @@ CallParticipants::addParticipant(const ParticipantInfos& participant)
         std::lock_guard<std::mutex> lk(participantsMtx_);
         auto it = participants_.find(participant.sinkId);
         if (it == participants_.end()) {
-            participants_.insert(std::next(participants_.begin(), idx_), participant.sinkId, participant);
+            participants_.insert(std::next(participants_.begin(), idx_),
+                                 participant.sinkId,
+                                 participant);
             added = true;
         } else {
             if (participant == (*it))
@@ -198,6 +200,7 @@ CallParticipants::toQJsonObject(uint index) const
     ret[ParticipantsInfosStrings::ISLOCAL] = participant->islocal;
     ret[ParticipantsInfosStrings::ISCONTACT] = participant->isContact;
     ret[ParticipantsInfosStrings::HANDRAISED] = participant->handRaised;
+    ret[ParticipantsInfosStrings::VOICEACTIVITY] = participant->voiceActivity;
     ret[ParticipantsInfosStrings::CALLID] = callId_;
 
     return ret;