mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-08-04 14:55:43 +02:00
vad: show a drop shadow around talking participants
use "voiceActivity" from the conferences informations to show talking participants https://git.jami.net/savoirfairelinux/jami-daemon/-/issues/741 Change-Id: Iaedc61ce485ff03464128b5a17e0a6a0ea9d2c2e
This commit is contained in:
parent
17e97ded71
commit
d7d29156db
9 changed files with 49 additions and 26 deletions
|
@ -98,6 +98,9 @@ CallParticipantsModel::data(const QModelIndex& index, int role) const
|
||||||
case Role::HandRaised:
|
case Role::HandRaised:
|
||||||
return QVariant::fromValue(
|
return QVariant::fromValue(
|
||||||
participant.item.value(lrc::api::ParticipantsInfosStrings::HANDRAISED));
|
participant.item.value(lrc::api::ParticipantsInfosStrings::HANDRAISED));
|
||||||
|
case Role::VoiceActivity:
|
||||||
|
return QVariant::fromValue(
|
||||||
|
participant.item.value(lrc::api::ParticipantsInfosStrings::VOICEACTIVITY));
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
X(IsModerator) \
|
X(IsModerator) \
|
||||||
X(IsLocal) \
|
X(IsLocal) \
|
||||||
X(IsContact) \
|
X(IsContact) \
|
||||||
|
X(VoiceActivity) \
|
||||||
X(HandRaised)
|
X(HandRaised)
|
||||||
|
|
||||||
namespace CallParticipant {
|
namespace CallParticipant {
|
||||||
|
|
|
@ -175,7 +175,7 @@ Rectangle {
|
||||||
id: participantsLayer
|
id: participantsLayer
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.margins: 3
|
anchors.margins: 1
|
||||||
visible: participantsLayer.count !== 0
|
visible: participantsLayer.count !== 0
|
||||||
participantsSide: callOverlay.participantsSide
|
participantsSide: callOverlay.participantsSide
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ Item {
|
||||||
property bool participantIsModeratorMuted: false
|
property bool participantIsModeratorMuted: false
|
||||||
property bool participantHandIsRaised: false
|
property bool participantHandIsRaised: false
|
||||||
property bool videoMuted: true
|
property bool videoMuted: true
|
||||||
|
property bool voiceActive: false
|
||||||
property bool isLocalMuted: true
|
property bool isLocalMuted: true
|
||||||
|
|
||||||
property bool meHost: CallAdapter.isCurrentHost()
|
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 {
|
VideoView {
|
||||||
id: mediaDistRender
|
id: mediaDistRender
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
rendererId: root.sinkId
|
rendererId: root.sinkId
|
||||||
crop: !participantIsActive
|
crop: !participantIsActive
|
||||||
|
|
||||||
|
@ -118,17 +131,13 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
overlayItems: Rectangle {
|
overlayItems: Item {
|
||||||
id: overlayRect
|
id: overlayRect
|
||||||
|
|
||||||
width: participantIsActive ? mediaDistRender.contentRect.width : undefined
|
width: participantIsActive ? mediaDistRender.contentRect.width - 2 : undefined
|
||||||
height: participantIsActive ? mediaDistRender.contentRect.height : undefined
|
height: participantIsActive ? mediaDistRender.contentRect.height - 2 : undefined
|
||||||
anchors.centerIn: participantIsActive ? parent : undefined
|
anchors.centerIn: participantIsActive ? parent : undefined
|
||||||
anchors.fill: participantIsActive ? undefined : parent
|
anchors.fill: participantIsActive ? undefined : parent
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Item {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
HoverHandler {
|
HoverHandler {
|
||||||
onPointChanged: {
|
onPointChanged: {
|
||||||
|
@ -145,12 +154,10 @@ Item {
|
||||||
participantRect.opacity = hovered ? 1 : 0
|
participantRect.opacity = hovered ? 1 : 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
id: participantRect
|
id: participantRect
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: "transparent"
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|
||||||
// Participant buttons for moderation
|
// 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 not moderator, the mute state is isLocalMuted || participantIsModeratorMuted
|
||||||
// - In another participant, if i am moderator, the mute state is isLocalMuted
|
// - In another participant, if i am moderator, the mute state is isLocalMuted
|
||||||
// - In my video, the mute state is isLocalMuted
|
// - In my video, the mute state is isLocalMuted
|
||||||
Rectangle {
|
Item {
|
||||||
id: participantIndicators
|
id: participantIndicators
|
||||||
width: participantRect.width
|
width: participantRect.width
|
||||||
height: shapeHeight
|
height: shapeHeight
|
||||||
color: "transparent"
|
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
Shape {
|
Shape {
|
||||||
|
|
|
@ -19,8 +19,8 @@
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
|
||||||
import QtQuick.Layouts 1.15
|
import QtQuick.Layouts
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls
|
||||||
|
|
||||||
import net.jami.Adapters 1.1
|
import net.jami.Adapters 1.1
|
||||||
import net.jami.Models 1.1
|
import net.jami.Models 1.1
|
||||||
|
@ -55,6 +55,8 @@ Item {
|
||||||
id: callVideoMedia
|
id: callVideoMedia
|
||||||
|
|
||||||
ParticipantOverlay {
|
ParticipantOverlay {
|
||||||
|
id: overlay
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: leftMargin_
|
anchors.leftMargin: leftMargin_
|
||||||
|
|
||||||
|
@ -71,6 +73,7 @@ Item {
|
||||||
videoMuted: videoMuted_
|
videoMuted: videoMuted_
|
||||||
participantIsActive: active_
|
participantIsActive: active_
|
||||||
isLocalMuted: audioLocalMuted_
|
isLocalMuted: audioLocalMuted_
|
||||||
|
voiceActive: voiceActive_
|
||||||
participantIsModeratorMuted: audioModeratorMuted_
|
participantIsModeratorMuted: audioModeratorMuted_
|
||||||
participantHandIsRaised: isHandRaised_
|
participantHandIsRaised: isHandRaised_
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,7 @@ SplitView {
|
||||||
property bool audioLocalMuted_: AudioLocalMuted
|
property bool audioLocalMuted_: AudioLocalMuted
|
||||||
property bool audioModeratorMuted_: AudioModeratorMuted
|
property bool audioModeratorMuted_: AudioModeratorMuted
|
||||||
property bool isHandRaised_: HandRaised
|
property bool isHandRaised_: HandRaised
|
||||||
|
property bool voiceActive_: VoiceActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,6 +308,7 @@ SplitView {
|
||||||
property bool audioLocalMuted_: AudioLocalMuted
|
property bool audioLocalMuted_: AudioLocalMuted
|
||||||
property bool audioModeratorMuted_: AudioModeratorMuted
|
property bool audioModeratorMuted_: AudioModeratorMuted
|
||||||
property bool isHandRaised_: HandRaised
|
property bool isHandRaised_: HandRaised
|
||||||
|
property bool voiceActive_: VoiceActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,6 +215,7 @@ SplitView {
|
||||||
property bool audioLocalMuted_: AudioLocalMuted
|
property bool audioLocalMuted_: AudioLocalMuted
|
||||||
property bool audioModeratorMuted_: AudioModeratorMuted
|
property bool audioModeratorMuted_: AudioModeratorMuted
|
||||||
property bool isHandRaised_: HandRaised
|
property bool isHandRaised_: HandRaised
|
||||||
|
property bool voiceActive_: VoiceActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,6 +289,7 @@ SplitView {
|
||||||
property bool audioLocalMuted_: AudioLocalMuted
|
property bool audioLocalMuted_: AudioLocalMuted
|
||||||
property bool audioModeratorMuted_: AudioModeratorMuted
|
property bool audioModeratorMuted_: AudioModeratorMuted
|
||||||
property bool isHandRaised_: HandRaised
|
property bool isHandRaised_: HandRaised
|
||||||
|
property bool voiceActive_: VoiceActivity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ const QString AUDIOLOCALMUTED = "audioLocalMuted";
|
||||||
const QString AUDIOMODERATORMUTED = "audioModeratorMuted";
|
const QString AUDIOMODERATORMUTED = "audioModeratorMuted";
|
||||||
const QString ISMODERATOR = "isModerator";
|
const QString ISMODERATOR = "isModerator";
|
||||||
const QString HANDRAISED = "handRaised";
|
const QString HANDRAISED = "handRaised";
|
||||||
|
const QString VOICEACTIVITY = "voiceActivity";
|
||||||
const QString STREAMID = "sinkId"; // TODO update
|
const QString STREAMID = "sinkId"; // TODO update
|
||||||
const QString BESTNAME = "bestName";
|
const QString BESTNAME = "bestName";
|
||||||
const QString ISLOCAL = "isLocal";
|
const QString ISLOCAL = "isLocal";
|
||||||
|
@ -81,6 +82,7 @@ struct ParticipantInfos
|
||||||
audioModeratorMuted = infos[ParticipantsInfosStrings::AUDIOMODERATORMUTED] == "true";
|
audioModeratorMuted = infos[ParticipantsInfosStrings::AUDIOMODERATORMUTED] == "true";
|
||||||
isModerator = infos[ParticipantsInfosStrings::ISMODERATOR] == "true";
|
isModerator = infos[ParticipantsInfosStrings::ISMODERATOR] == "true";
|
||||||
handRaised = infos[ParticipantsInfosStrings::HANDRAISED] == "true";
|
handRaised = infos[ParticipantsInfosStrings::HANDRAISED] == "true";
|
||||||
|
voiceActivity = infos[ParticipantsInfosStrings::VOICEACTIVITY] == "true";
|
||||||
|
|
||||||
if (infos[ParticipantsInfosStrings::STREAMID].isEmpty())
|
if (infos[ParticipantsInfosStrings::STREAMID].isEmpty())
|
||||||
sinkId = callId + uri + device;
|
sinkId = callId + uri + device;
|
||||||
|
@ -107,6 +109,7 @@ struct ParticipantInfos
|
||||||
bool islocal {false};
|
bool islocal {false};
|
||||||
bool isContact {false};
|
bool isContact {false};
|
||||||
bool handRaised {false};
|
bool handRaised {false};
|
||||||
|
bool voiceActivity {false};
|
||||||
|
|
||||||
bool operator==(const ParticipantInfos& other) const
|
bool operator==(const ParticipantInfos& other) const
|
||||||
{
|
{
|
||||||
|
@ -115,7 +118,7 @@ struct ParticipantInfos
|
||||||
&& audioModeratorMuted == other.audioModeratorMuted && avatar == other.avatar
|
&& audioModeratorMuted == other.audioModeratorMuted && avatar == other.avatar
|
||||||
&& bestName == other.bestName && isContact == other.isContact
|
&& bestName == other.bestName && isContact == other.isContact
|
||||||
&& islocal == other.islocal && videoMuted == other.videoMuted
|
&& islocal == other.islocal && videoMuted == other.videoMuted
|
||||||
&& handRaised == other.handRaised;
|
&& handRaised == other.handRaised && voiceActivity == other.voiceActivity;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -115,7 +115,9 @@ CallParticipants::addParticipant(const ParticipantInfos& participant)
|
||||||
std::lock_guard<std::mutex> lk(participantsMtx_);
|
std::lock_guard<std::mutex> lk(participantsMtx_);
|
||||||
auto it = participants_.find(participant.sinkId);
|
auto it = participants_.find(participant.sinkId);
|
||||||
if (it == participants_.end()) {
|
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;
|
added = true;
|
||||||
} else {
|
} else {
|
||||||
if (participant == (*it))
|
if (participant == (*it))
|
||||||
|
@ -198,6 +200,7 @@ CallParticipants::toQJsonObject(uint index) const
|
||||||
ret[ParticipantsInfosStrings::ISLOCAL] = participant->islocal;
|
ret[ParticipantsInfosStrings::ISLOCAL] = participant->islocal;
|
||||||
ret[ParticipantsInfosStrings::ISCONTACT] = participant->isContact;
|
ret[ParticipantsInfosStrings::ISCONTACT] = participant->isContact;
|
||||||
ret[ParticipantsInfosStrings::HANDRAISED] = participant->handRaised;
|
ret[ParticipantsInfosStrings::HANDRAISED] = participant->handRaised;
|
||||||
|
ret[ParticipantsInfosStrings::VOICEACTIVITY] = participant->voiceActivity;
|
||||||
ret[ParticipantsInfosStrings::CALLID] = callId_;
|
ret[ParticipantsInfosStrings::CALLID] = callId_;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Add table
Reference in a new issue