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 InfoList { get; set; } = new(); private ReaderWriterLockSlim InfoListrwl { get; } = new(); #region Parameter public ObservableCollection 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 NetworkCardList { get; set; } = new(); public System.Net.NetworkInformation.NetworkInterface SelectedNetworkCard { get; set; } public ObservableCollection TimeoutList { get; set; } = new(); public int SelectedTimeout { get; set; } #endregion Parameter #region Command public DelegateCommand LoadedCommand { get; private set; } public ExtendCommand 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(LoadedPageAction); NvrInfoComboBoxSelectionChangedCommand = new ExtendCommand(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(); }); } /// /// 广播搜索 /// private void BroadcastSearchAction() { OperateInfoListByLock(async () => { InfoList.Clear(); Discovery onvifDiscovery = new(); IEnumerable 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); } }); } /// /// 单播搜索 /// private void UnicastSearchAction() { } /// /// 获取所有 /// private void GainAllAction() { OperateInfoListByLock(async () => { foreach (IpcInfo info in InfoList) { if (!VerifyUnit.CheckIp(info.IpcIp)) { continue; } await GainInfo(info); } }); } /// /// 获取选中 /// private void GainSelectedAction() { OperateInfoListByLock(async () => { IpcInfo info = (IpcInfo)ThatPage.InfoGrid.SelectedItem; if (info == null) { return; } await GainInfo(info); }); } /// /// 添加所有 /// private void PublishAllIpcInfoAction() { List list = new(); string nvrName = SelectedNvrInfo.NvrName; foreach (IpcInfo item in InfoList) { IpcInfo info = item.DeepCopy(); info.NvrName = nvrName; list.Add(info); } _ea.GetEvent().Publish(list); } /// /// 添加当前 /// private void PublishSelectedIpcInfoAction() { IpcInfo item = (IpcInfo)ThatPage.InfoGrid.SelectedItem; if (item == null) { return; } List list = new(); string nvrName = SelectedNvrInfo.NvrName; IpcInfo info = item.DeepCopy(); info.NvrName = nvrName; list.Add(info); _ea.GetEvent().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 list = await ctx.GetListAsync(); list.ForEach(info => NvrInfoList.Add(info)); ThatPage.NvrInfoComboBox.SelectedIndex = 0; } private void LoadNetworkCardList() { NetworkCardList.Clear(); IEnumerable 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 } }