From f7c3ed4b8b2d991f57a1547fdf732d9f548351bf Mon Sep 17 00:00:00 2001 From: Neil Dorin Date: Wed, 24 Jun 2026 22:28:40 -0600 Subject: [PATCH] feat: add mobile control messengers for participant audio and video mute functionality --- .../VideoCodec/Interfaces/Participant.cs | 15 ++++++- .../IHasParticipantAudioMuteMessenger.cs | 40 +++++++++++++++++ .../IHasParticipantVideoMuteMessenger.cs | 44 +++++++++++++++++++ .../MessengerFactoryRegistry.cs | 11 +++++ 4 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasParticipantAudioMuteMessenger.cs create mode 100644 src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasParticipantVideoMuteMessenger.cs diff --git a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/Participant.cs b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/Participant.cs index e8c46f7a..1c8678b3 100644 --- a/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/Participant.cs +++ b/src/PepperDash.Essentials.Devices.Common/VideoCodec/Interfaces/Participant.cs @@ -1,3 +1,4 @@ +using Newtonsoft.Json; namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces { /// @@ -8,61 +9,73 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces /// /// Gets or sets the UserId /// + [JsonProperty("userId")] public int UserId { get; set; } /// /// Gets or sets the IsHost /// + [JsonProperty("isHost")] public bool IsHost { get; set; } /// /// Gets or sets the IsCohost /// + [JsonProperty("isCohost")] public bool IsCohost { get; set; } /// /// Gets or sets the IsMyself /// + [JsonProperty("isMyself")] public bool IsMyself { get; set; } /// /// Gets or sets the Name /// + [JsonProperty("name")] public string Name { get; set; } /// /// Gets or sets the Email /// + [JsonProperty("email")] public bool CanMuteVideo { get; set; } /// /// Gets or sets the CanUnmuteVideo /// + [JsonProperty("canUnmuteVideo")] public bool CanUnmuteVideo { get; set; } /// /// Gets or sets the CanMuteAudio /// - public bool VideoMuteFb { get; set; } + [JsonProperty("canMuteAudio")] + public bool CanMuteAudio { get; set; } /// /// Gets or sets the AudioMuteFb /// + [JsonProperty("audioMuteFb")] public bool AudioMuteFb { get; set; } /// /// Gets or sets the HandIsRaisedFb /// + [JsonProperty("handIsRaisedFb")] public bool HandIsRaisedFb { get; set; } /// /// Gets or sets the IsPinnedFb /// + [JsonProperty("isPinnedFb")] public bool IsPinnedFb { get; set; } /// /// Gets or sets the ScreenIndexIsPinnedToFb /// + [JsonProperty("screenIndexIsPinnedToFb")] public int ScreenIndexIsPinnedToFb { get; set; } /// diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasParticipantAudioMuteMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasParticipantAudioMuteMessenger.cs new file mode 100644 index 00000000..e7f6cebe --- /dev/null +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasParticipantAudioMuteMessenger.cs @@ -0,0 +1,40 @@ +using System; +using Newtonsoft.Json.Linq; +using PepperDash.Essentials.AppServer; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; + +namespace PepperDash.Essentials.AppServer.Messengers +{ + /// + /// Mobile Control messenger for : + /// mute-all and per-participant audio/video mute toggles. Action-only (no status of its own). + /// + public class IHasParticipantAudioMuteMessenger : MessengerBase + { + private readonly IHasParticipantAudioMute _codec; + + public IHasParticipantAudioMuteMessenger(string key, string messagePath, EssentialsDevice device) + : base(key, messagePath, device) + { + _codec = device as IHasParticipantAudioMute ?? throw new ArgumentNullException(nameof(device)); + } + + protected override void RegisterActions() + { + base.RegisterActions(); + + AddAction("/muteAllParticipants", (id, content) => _codec.MuteAudioForAllParticipants()); + AddAction("/toggleParticipantAudioMute", (id, content) => + { + var i = content?.ToObject>(); + if (i != null) _codec.ToggleAudioForParticipant(i.Value); + }); + AddAction("/toggleParticipantVideoMute", (id, content) => + { + var i = content?.ToObject>(); + if (i != null) _codec.ToggleVideoForParticipant(i.Value); + }); + } + } +} diff --git a/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasParticipantVideoMuteMessenger.cs b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasParticipantVideoMuteMessenger.cs new file mode 100644 index 00000000..449a51d0 --- /dev/null +++ b/src/PepperDash.Essentials.MobileControl.Messengers/Messengers/IHasParticipantVideoMuteMessenger.cs @@ -0,0 +1,44 @@ +using System; +using Newtonsoft.Json.Linq; +using PepperDash.Essentials.AppServer; +using PepperDash.Essentials.Core; +using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces; + +namespace PepperDash.Essentials.AppServer.Messengers +{ + /// + /// Mobile Control messenger for : + /// per-participant video mute/unmute/toggle. Action-only (no status of its own). + /// + public class IHasParticipantVideoMuteMessenger : MessengerBase + { + private readonly IHasParticipantVideoMute _codec; + + public IHasParticipantVideoMuteMessenger(string key, string messagePath, EssentialsDevice device) + : base(key, messagePath, device) + { + _codec = device as IHasParticipantVideoMute ?? throw new ArgumentNullException(nameof(device)); + } + + protected override void RegisterActions() + { + base.RegisterActions(); + + AddAction("/muteVideoForParticipant", (id, content) => + { + var i = content?.ToObject>(); + if (i != null) _codec.MuteVideoForParticipant(i.Value); + }); + AddAction("/unmuteVideoForParticipant", (id, content) => + { + var i = content?.ToObject>(); + if (i != null) _codec.UnmuteVideoForParticipant(i.Value); + }); + AddAction("/toggleParticipantVideoMute", (id, content) => + { + var i = content?.ToObject>(); + if (i != null) _codec.ToggleVideoForParticipant(i.Value); + }); + } + } +} diff --git a/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs b/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs index 7124de56..e5c7e19a 100644 --- a/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs +++ b/src/PepperDash.Essentials.MobileControl/MessengerFactoryRegistry.cs @@ -236,6 +236,17 @@ namespace PepperDash.Essentials (d, mp, ck) => new IHasFarEndContentStatusMessenger( $"{d.Key}-farEndContent-{ck}", mp, d) ), + new MessengerFactoryEntry( + typeof(IHasParticipantAudioMute), + (d, mp, ck) => new IHasParticipantAudioMuteMessenger( + $"{d.Key}-participantAudioMute-{ck}", mp, d) + ), + new MessengerFactoryEntry( + typeof(IHasParticipantVideoMute), + (d, mp, ck) => new IHasParticipantVideoMuteMessenger( + $"{d.Key}-participantVideoMute-{ck}", mp, d), + predicate: d => d is IHasParticipantVideoMute && !(d is IHasParticipantAudioMute) + ), new MessengerFactoryEntry( typeof(IHasMeetingInfo), (d, mp, ck) => new IHasMeetingInfoMessenger(