|
|
|
using Cis.Application.Core.Component.MarkSeacher;
|
|
|
|
using Cis.Application.Core.Component.PtzServer;
|
|
|
|
using EC.Helper.CameraSDK;
|
|
|
|
using FreeRedis;
|
|
|
|
using StackExchange.Profiling.Internal;
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
|
|
|
namespace Cis.Application.Core;
|
|
|
|
|
|
|
|
public class CameraDataCenter : ISingleton
|
|
|
|
{
|
|
|
|
#region Attr
|
|
|
|
|
|
|
|
private readonly RedisClient _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(
|
|
|
|
RedisClient cache,
|
|
|
|
ICameraSdkServer cameraSdkServer,
|
|
|
|
IMarkSearcherServer markSearcherServer
|
|
|
|
)
|
|
|
|
{
|
|
|
|
_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(async () =>
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
await RefreshCameraPtzInfos();
|
|
|
|
Thread.Sleep(_options.CameraPtz.LoopInterval);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
{
|
|
|
|
IsBackground = true// 设置后台线程
|
|
|
|
};
|
|
|
|
// 启动 CameraPtzThread
|
|
|
|
RefreshCameraPtzThread.Start();
|
|
|
|
|
|
|
|
// 初始化 MarkSearcherThread
|
|
|
|
RefreshMarkSearcherThread = new Thread(async () =>
|
|
|
|
{
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
await 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 Task RefreshCameraPtzInfos()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
string[] cameraIpList = await _cache.HKeysAsync(CacheInfo.CameraIpCounts);
|
|
|
|
List<Task> tasks = new();
|
|
|
|
foreach (string cameraIp in cameraIpList)
|
|
|
|
{
|
|
|
|
tasks.Add(RefreshCameraPtzInfo(cameraIp));
|
|
|
|
}
|
|
|
|
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout));
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 刷新相机 ptz
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="cameraIp"></param>
|
|
|
|
/// <returns></returns>
|
|
|
|
private async Task RefreshCameraPtzInfo(string cameraIp)
|
|
|
|
{
|
|
|
|
bool ret = _cameraSdkServer.TryGetPtzInfoByIp(cameraIp, out PtzInfo ptzInfo);
|
|
|
|
if (!ret) return;
|
|
|
|
await _cache.HSetAsync(CacheInfo.CameraPtzInfos, cameraIp, ptzInfo.ToJson());
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// 刷新所有 markSearcher
|
|
|
|
/// </summary>
|
|
|
|
private async Task RefreshMarkSearchers()
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
string[] cameraIdList = await _cache.HKeysAsync(CacheInfo.CameraId2Ip);
|
|
|
|
List<Task> tasks = new();
|
|
|
|
foreach (string cameraId in cameraIdList)
|
|
|
|
{
|
|
|
|
tasks.Add(RefreshMarkSearcher(cameraId.ToLong()));
|
|
|
|
}
|
|
|
|
await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(_options.CameraPtz.Timeout));
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <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 = await _cache.HGetAsync(CacheInfo.CameraId2Ip, cameraId.ToString());
|
|
|
|
string ptzInfoStr = await _cache.HGetAsync(CacheInfo.CameraPtzInfos, cameraIp);
|
|
|
|
if (string.IsNullOrEmpty(ptzInfoStr)) return;
|
|
|
|
PtzInfo ptzInfo = ptzInfoStr.ToObject<PtzInfo>();
|
|
|
|
if (ptzInfo == null) return;
|
|
|
|
await markSearcher.UpdateCameraCalcParamsAsync(ptzInfo);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endregion Loop
|
|
|
|
}
|