You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

346 lines
9.2 KiB

using EC.Entity.CameraInfo;
using EC.Onvif;
using EC.Onvif.Common;
using EC.Onvif.Device;
using EC.Onvif.Media;
using EC.Onvif.RemoteDiscovery;
using EC.Service.CameraInfo;
using EC.UsingEventAggregator;
using ECMonitor.Code.Models;
using ECMonitor.MVVM;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Controls;
namespace ECMonitor.Page.SystemSet
{
public class SearchIpcViewModel : BaseModel
{
private SearchIpc ThatPage { get; set; }
public ObservableCollection<IpcInfo> InfoList { get; set; } = new();
private ReaderWriterLockSlim InfoListrwl { get; } = new();
#region Parameter
public ObservableCollection<NvrInfo> NvrInfoList { get; set; } = new();
public NvrInfo SelectedNvrInfo { get; set; }
private string _userName { get; set; }
public string UserName
{ get { return _userName; } set { _userName = value; RaisePropertyChanged(nameof(UserName)); } }
private string _password { get; set; }
public string Password
{ get { return _password; } set { _password = value; RaisePropertyChanged(nameof(Password)); } }
public ObservableCollection<System.Net.NetworkInformation.NetworkInterface> NetworkCardList { get; set; } = new();
public System.Net.NetworkInformation.NetworkInterface SelectedNetworkCard { get; set; }
public ObservableCollection<int> TimeoutList { get; set; } = new();
public int SelectedTimeout { get; set; }
#endregion Parameter
#region Command
public DelegateCommand<UserControl> LoadedCommand { get; private set; }
public ExtendCommand<SelectionChangedEventArgs> NvrInfoComboBoxSelectionChangedCommand { get; private set; }
public DelegateCommand RefreshCommand { get; private set; }
public DelegateCommand BroadcastSearchCommand { get; private set; }
public DelegateCommand UnicastSearchCommand { get; private set; }
public DelegateCommand GainAllCommand { get; private set; }
public DelegateCommand GainSelectedCommand { get; private set; }
public DelegateCommand PublishAllCommand { get; private set; }
public DelegateCommand PublishSelectedCommand { get; private set; }
#endregion Command
public SearchIpcViewModel(IRegionManager regionManager, IEventAggregator ea) : base(regionManager, ea)
{
LoadedCommand = new DelegateCommand<UserControl>(LoadedPageAction);
NvrInfoComboBoxSelectionChangedCommand = new ExtendCommand<SelectionChangedEventArgs>(NvrInfoComboBoxSelectionChangedAction);
RefreshCommand = new DelegateCommand(RefreshAction);
BroadcastSearchCommand = new DelegateCommand(BroadcastSearchAction);
UnicastSearchCommand = new DelegateCommand(UnicastSearchAction);
GainAllCommand = new DelegateCommand(GainAllAction);
GainSelectedCommand = new DelegateCommand(GainSelectedAction);
PublishAllCommand = new DelegateCommand(PublishAllIpcInfoAction);
PublishSelectedCommand = new DelegateCommand(PublishSelectedIpcInfoAction);
}
#region Event Action
private void LoadedPageAction(UserControl view)
{
if (ThatPage != null) { return; }
ThatPage = (SearchIpc)view;
RefreshAction();
}
private void NvrInfoComboBoxSelectionChangedAction(SelectionChangedEventArgs e)
{
NvrInfo selectedNvrInfo = (NvrInfo)ThatPage.NvrInfoComboBox.SelectedItem;
UserName = selectedNvrInfo?.UserName;
Password = selectedNvrInfo?.UserPwd;
}
#endregion Event Action
#region Operate Action
private void RefreshAction()
{
OperateInfoListByLock(() =>
{
LoadNvrInfoList();
LoadNetworkCardList();
LoadTimeoutList();
});
}
/// <summary>
/// 广播搜索
/// </summary>
private void BroadcastSearchAction()
{
OperateInfoListByLock(async () =>
{
InfoList.Clear();
Discovery onvifDiscovery = new();
IEnumerable<DiscoveryDevice> deviceList = await onvifDiscovery.DiscoverByAdapter(new[] { SelectedNetworkCard }, SelectedTimeout);
foreach (DiscoveryDevice device in deviceList)
{
IpcInfo info = new();
info.IpcType = device.Mfr;
info.IpcIp = device.Address;
info.OnvifAddr = device.XAdresses.Count > 0 ? device.XAdresses[0] : string.Empty;
info.IpcEnableBool = true;
InfoList.Add(info);
}
});
}
/// <summary>
/// 单播搜索
/// </summary>
private void UnicastSearchAction()
{
}
/// <summary>
/// 获取所有
/// </summary>
private void GainAllAction()
{
OperateInfoListByLock(async () =>
{
foreach (IpcInfo info in InfoList)
{
if (!VerifyUnit.CheckIp(info.IpcIp))
{
continue;
}
await GainInfo(info);
}
});
}
/// <summary>
/// 获取选中
/// </summary>
private void GainSelectedAction()
{
OperateInfoListByLock(async () =>
{
IpcInfo info = (IpcInfo)ThatPage.InfoGrid.SelectedItem;
if (info == null) { return; }
await GainInfo(info);
});
}
/// <summary>
/// 添加所有
/// </summary>
private void PublishAllIpcInfoAction()
{
List<IpcInfo> list = new();
string nvrName = SelectedNvrInfo.NvrName;
foreach (IpcInfo item in InfoList)
{
IpcInfo info = item.DeepCopy<IpcInfo>();
info.NvrName = nvrName;
list.Add(info);
}
_ea.GetEvent<SendIpcInfoListEvent>().Publish(list);
}
/// <summary>
/// 添加当前
/// </summary>
private void PublishSelectedIpcInfoAction()
{
IpcInfo item = (IpcInfo)ThatPage.InfoGrid.SelectedItem;
if (item == null) { return; }
List<IpcInfo> list = new();
string nvrName = SelectedNvrInfo.NvrName;
IpcInfo info = item.DeepCopy<IpcInfo>();
info.NvrName = nvrName;
list.Add(info);
_ea.GetEvent<SendIpcInfoListEvent>().Publish(list);
}
#endregion Operate Action
#region Operate List
private void OperateInfoListByLock(Action action)
{
if (InfoListrwl.IsWriteLockHeld) { return; }
if (!InfoListrwl.TryEnterWriteLock(100)) { return; }
try
{
action?.Invoke();
}
finally
{
InfoListrwl.ExitWriteLock();
}
}
private async void LoadNvrInfoList()
{
NvrInfoList.Clear();
using NvrInfoContext ctx = new();
List<NvrInfo> list = await ctx.GetListAsync();
list.ForEach(info => NvrInfoList.Add(info));
ThatPage.NvrInfoComboBox.SelectedIndex = 0;
}
private void LoadNetworkCardList()
{
NetworkCardList.Clear();
IEnumerable<System.Net.NetworkInformation.NetworkInterface> adapterList = OnvifUdpClient.GetVaildNetworkAdapters();
foreach (System.Net.NetworkInformation.NetworkInterface adapter in adapterList)
{
NetworkCardList.Add(adapter);
}
ThatPage.NetworkCardComboBox.SelectedIndex = 0;
}
private void LoadTimeoutList()
{
TimeoutList.Clear();
TimeoutList.Add(2);
TimeoutList.Add(5);
TimeoutList.Add(10);
TimeoutList.Add(15);
TimeoutList.Add(30);
ThatPage.TimeoutComboBox.SelectedIndex = 0;
}
#endregion Operate List
#region Helper
private StreamSetup RtspStreamSetup { get; } = new()
{
Stream = StreamType.RTPUnicast,
Transport = new() { Protocol = TransportProtocol.RTSP }
};
private async Task GainInfo(IpcInfo info)
{
bool isMediaGain = info.IsUriGain(info.MediaAddr);
bool isPtzGain = info.IsUriGain(info.PtzAddr);
bool isRtspGain = info.IsUriGain(info.RtspMain) || info.IsUriGain(info.RtspSub);
if (!isMediaGain || !isPtzGain)
{
try
{
DeviceClient device = await OnvifClientFactory.CreateDeviceClientAsync(info.IpcIp, UserName, Password);
if (string.IsNullOrEmpty(info.IpcType))
{
GetDeviceInformationResponse resp = await device.GetDeviceInformationAsync(new());
info.SetValue("IpcType", resp.Manufacturer);
}
GetCapabilitiesResponse caps;
if (!isMediaGain)
{
caps = await device.GetCapabilitiesAsync(new[] { CapabilityCategory.Media });
info.SetValue("MediaAddr", caps.Capabilities.Media.XAddr);
};
if (!isPtzGain)
{
caps = await device.GetCapabilitiesAsync(new[] { CapabilityCategory.PTZ });
info.SetValue("PtzAddr", caps.Capabilities.PTZ.XAddr);
};
}
catch (Exception)
{
}
finally
{
if (!info.IsUriGain(info.MediaAddr)) { info.SetValue("MediaAddr", info.FaultUri); }
if (!info.IsUriGain(info.PtzAddr)) { info.SetValue("PtzAddr", info.FaultUri); }
}
}
if (!isRtspGain)
{
try
{
MediaClient media = await OnvifClientFactory.CreateMediaClientAsync(info.IpcIp, UserName, Password);
info.SetValue("UserName", UserName);
info.SetValue("UserPwd", Password);
GetProfilesResponse profiles = await media.GetProfilesAsync();
string profileToken;
if (profiles.Profiles.Length >= 1)
{
profileToken = profiles.Profiles[0].token;
MediaUri streamUri = await media.GetStreamUriAsync(RtspStreamSetup, profileToken);
info.SetValue("RtspMain", streamUri.Uri);
}
if (profiles.Profiles.Length >= 2)
{
profileToken = profiles.Profiles[1].token;
MediaUri streamUri = await media.GetStreamUriAsync(RtspStreamSetup, profileToken);
info.SetValue("RtspSub", streamUri.Uri);
}
}
catch (Exception)
{
}
finally
{
if (!info.IsUriGain(info.RtspMain)) { info.SetValue("RtspMain", info.FaultUri); }
if (!info.IsUriGain(info.RtspSub)) { info.SetValue("RtspSub", info.FaultUri); }
}
}
}
#endregion Helper
}
}