mirror of
https://github.com/PepperDash/Essentials.git
synced 2026-01-28 20:04:56 +00:00
finished up with some things
This commit is contained in:
@@ -562,6 +562,59 @@ namespace PepperDash_Essentials_Core.Bridges.JoinMaps
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceShareStart")] public JoinDataComplete SourceShareStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 201, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Start Sharing & Feedback",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("SourceShareEnd")]
|
||||
public JoinDataComplete SourceShareEnd =
|
||||
new JoinDataComplete(new JoinData { JoinNumber = 202, JoinSpan = 1 },
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Stop Sharing & Feedback",
|
||||
JoinCapabilities = eJoinCapabilities.ToFromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("AutoShareWhileInCall")] public JoinDataComplete SourceShareAutoStart =
|
||||
new JoinDataComplete(new JoinData {JoinNumber = 203, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "When high, will autostart sharing when a call is joined",
|
||||
JoinCapabilities = eJoinCapabilities.FromSIMPL,
|
||||
JoinType = eJoinType.Digital
|
||||
});
|
||||
|
||||
[JoinName("CurrentSource")] public JoinDataComplete CurrentSource = new JoinDataComplete(new JoinData{JoinNumber = 201, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Current Source",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("CurrentParticipants")] public JoinDataComplete CurrentParticipants =
|
||||
new JoinDataComplete(new JoinData{JoinNumber = 151, JoinSpan = 1},
|
||||
new JoinMetadata()
|
||||
{
|
||||
Description = "Current Participants XSig",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Serial
|
||||
});
|
||||
|
||||
[JoinName("ParticipantCount")] public JoinDataComplete ParticipantCount = new JoinDataComplete(new JoinData{JoinNumber = 151, JoinSpan = 1},
|
||||
new JoinMetadata
|
||||
{
|
||||
Description = "Current Participant Count",
|
||||
JoinCapabilities = eJoinCapabilities.ToSIMPL,
|
||||
JoinType = eJoinType.Analog
|
||||
});
|
||||
|
||||
public VideoCodecControllerJoinMap(uint joinStart) : base(joinStart, typeof (VideoCodecControllerJoinMap))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@
|
||||
<Compile Include="VideoCodec\CiscoCodec\RoomPresets.cs" />
|
||||
<Compile Include="Cameras\CameraControl.cs" />
|
||||
<Compile Include="Display\PanasonicThDisplay.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\IHasParticipants.cs" />
|
||||
<Compile Include="VideoCodec\Interfaces\iVideoCodecInfo.cs" />
|
||||
<Compile Include="Codec\iHasCallFavorites.cs" />
|
||||
<Compile Include="Codec\iHasCallHistory.cs" />
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces
|
||||
{
|
||||
public interface IHasParticipants
|
||||
{
|
||||
CodecParticipants Participants { get; }
|
||||
}
|
||||
|
||||
public interface IHasParticipantVideoMute:IHasParticipants
|
||||
{
|
||||
void MuteVideoForParticipant(int userId);
|
||||
void UnmuteVideoForParticipant(int userId);
|
||||
void ToggleVideoForParticipant(int userId);
|
||||
}
|
||||
|
||||
public interface IHasParticipantAudioMute:IHasParticipantVideoMute
|
||||
{
|
||||
void MuteAudioForParticipant(int userId);
|
||||
void UnmuteAudioForParticipant(int userId);
|
||||
void ToggleAudioForParticipant(int userId);
|
||||
}
|
||||
|
||||
public class CodecParticipants
|
||||
{
|
||||
private List<Participant> _currentParticipants;
|
||||
|
||||
public List<Participant> CurrentParticipants {
|
||||
get { return _currentParticipants; }
|
||||
set
|
||||
{
|
||||
_currentParticipants = value;
|
||||
var handler = ParticipantsListHasChanged;
|
||||
|
||||
if(handler == null) return;
|
||||
|
||||
handler(this, new EventArgs());
|
||||
}
|
||||
}
|
||||
|
||||
public event EventHandler<EventArgs> ParticipantsListHasChanged;
|
||||
|
||||
public CodecParticipants()
|
||||
{
|
||||
_currentParticipants = new List<Participant>();
|
||||
}
|
||||
}
|
||||
|
||||
public class Participant
|
||||
{
|
||||
public bool IsHost { get; set; }
|
||||
public string Name { get; set; }
|
||||
public bool CanMuteVideo { get; set; }
|
||||
public bool CanUnmuteVideo { get; set; }
|
||||
public bool VideoMuteFb { get; set; }
|
||||
public bool AudioMuteFb { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ using PepperDash.Essentials.Core.Devices;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
using PepperDash_Essentials_Core.Bridges.JoinMaps;
|
||||
using Feedback = PepperDash.Essentials.Core.Feedback;
|
||||
|
||||
@@ -25,6 +26,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
IUsageTracking, IHasDialer, IHasContentSharing, ICodecAudio, iVideoCodecInfo, IBridgeAdvanced
|
||||
{
|
||||
private const int XSigEncoding = 28591;
|
||||
private readonly byte[] _clearBytes = XSigHelpers.ClearOutputs();
|
||||
protected VideoCodecBase(DeviceConfig config)
|
||||
: base(config)
|
||||
{
|
||||
@@ -287,6 +289,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
|
||||
LinkVideoCodecCallControlsToApi(trilist, joinMap);
|
||||
|
||||
LinkVideoCodecContentSharingToApi(trilist, joinMap);
|
||||
|
||||
if (codec is IHasCodecCameras)
|
||||
{
|
||||
LinkVideoCodecCameraToApi(codec as IHasCodecCameras, trilist, joinMap);
|
||||
@@ -317,8 +321,85 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
{
|
||||
LinkVideoCodecScheduleToApi(codec as IHasScheduleAwareness, trilist, joinMap);
|
||||
}
|
||||
|
||||
if (codec is IHasParticipants)
|
||||
{
|
||||
LinkVideoCodecParticipantsToApi(codec as IHasParticipants, trilist, joinMap);
|
||||
}
|
||||
}
|
||||
|
||||
private void LinkVideoCodecParticipantsToApi(IHasParticipants codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
codec.Participants.ParticipantsListHasChanged += (sender, args) =>
|
||||
{
|
||||
string participantsXSig;
|
||||
if (codec.Participants.CurrentParticipants.Count == 0)
|
||||
{
|
||||
participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
|
||||
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
||||
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort)codec.Participants.CurrentParticipants.Count);
|
||||
return;
|
||||
}
|
||||
|
||||
participantsXSig = Encoding.GetEncoding(XSigEncoding).GetString(_clearBytes, 0, _clearBytes.Length);
|
||||
|
||||
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
||||
|
||||
participantsXSig = UpdateParticipantsXSig(codec.Participants.CurrentParticipants);
|
||||
|
||||
trilist.SetString(joinMap.CurrentParticipants.JoinNumber, participantsXSig);
|
||||
|
||||
trilist.SetUshort(joinMap.ParticipantCount.JoinNumber, (ushort) codec.Participants.CurrentParticipants.Count);
|
||||
};
|
||||
}
|
||||
|
||||
private string UpdateParticipantsXSig(List<Participant> currentParticipants)
|
||||
{
|
||||
const int maxParticipants = 255;
|
||||
const int maxDigitals = 5;
|
||||
const int maxStrings = 1;
|
||||
const int offset = maxDigitals + maxStrings;
|
||||
var digitalIndex = maxStrings * maxParticipants; //15
|
||||
var stringIndex = 0;
|
||||
var meetingIndex = 0;
|
||||
|
||||
var tokenArray = new XSigToken[maxParticipants * offset];
|
||||
|
||||
foreach (var participant in currentParticipants)
|
||||
{
|
||||
if (meetingIndex > maxParticipants * offset) break;
|
||||
|
||||
//digitals
|
||||
tokenArray[digitalIndex] = new XSigDigitalToken(digitalIndex + 1, participant.AudioMuteFb);
|
||||
tokenArray[digitalIndex + 1] = new XSigDigitalToken(digitalIndex + 2, participant.VideoMuteFb);
|
||||
tokenArray[digitalIndex + 2] = new XSigDigitalToken(digitalIndex + 3, participant.CanMuteVideo);
|
||||
tokenArray[digitalIndex + 3] = new XSigDigitalToken(digitalIndex + 4, participant.CanUnmuteVideo);
|
||||
tokenArray[digitalIndex + 4] = new XSigDigitalToken(digitalIndex + 5, participant.IsHost);
|
||||
|
||||
//serials
|
||||
tokenArray[stringIndex] = new XSigSerialToken(stringIndex + 1, participant.Name);
|
||||
|
||||
digitalIndex += maxDigitals;
|
||||
meetingIndex += offset;
|
||||
stringIndex += maxStrings;
|
||||
}
|
||||
|
||||
return GetXSigString(tokenArray);
|
||||
}
|
||||
|
||||
private void LinkVideoCodecContentSharingToApi(BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
SharingContentIsOnFeedback.LinkInputSig(trilist.BooleanInput[joinMap.SourceShareStart.JoinNumber]);
|
||||
SharingContentIsOnFeedback.LinkComplementInputSig(trilist.BooleanInput[joinMap.SourceShareEnd.JoinNumber]);
|
||||
|
||||
SharingSourceFeedback.LinkInputSig(trilist.StringInput[joinMap.CurrentSource.JoinNumber]);
|
||||
|
||||
trilist.SetSigFalseAction(joinMap.SourceShareStart.JoinNumber, StartSharing);
|
||||
trilist.SetSigFalseAction(joinMap.SourceShareEnd.JoinNumber, StopSharing);
|
||||
|
||||
trilist.SetBoolSigAction(joinMap.SourceShareAutoStart.JoinNumber, (b) => AutoShareContentWhileInCall = b);
|
||||
}
|
||||
|
||||
private void LinkVideoCodecScheduleToApi(IHasScheduleAwareness codec, BasicTriList trilist, VideoCodecControllerJoinMap joinMap)
|
||||
{
|
||||
trilist.SetSigFalseAction(joinMap.UpdateMeetings.JoinNumber, codec.GetSchedule);
|
||||
@@ -341,6 +422,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec
|
||||
Dial(codec.CodecSchedule.Meetings[0]);
|
||||
}
|
||||
});
|
||||
|
||||
trilist.SetUshort(joinMap.MeetingCount.JoinNumber, (ushort) codec.CodecSchedule.Meetings.Count);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ using PepperDash.Essentials.Devices.Common.Codec;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
@@ -909,7 +910,7 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
/// </summary>
|
||||
public class zCommand
|
||||
{
|
||||
public partial class BookingsListResult
|
||||
public class BookingsListResult
|
||||
{
|
||||
[JsonProperty("accessRole")]
|
||||
public string AccessRole { get; set; }
|
||||
@@ -1072,6 +1073,23 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
HandStatus = new HandStatus();
|
||||
}
|
||||
|
||||
public static List<Participant> GetGenericParticipantListFromParticipantsResult(
|
||||
List<ListParticipant> participants)
|
||||
{
|
||||
return
|
||||
participants.Select(
|
||||
p =>
|
||||
new Participant
|
||||
{
|
||||
Name = p.UserName,
|
||||
IsHost = p.IsHost,
|
||||
CanMuteVideo = p.IsVideoCanMuteByHost,
|
||||
CanUnmuteVideo = p.IsVideoCanUnmuteByHost,
|
||||
AudioMuteFb = p.AudioStatusState == "AUDIO_MUTED",
|
||||
VideoMuteFb = p.VideoStatusIsSending
|
||||
}).ToList();
|
||||
}
|
||||
}
|
||||
|
||||
public class CallinCountryList
|
||||
|
||||
@@ -14,12 +14,13 @@ using PepperDash.Essentials.Core.Config;
|
||||
using PepperDash.Essentials.Core.Routing;
|
||||
using PepperDash.Essentials.Devices.Common.Cameras;
|
||||
using PepperDash.Essentials.Devices.Common.Codec;
|
||||
using PepperDash.Essentials.Devices.Common.VideoCodec.Interfaces;
|
||||
|
||||
namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
public class ZoomRoom : VideoCodecBase, IHasCodecSelfView, IHasDirectoryHistoryStack, ICommunicationMonitor,
|
||||
IRouting,
|
||||
IHasScheduleAwareness, IHasCodecCameras
|
||||
IHasScheduleAwareness, IHasCodecCameras, IHasParticipants
|
||||
{
|
||||
private const uint DefaultMeetingDurationMin = 30;
|
||||
private const string Delimiter = "\x0D\x0A";
|
||||
@@ -94,6 +95,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
Cameras = new List<CameraBase>();
|
||||
|
||||
SetUpDirectory();
|
||||
|
||||
Participants = new CodecParticipants();
|
||||
}
|
||||
|
||||
public CommunicationGather PortGather { get; private set; }
|
||||
@@ -827,51 +830,61 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
Debug.Console(1, this, "JTokenType: {0}", responseObj.Type);
|
||||
|
||||
if (responseObj.Type == JTokenType.Array)
|
||||
switch (responseObj.Type)
|
||||
{
|
||||
// if the type is array this must be the complete list
|
||||
Status.Call.Participants =
|
||||
JsonConvert.DeserializeObject<List<zCommand.ListParticipant>>(
|
||||
responseObj.ToString());
|
||||
}
|
||||
else if (responseObj.Type == JTokenType.Object)
|
||||
{
|
||||
// this is a single participant event notification
|
||||
|
||||
var participant =
|
||||
JsonConvert.DeserializeObject<zCommand.ListParticipant>(responseObj.ToString());
|
||||
|
||||
if (participant != null)
|
||||
case JTokenType.Array:
|
||||
Status.Call.Participants =
|
||||
JsonConvert.DeserializeObject<List<zCommand.ListParticipant>>(
|
||||
responseObj.ToString());
|
||||
break;
|
||||
case JTokenType.Object:
|
||||
{
|
||||
if (participant.Event == "ZRCUserChangedEventLeftMeeting" ||
|
||||
participant.Event == "ZRCUserChangedEventUserInfoUpdated")
|
||||
{
|
||||
var existingParticipant =
|
||||
Status.Call.Participants.FirstOrDefault(
|
||||
p => p.UserId.Equals(participant.UserId));
|
||||
// this is a single participant event notification
|
||||
|
||||
if (existingParticipant != null)
|
||||
var participant =
|
||||
JsonConvert.DeserializeObject<zCommand.ListParticipant>(responseObj.ToString());
|
||||
|
||||
if (participant != null)
|
||||
{
|
||||
switch (participant.Event)
|
||||
{
|
||||
if (participant.Event == "ZRCUserChangedEventLeftMeeting")
|
||||
case "ZRCUserChangedEventUserInfoUpdated":
|
||||
case "ZRCUserChangedEventLeftMeeting":
|
||||
{
|
||||
// Remove participant
|
||||
Status.Call.Participants.Remove(existingParticipant);
|
||||
}
|
||||
else if (participant.Event == "ZRCUserChangedEventUserInfoUpdated")
|
||||
{
|
||||
// Update participant
|
||||
JsonConvert.PopulateObject(responseObj.ToString(),
|
||||
existingParticipant);
|
||||
var existingParticipant =
|
||||
Status.Call.Participants.FirstOrDefault(
|
||||
p => p.UserId.Equals(participant.UserId));
|
||||
|
||||
if (existingParticipant != null)
|
||||
{
|
||||
switch (participant.Event)
|
||||
{
|
||||
case "ZRCUserChangedEventLeftMeeting":
|
||||
Status.Call.Participants.Remove(existingParticipant);
|
||||
break;
|
||||
case "ZRCUserChangedEventUserInfoUpdated":
|
||||
JsonConvert.PopulateObject(responseObj.ToString(),
|
||||
existingParticipant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case "ZRCUserChangedEventJoinedMeeting":
|
||||
Status.Call.Participants.Add(participant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (participant.Event == "ZRCUserChangedEventJoinedMeeting")
|
||||
{
|
||||
Status.Call.Participants.Add(participant);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
var participants =
|
||||
zCommand.ListParticipant.GetGenericParticipantListFromParticipantsResult(
|
||||
Status.Call.Participants);
|
||||
|
||||
Participants.CurrentParticipants = participants;
|
||||
|
||||
PrintCurrentCallParticipants();
|
||||
|
||||
break;
|
||||
@@ -1019,6 +1032,8 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
OnCallStatusChange(activeCall);
|
||||
}
|
||||
}
|
||||
var emptyList = new List<Participant>();
|
||||
Participants.CurrentParticipants = emptyList;
|
||||
}
|
||||
|
||||
UpdateCallStatus();
|
||||
@@ -1175,16 +1190,18 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
|
||||
public void PrintCurrentCallParticipants()
|
||||
{
|
||||
if (Debug.Level > 0)
|
||||
if (Debug.Level <= 0)
|
||||
{
|
||||
Debug.Console(1, this, "****************************Call Participants***************************");
|
||||
foreach (var participant in Status.Call.Participants)
|
||||
{
|
||||
Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.UserName,
|
||||
participant.AudioStatusState, participant.IsHost);
|
||||
}
|
||||
Debug.Console(1, this, "************************************************************************");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Console(1, this, "****************************Call Participants***************************");
|
||||
foreach (var participant in Participants.CurrentParticipants)
|
||||
{
|
||||
Debug.Console(1, this, "Name: {0} Audio: {1} IsHost: {2}", participant.Name,
|
||||
participant.AudioMuteFb, participant.IsHost);
|
||||
}
|
||||
Debug.Console(1, this, "************************************************************************");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1226,13 +1243,14 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
var existingCall = ActiveCalls.FirstOrDefault(c => !c.Status.Equals(eCodecCallStatus.Ringing));
|
||||
|
||||
if (callStatus == zStatus.eCallStatus.IN_MEETING)
|
||||
switch (callStatus)
|
||||
{
|
||||
existingCall.Status = eCodecCallStatus.Connected;
|
||||
}
|
||||
else if (callStatus == zStatus.eCallStatus.NOT_IN_MEETING)
|
||||
{
|
||||
existingCall.Status = eCodecCallStatus.Disconnected;
|
||||
case zStatus.eCallStatus.IN_MEETING:
|
||||
existingCall.Status = eCodecCallStatus.Connected;
|
||||
break;
|
||||
case zStatus.eCallStatus.NOT_IN_MEETING:
|
||||
existingCall.Status = eCodecCallStatus.Disconnected;
|
||||
break;
|
||||
}
|
||||
|
||||
OnCallStatusChange(existingCall);
|
||||
@@ -1525,6 +1543,12 @@ namespace PepperDash.Essentials.Devices.Common.VideoCodec.ZoomRoom
|
||||
{
|
||||
// TODO: set up far end cameras for the current call
|
||||
}
|
||||
|
||||
#region Implementation of IHasParticipants
|
||||
|
||||
public CodecParticipants Participants { get; private set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user