Camera Information System
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.
 
 
 
 

174 lines
5.3 KiB

using Cis.Application.Cb;
using Cis.Application.Cm;
using Cis.Application.Core.Component.MarkSeacher;
using Cis.Application.Core.Component.PtzServer;
using EC.Helper.CameraSDK;
using StackExchange.Profiling.Internal;
using StackExchange.Redis;
using System.Collections.Concurrent;
namespace Cis.Application.Core;
public class CameraDataCenter : ISingleton
{
#region Attr
private readonly SqlSugarRepository<CbCamera> _cbCameraRep;
private readonly SqlSugarRepository<CmMarkLabel> _cmMarkLableRep;
private readonly IDatabase _cache;
private readonly CameraDataOptions _options;
private readonly ICameraSdkServer _cameraSdkServer;
private readonly IMarkSearcherServer _markSearcherServer;
/// <summary>
/// {cameraId, List(MarkLabelCalcResult)}
/// </summary>
private ConcurrentDictionary<long, List<MarkLabelCalcResult>> SearchResultListDict { get; set; } = new();
#endregion Attr
public CameraDataCenter(
IDatabase cache,
ICameraSdkServer cameraSdkServer,
IMarkSearcherServer markSearcherServer
)
{
_cbCameraRep = App.GetService<SqlSugarRepository<CbCamera>>();
_cmMarkLableRep = App.GetService<SqlSugarRepository<CmMarkLabel>>();
_cache = cache;
_options = App.GetOptions<CameraDataOptions>();
_cameraSdkServer = cameraSdkServer;
_markSearcherServer = markSearcherServer;
InitThread();
}
#region Loop
private Thread RefreshCameraPtzThread { get; set; }
private Thread RefreshMarkSearcherThread { get; set; }
/// <summary>
/// 初始化线程
/// </summary>
private void InitThread()
{
// 初始化 CameraPtzThread
RefreshCameraPtzThread = new Thread(() =>
{
while (true)
{
RefreshCameraPtzInfos();
Thread.Sleep(_options.CameraPtz.LoopInterval);
}
})
{
IsBackground = true// 设置后台线程
};
// 启动 CameraPtzThread
RefreshCameraPtzThread.Start();
// 初始化 MarkSearcherThread
RefreshMarkSearcherThread = new Thread(() =>
{
while (true)
{
RefreshMarkSearchers();
Thread.Sleep(_options.MarkSearcher.LoopInterval);
}
})
{
IsBackground = true// 设置后台线程
};
// 启动 MarkSearcherThread
RefreshMarkSearcherThread.Start();
}
/// <summary>
/// 刷新所有相机 ptz
/// 有待改善,应设置超时计数机制
/// https://blog.csdn.net/qq_28368039/article/details/118597396
/// </summary>
private async void RefreshCameraPtzInfos()
{
HashEntry[] entries = _cache.HashGetAll(CacheInfo.CameraIpCounts);
List<Task> tasks = new();
foreach (HashEntry entry in entries)
{
string cameraIp = entry.Name;
tasks.Add(RefreshCameraPtzInfo(cameraIp));
}
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout));
}
/// <summary>
/// 刷新相机 ptz
/// </summary>
/// <param name="cameraIp"></param>
/// <returns></returns>
private async Task RefreshCameraPtzInfo(string cameraIp)
{
bool ret = _cameraSdkServer.GetPtzInfoByIp(cameraIp, out PtzInfo ptzInfo);
if (!ret) return;
await _cache.HashSetAsync(CacheInfo.CameraPtzInfos, cameraIp, ptzInfo.ToJson());
}
/// <summary>
/// 刷新所有 markSearcher
/// </summary>
private async void RefreshMarkSearchers()
{
HashEntry[] entries = _cache.HashGetAll(CacheInfo.CameraId2Ip);
List<Task> tasks = new();
foreach (HashEntry entry in entries)
{
string cameraId = entry.Name;
tasks.Add(RefreshMarkSearcher(cameraId.ToLong()));
}
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout));
}
/// <summary>
/// 刷新 markSearcher
/// </summary>
/// <param name="cameraId"></param>
/// <returns></returns>
private async Task RefreshMarkSearcher(long cameraId)
{
MarkSearcherBase markSearcher = _markSearcherServer.GetSearcher(cameraId);
if (markSearcher == null) return;
string cameraIp = _cache.HashGet(CacheInfo.CameraId2Ip, cameraId);
RedisValue value = _cache.HashGet(CacheInfo.CameraPtzInfos, cameraIp);
if (!value.HasValue) return;
PtzInfo ptzInfo = value.ToString().FromJson<PtzInfo>();
markSearcher.UpdateCameraCalcParams(ptzInfo);
List<MarkLabelCalcResult> resultList = await markSearcher.SearchAsync();
SearchResultListDict[cameraId] = resultList;
}
#endregion Loop
#region Base Method
public List<MarkLabelCalcResult> GetMarkLabelCalcResultList(long cameraId)
{
bool ret = SearchResultListDict.TryGetValue(cameraId, out List<MarkLabelCalcResult> resultList);
return ret ? resultList : new List<MarkLabelCalcResult>();
}
#endregion Base Method
#region Base Method Async
public async Task<List<MarkLabelCalcResult>> GetMarkLabelCalcResultListAsync(long cameraId)
{
return await Task.Run(() =>
{
return GetMarkLabelCalcResultList(cameraId);
});
}
#endregion Base Method Async
}