finished up with some things

This commit is contained in:
Andrew Welker
2020-09-23 15:54:11 -06:00
parent 9d15704b78
commit 88263ccc77
6 changed files with 288 additions and 50 deletions

View File

@@ -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))
{
}

View File

@@ -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" />

View File

@@ -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; }
}
}

View File

@@ -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);
};
}

View File

@@ -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

View File

@@ -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>