177 lines
6.1 KiB
C#
177 lines
6.1 KiB
C#
using Microsoft.Extensions.Logging;
|
||
using Microsoft.Extensions.Options;
|
||
using OrpaonVision.Core.Results;
|
||
using OrpaonVision.SiteApp.Runtime.Contracts;
|
||
using OrpaonVision.SiteApp.Runtime.Options;
|
||
using OrpaonVision.SiteApp.Runtime.Services;
|
||
|
||
namespace OrpaonVision.SiteApp.Runtime.Services;
|
||
|
||
/// <summary>
|
||
/// 海康相机服务适配器,将IHikCameraService适配到ICameraService接口。
|
||
/// </summary>
|
||
public sealed class HikCameraAdapter : ICameraService
|
||
{
|
||
private readonly ILogger<HikCameraAdapter> _logger;
|
||
private readonly IHikCameraService _hikCameraService;
|
||
private readonly RuntimeOptions _options;
|
||
|
||
/// <summary>
|
||
/// 构造函数。
|
||
/// </summary>
|
||
public HikCameraAdapter(
|
||
ILogger<HikCameraAdapter> logger,
|
||
IHikCameraService hikCameraService,
|
||
IOptions<RuntimeOptions> options)
|
||
{
|
||
_logger = logger;
|
||
_hikCameraService = hikCameraService;
|
||
_options = options.Value;
|
||
}
|
||
|
||
/// <inheritdoc />
|
||
public Result<CameraFrameDto> CaptureFrame()
|
||
{
|
||
try
|
||
{
|
||
// 确保相机已连接
|
||
if (!_hikCameraService.IsConnected)
|
||
{
|
||
var connectResult = ConnectDefaultCamera();
|
||
if (!connectResult.Succeeded)
|
||
{
|
||
return Result<CameraFrameDto>.Fail(connectResult.Code, connectResult.Message, connectResult.Errors.ToArray());
|
||
}
|
||
}
|
||
|
||
// 确保相机正在采集
|
||
var frameResult = _hikCameraService.GetLatestFrameWithTimestamp();
|
||
if (!frameResult.Succeeded)
|
||
{
|
||
return Result<CameraFrameDto>.Fail(frameResult.Code, frameResult.Message, frameResult.Errors.ToArray());
|
||
}
|
||
|
||
var frame = frameResult.Data;
|
||
frame.FrameId = Guid.NewGuid();
|
||
frame.CameraId = _options.CameraId;
|
||
|
||
return Result<CameraFrameDto>.Success(frame, message: "相机采图成功。");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
var traceId = Guid.NewGuid().ToString("N");
|
||
_logger.LogError(ex, "相机采图适配失败。TraceId: {TraceId}", traceId);
|
||
var result = Result.FromException(ex, "CAMERA_ADAPTER_CAPTURE_FAILED", "相机采图适配失败。", traceId);
|
||
return Result<CameraFrameDto>.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 连接默认相机。
|
||
/// </summary>
|
||
private Result ConnectDefaultCamera()
|
||
{
|
||
try
|
||
{
|
||
_logger.LogInformation("正在连接默认相机...");
|
||
|
||
// 枚举设备
|
||
var enumResult = _hikCameraService.EnumerateDevices();
|
||
if (!enumResult.Succeeded || enumResult.Data.Count == 0)
|
||
{
|
||
return Result.Fail("CAMERA_NO_DEVICES", "未发现可用的相机设备。");
|
||
}
|
||
|
||
// 尝试连接第一个设备
|
||
var firstDevice = enumResult.Data.First();
|
||
var connectResult = _hikCameraService.ConnectToDevice(firstDevice);
|
||
if (!connectResult.Succeeded)
|
||
{
|
||
return connectResult;
|
||
}
|
||
|
||
// 设置相机参数
|
||
var setParamsResult = _hikCameraService.SetCameraParameters(
|
||
width: 1920,
|
||
height: 1080,
|
||
pixelFormat: "BGR8Packed",
|
||
triggerMode: 0);
|
||
if (!setParamsResult.Succeeded)
|
||
{
|
||
_logger.LogWarning("设置相机参数失败: {Message}", setParamsResult.Message);
|
||
}
|
||
|
||
// 开始采集
|
||
var startGrabResult = _hikCameraService.StartGrabbing();
|
||
if (!startGrabResult.Succeeded)
|
||
{
|
||
return startGrabResult;
|
||
}
|
||
|
||
_logger.LogInformation("默认相机连接并启动采集成功");
|
||
return Result.Success(message: "默认相机连接成功。");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
var traceId = Guid.NewGuid().ToString("N");
|
||
_logger.LogError(ex, "连接默认相机失败。TraceId: {TraceId}", traceId);
|
||
var result = Result.FromException(ex, "CAMERA_CONNECT_DEFAULT_FAILED", "连接默认相机失败。", traceId);
|
||
return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化相机服务。
|
||
/// </summary>
|
||
public Result Initialize()
|
||
{
|
||
try
|
||
{
|
||
_logger.LogInformation("正在初始化海康相机适配器...");
|
||
|
||
// 检查连接状态
|
||
if (_hikCameraService.IsConnected)
|
||
{
|
||
_logger.LogInformation("相机已连接,无需重新连接");
|
||
return Result.Success(message: "相机适配器初始化成功。");
|
||
}
|
||
|
||
// 连接默认相机
|
||
var connectResult = ConnectDefaultCamera();
|
||
if (!connectResult.Succeeded)
|
||
{
|
||
return connectResult;
|
||
}
|
||
|
||
_logger.LogInformation("海康相机适配器初始化成功");
|
||
return Result.Success(message: "相机适配器初始化成功。");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
var traceId = Guid.NewGuid().ToString("N");
|
||
_logger.LogError(ex, "初始化海康相机适配器失败。TraceId: {TraceId}", traceId);
|
||
var result = Result.FromException(ex, "CAMERA_ADAPTER_INIT_FAILED", "初始化相机适配器失败。", traceId);
|
||
return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清理资源。
|
||
/// </summary>
|
||
public void Cleanup()
|
||
{
|
||
try
|
||
{
|
||
if (_hikCameraService.IsConnected)
|
||
{
|
||
_hikCameraService.Disconnect();
|
||
_logger.LogInformation("相机适配器清理完成");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "清理相机适配器时发生异常");
|
||
}
|
||
}
|
||
}
|