mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-03-28 14:56:19 +01:00
call layout: add option to mirror local camera videos
In conference, this patch depends on using local sinks ids to avoid mirroring video from sharing resources. GitLab: https://git.jami.net/savoirfairelinux/jami-client-gnome/-/issues/1284 Change-Id: I0c74f0780ebf17c68ffcffdca62eb33784189741
This commit is contained in:
parent
8fd2c36bfd
commit
378161ebe5
15 changed files with 59 additions and 5 deletions
2
daemon
2
daemon
|
@ -1 +1 @@
|
|||
Subproject commit bbf8cca24f6ca8f164a1282d7b8fe93de7e953d4
|
||||
Subproject commit 977ee99c115f8435b0aa0521aa5b54ea7a2d4895
|
1
resources/icons/flip_24dp.svg
Normal file
1
resources/icons/flip_24dp.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="15" height="15" viewBox="0 0 15 15"><g transform="translate(-74.997 -75.001)"><path class="a" d="M581.25,75.269V89.734a.268.268,0,0,0,.536,0V75.269a.268.268,0,1,0-.536,0Z" transform="translate(-499.02)"/><path class="a" d="M75.412,330.394a.8.8,0,0,0-.415.7v6.335a.8.8,0,0,0,1.248.67l4.913-3.271a.8.8,0,0,0-.019-1.339l-4.913-3.078a.8.8,0,0,0-.814-.016Z" transform="translate(0 -251.642)"/><path class="a" d="M675.856,330.788a.8.8,0,0,0-.8.021l-4.915,3.062a.8.8,0,0,0-.019,1.339l4.9,3.281a.8.8,0,0,0,1.248-.67v-6.335a.8.8,0,0,0-.415-.7Zm-3.731,5.127-1.666-1.109h5.277v1.071h-3.482a.269.269,0,0,0-.129.037Zm.1-2.716h3.506v1.071H670.51Zm3.1-1.934a.265.265,0,0,1,.413.22v1.179h-2.657Zm.268,6.8a.268.268,0,0,1-.268,0l-2.456-1.65h2.866v1.409a.268.268,0,0,1-.142.236Z" transform="translate(-586.274 -252.037)"/></g></svg>
|
After Width: | Height: | Size: 861 B |
|
@ -57,7 +57,8 @@ extern const QString defaultDownloadPath;
|
|||
X(EnableExperimentalSwarm, false) \
|
||||
X(LANG, "SYSTEM") \
|
||||
X(PositionShareDuration, 15) \
|
||||
X(PositionShareLimit, true)
|
||||
X(PositionShareLimit, true) \
|
||||
X(FlipSelf, false)
|
||||
|
||||
/*
|
||||
* A class to expose settings keys in both c++ and QML.
|
||||
|
|
|
@ -94,6 +94,9 @@ CallParticipantsModel::data(const QModelIndex& index, int role) const
|
|||
return QVariant(item.value(VOICEACTIVITY).toBool());
|
||||
case Role::IsRecording:
|
||||
return QVariant(item.value(ISRECORDING).toBool());
|
||||
case Role::IsSharing:
|
||||
// this only works when using local sinks in conference
|
||||
return QVariant(item.value(STREAMID).toString().startsWith("file://") || item.value(STREAMID).toString().startsWith("display://"));
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
|
|
@ -48,7 +48,8 @@
|
|||
X(IsContact) \
|
||||
X(VoiceActivity) \
|
||||
X(IsRecording) \
|
||||
X(HandRaised)
|
||||
X(HandRaised) \
|
||||
X(IsSharing)
|
||||
|
||||
namespace CallParticipant {
|
||||
Q_NAMESPACE
|
||||
|
|
|
@ -31,6 +31,7 @@ Item {
|
|||
/ videoOutput.sourceRect.width) ||
|
||||
0.5625 // 16:9 default
|
||||
property bool crop: false
|
||||
property bool flip: false
|
||||
|
||||
// This rect describes the actual rendered content rectangle
|
||||
// as the VideoOutput component may use PreserveAspectFit
|
||||
|
@ -72,6 +73,11 @@ Item {
|
|||
anchors.fill: root
|
||||
radius: (1. - opacity) * 100
|
||||
}
|
||||
|
||||
transform: Scale {
|
||||
origin.x: videoOutput.width / 2
|
||||
xScale: root.flip ? -1 : 1
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
|
|
|
@ -197,6 +197,7 @@ Item {
|
|||
property string fps: qsTr("Frames per second")
|
||||
property string selectFPS: qsTr("Select video frame rate (frames per second)")
|
||||
property string enableHWAccel: qsTr("Enable hardware acceleration")
|
||||
property string mirrorLocalVideo: qsTr("Mirror local video")
|
||||
property string previewUnavailable: qsTr("Preview unavailable")
|
||||
property string screenSharing: qsTr("Screen Sharing")
|
||||
property string selectScreenSharingFPS: qsTr("Select screen sharing frame rate (frames per second)")
|
||||
|
|
|
@ -51,6 +51,8 @@ class CurrentCall final : public QObject
|
|||
QML_PROPERTY(bool, hideSpectators)
|
||||
QML_RO_PROPERTY(bool, isOutgoing)
|
||||
|
||||
QML_PROPERTY(bool, flipSelf)
|
||||
|
||||
public:
|
||||
explicit CurrentCall(LRCInstance* lrcInstance, QObject* parent = nullptr);
|
||||
~CurrentCall() = default;
|
||||
|
|
|
@ -188,6 +188,10 @@ Control {
|
|||
UtilsAdapter.setAppValue(Settings.HideSpectators, !layoutModel.get(index).ActiveSetting)
|
||||
CurrentCall.hideSpectators = UtilsAdapter.getAppValue(Settings.HideSpectators)
|
||||
break
|
||||
case JamiStrings.mirrorLocalVideo:
|
||||
UtilsAdapter.setAppValue(Settings.FlipSelf, !layoutModel.get(index).ActiveSetting)
|
||||
CurrentCall.flipSelf = UtilsAdapter.getAppValue(Settings.FlipSelf)
|
||||
break
|
||||
}
|
||||
}
|
||||
onTriggered: {
|
||||
|
@ -218,9 +222,17 @@ Control {
|
|||
"IconSource": JamiResources.hidemyself_black_24dp_svg,
|
||||
"ActiveSetting": UtilsAdapter.getAppValue(Settings.HideSelf),
|
||||
"TopMargin": true,
|
||||
"BottomMargin": true,
|
||||
"SectionEnd": true})
|
||||
"BottomMargin": false,
|
||||
"SectionEnd": false})
|
||||
}
|
||||
|
||||
layoutModel.append({"Name": JamiStrings.mirrorLocalVideo,
|
||||
"IconSource": JamiResources.flip_24dp_svg,
|
||||
"ActiveSetting": UtilsAdapter.getAppValue(Settings.FlipSelf),
|
||||
"TopMargin": !CurrentCall.isConference,
|
||||
"BottomMargin": true,
|
||||
"SectionEnd": true})
|
||||
|
||||
layoutModel.append({"Name": JamiStrings.viewFullScreen,
|
||||
"IconSource": JamiResources.open_in_full_24dp_svg,
|
||||
"ActiveSetting": layoutManager.isCallFullscreen,
|
||||
|
|
|
@ -209,6 +209,7 @@ Rectangle {
|
|||
width: Math.max(callPageMainRect.width / 5, JamiTheme.minimumPreviewWidth)
|
||||
x: callPageMainRect.width - previewRenderer.width - previewMargin
|
||||
y: previewMarginYTop
|
||||
flip: CurrentCall.flipSelf && !CurrentCall.isSharing
|
||||
|
||||
// HACK: this is a workaround to the preview video starting
|
||||
// and stopping a few times. The root cause should be investigated ASAP.
|
||||
|
|
|
@ -59,6 +59,7 @@ Item {
|
|||
property bool voiceActive: false
|
||||
property bool isLocalMuted: true
|
||||
property bool isRecording: false
|
||||
property bool isSharing: false
|
||||
|
||||
property bool meHost: CallAdapter.isCurrentHost()
|
||||
property bool meModerator: CallAdapter.isModerator()
|
||||
|
@ -123,6 +124,8 @@ Item {
|
|||
anchors.margins: 2
|
||||
rendererId: root.sinkId
|
||||
crop: !participantIsActive
|
||||
flip: isMe && !isSharing && CurrentCall.flipSelf
|
||||
|
||||
underlayItems: Avatar {
|
||||
property real componentSize: Math.min(mediaDistRender.contentRect.width / 2, mediaDistRender.contentRect.height / 2)
|
||||
height: componentSize
|
||||
|
|
|
@ -45,6 +45,7 @@ Item {
|
|||
onVisibleChanged: {
|
||||
CurrentCall.hideSelf = UtilsAdapter.getAppValue(Settings.HideSelf)
|
||||
CurrentCall.hideSpectators = UtilsAdapter.getAppValue(Settings.HideSpectators)
|
||||
CurrentCall.flipSelf = UtilsAdapter.getAppValue(Settings.FlipSelf)
|
||||
}
|
||||
|
||||
Component {
|
||||
|
@ -76,6 +77,7 @@ Item {
|
|||
isRecording: isRecording_
|
||||
participantIsModeratorMuted: audioModeratorMuted_
|
||||
participantHandIsRaised: isHandRaised_
|
||||
isSharing: isSharing_
|
||||
|
||||
onParticipantHoveredChanged: {
|
||||
if (participantHovered) {
|
||||
|
|
|
@ -122,6 +122,7 @@ SplitView {
|
|||
property bool isHandRaised_: HandRaised
|
||||
property bool voiceActive_: VoiceActivity
|
||||
property bool isRecording_: IsRecording
|
||||
property bool isSharing_: IsSharing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,6 +312,7 @@ SplitView {
|
|||
property bool isHandRaised_: HandRaised
|
||||
property bool voiceActive_: VoiceActivity
|
||||
property bool isRecording_: IsRecording
|
||||
property bool isSharing_: IsSharing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -217,6 +217,7 @@ SplitView {
|
|||
property bool isHandRaised_: HandRaised
|
||||
property bool voiceActive_: VoiceActivity
|
||||
property bool isRecording_: IsRecording
|
||||
property bool isSharing_: IsSharing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -292,6 +293,7 @@ SplitView {
|
|||
property bool isHandRaised_: HandRaised
|
||||
property bool voiceActive_: VoiceActivity
|
||||
property bool isRecording_: IsRecording
|
||||
property bool isSharing_: IsSharing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
flipControl.checked = UtilsAdapter.getAppValue(Settings.FlipSelf)
|
||||
if (visible) {
|
||||
hardwareAccelControl.checked = AvAdapter.getHardwareAcceleration()
|
||||
if (previewWidget.visible)
|
||||
|
@ -230,6 +231,21 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
ToggleSwitch {
|
||||
id: flipControl
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: JamiTheme.preferredMarginSize
|
||||
|
||||
labelText: JamiStrings.mirrorLocalVideo
|
||||
fontPointSize: JamiTheme.settingsFontSize
|
||||
|
||||
onSwitchToggled: {
|
||||
UtilsAdapter.setAppValue(Settings.FlipSelf, checked)
|
||||
CurrentCall.flipSelf = UtilsAdapter.getAppValue(Settings.FlipSelf)
|
||||
}
|
||||
}
|
||||
|
||||
// video Preview
|
||||
Rectangle {
|
||||
visible: VideoDevices.listSize !== 0
|
||||
|
@ -248,6 +264,7 @@ ColumnLayout {
|
|||
id: previewWidget
|
||||
|
||||
anchors.fill: parent
|
||||
flip: flipControl.checked
|
||||
|
||||
underlayItems: Text {
|
||||
anchors.centerIn: parent
|
||||
|
|
Loading…
Add table
Reference in a new issue