785 lines
26 KiB
C#
785 lines
26 KiB
C#
using FATrace.HKNetLib.Common;
|
||
using FATrace.HKNetLib.Hardware;
|
||
using FATrace.Model;
|
||
using System.Reflection;
|
||
using System.Runtime.InteropServices;
|
||
using System.IO;
|
||
using static FATrace.HKNetLib.Hardware.CHCNetSDK;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace FATrace.HKNetLib.Wrapper
|
||
{
|
||
public class HkCamera : ICamera
|
||
{
|
||
private bool _disposedValue;
|
||
private bool _sdkInit;
|
||
private int _userId;
|
||
private string _serailNumber;
|
||
private CameraLoginInfo _loginInfo = new CameraLoginInfo();
|
||
|
||
/// <summary>
|
||
/// 初始化海康sdk
|
||
/// </summary>
|
||
/// <exception cref="BadImageFormatException"></exception>
|
||
public HkCamera()
|
||
{
|
||
_sdkInit = CHCNetSDK.NET_DVR_Init();
|
||
}
|
||
|
||
static HkCamera()
|
||
{
|
||
//设置搜索路径,兼容x86 和 x64
|
||
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||
path = Path.Combine(path, "Lib", IntPtr.Size == 8 ? "x64" : "x86");
|
||
bool ok = SetDllDirectory(path);
|
||
if (!ok) throw new System.ComponentModel.Win32Exception();
|
||
|
||
}
|
||
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
||
private static extern bool SetDllDirectory(string path);
|
||
|
||
/// <summary>
|
||
/// 获取最新的错误信息
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string GetLastError()
|
||
{
|
||
var error = CHCNetSDK.NET_DVR_GetLastError();
|
||
if (error == 0)
|
||
{
|
||
return string.Empty;
|
||
}
|
||
|
||
if (Enum.TryParse(error.ToString(), out HKErrorCode result))
|
||
{
|
||
return result.GetDesc();
|
||
}
|
||
|
||
return $"错误码: {error}";
|
||
|
||
}
|
||
|
||
public string GetSerialNumber() { return _serailNumber; }
|
||
public bool Login(CameraLoginInfo cameraLoginInfo)
|
||
{
|
||
try
|
||
{
|
||
|
||
if (_userId >= 0)
|
||
{
|
||
Logout();
|
||
}
|
||
_loginInfo = cameraLoginInfo;
|
||
var loginInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();
|
||
|
||
loginInfo.sDeviceAddress = cameraLoginInfo.IP;
|
||
loginInfo.wPort = cameraLoginInfo.Port;
|
||
loginInfo.sUserName = cameraLoginInfo.UserName;
|
||
loginInfo.sPassword = cameraLoginInfo.Password;
|
||
//是否异步登录:0- 否,1- 是
|
||
loginInfo.bUseAsynLogin = false;
|
||
|
||
var _deviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();
|
||
_userId = CHCNetSDK.NET_DVR_Login_V40(ref loginInfo, ref _deviceInfo);
|
||
_serailNumber = _deviceInfo.struDeviceV30.sSerialNumber;
|
||
return _userId >= 0;
|
||
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
#region NVR信息
|
||
|
||
/// <summary>
|
||
/// NVR IP
|
||
/// </summary>
|
||
public string NVR_IP { get; set; }
|
||
|
||
/// <summary>
|
||
/// NVR Port
|
||
/// </summary>
|
||
public ushort NVR_Port { get; set; }
|
||
|
||
/// <summary>
|
||
/// NVR UserName
|
||
/// </summary>
|
||
public string NVR_UserName { get; set; }
|
||
|
||
/// <summary>
|
||
/// NVR Pw
|
||
/// </summary>
|
||
public string NVR_Pw { get; set; }
|
||
|
||
/// <summary>
|
||
/// NVR VideoSavePath 保存的地址信息
|
||
/// </summary>
|
||
public string NVRVideoSavePath { get; set; }
|
||
|
||
#endregion
|
||
|
||
|
||
#region 公共信息
|
||
|
||
/// <summary>
|
||
/// 事件发布的消息
|
||
/// </summary>
|
||
public event EventHandler<VideoAction> VideoActionEventHandler;
|
||
|
||
/// <summary>
|
||
/// 下发视频进度过程的Handler
|
||
/// </summary>
|
||
public event EventHandler<short> NVRLoadVideoProcessEventHandler;
|
||
|
||
/// <summary>
|
||
/// 下发视频完成的Handler
|
||
/// </summary>
|
||
public event EventHandler<string> NVRLoadVideoCompleteEventHandler;
|
||
|
||
/// <summary>
|
||
/// 当前NVR登录信息
|
||
/// </summary>
|
||
public CameraLoginInfo NVRLoginInfo { get; set; } = new CameraLoginInfo();
|
||
|
||
/// <summary>
|
||
/// NVR登录状态
|
||
/// </summary>
|
||
public bool NVRLoginState { get; set; }
|
||
|
||
#endregion
|
||
|
||
|
||
#region NVR开发
|
||
|
||
/// <summary>
|
||
/// NVRCamera 集合数据
|
||
/// </summary>
|
||
public List<NVRCamera> ListNVRCamera { get; set; } = new List<NVRCamera>();
|
||
|
||
/// <summary>
|
||
/// NVR设备信息 DVR_DEVICEINFO_V30
|
||
/// </summary>
|
||
public NET_DVR_DEVICEINFO_V30 DVRDeviceInfoV30;
|
||
|
||
/// <summary>
|
||
/// DVR_IPPARACFG_V40
|
||
/// </summary>
|
||
public CHCNetSDK.NET_DVR_IPPARACFG_V40 DVR_IPPARACFG_V40 { get; set; }
|
||
|
||
/// <summary>
|
||
/// 模拟通道个数
|
||
/// </summary>
|
||
private uint dwAChanTotalNum { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 数字通道个数
|
||
/// </summary>
|
||
private uint dwDChanTotalNum { get; set; } = 0;
|
||
|
||
public NET_DVR_GET_STREAM_UNION DVR_GET_STREAM_UNION { get; set; }
|
||
|
||
public CHCNetSDK.NET_DVR_IPCHANINFO DVR_IPCHANINFO { get; set; }
|
||
|
||
/// <summary>
|
||
/// 最新的错误信息
|
||
/// </summary>
|
||
public string LastMsgErr { get; set; }
|
||
|
||
/// <summary>
|
||
/// 登录的用户Id
|
||
/// </summary>
|
||
public Int32 m_lUserID { get; set; } = -1;
|
||
|
||
/// <summary>
|
||
/// 选择的通道号
|
||
/// 一般是 一个通道对应一个相机
|
||
/// </summary>
|
||
public long iSelIndex = 0;
|
||
|
||
/// <summary>
|
||
/// 通道集合
|
||
/// </summary>
|
||
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 96, ArraySubType = UnmanagedType.U4)]
|
||
public int[] iChannelNum = new int[96];
|
||
|
||
|
||
/// <summary>
|
||
/// 下载的Handle
|
||
/// </summary>
|
||
public Int32 m_lDownHandle { get; set; } = -1;
|
||
|
||
|
||
/// <summary>
|
||
/// 用户登录
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public bool Sdk_NET_DVR_Login_V30(string DVRIPAddress, int DVRPortNumber, string DVRUserName, string DVRPassword)
|
||
{
|
||
//登录设备 Login the device
|
||
m_lUserID = CHCNetSDK.NET_DVR_Login_V30(DVRIPAddress, DVRPortNumber, DVRUserName, DVRPassword, ref DVRDeviceInfoV30);
|
||
if (m_lUserID < 0)
|
||
{
|
||
LastMsgErr = GetLastError();
|
||
//MessageBox.Show(str1);
|
||
NVRLoginState = false;
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
//登录成功
|
||
//MessageBox.Show("Login Success!");
|
||
//btnLogin.Text = "Logout";
|
||
|
||
NVRLoginInfo.IP = DVRIPAddress;
|
||
NVRLoginInfo.Port = (ushort)DVRPortNumber;
|
||
NVRLoginInfo.Password = DVRPassword;
|
||
NVRLoginInfo.UserName = DVRUserName;
|
||
NVRLoginState = true;
|
||
|
||
dwAChanTotalNum = (uint)DVRDeviceInfoV30.byChanNum;
|
||
dwDChanTotalNum = (uint)DVRDeviceInfoV30.byIPChanNum + 256 * (uint)DVRDeviceInfoV30.byHighDChanNum;
|
||
|
||
if (dwDChanTotalNum > 0)
|
||
{
|
||
InfoIPChannel();
|
||
}
|
||
else
|
||
{
|
||
for (int i = 0; i < dwAChanTotalNum; i++)
|
||
{
|
||
//ListAnalogChannel(i + 1, 1);
|
||
iChannelNum[i] = i + (int)DVRDeviceInfoV30.byStartChan;
|
||
}
|
||
// MessageBox.Show("This device has no IP channel!");
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取通道信息
|
||
/// </summary>
|
||
private void InfoIPChannel()
|
||
{
|
||
uint dwSize = (uint)Marshal.SizeOf(DVR_IPPARACFG_V40);
|
||
|
||
IntPtr ptrIpParaCfgV40 = Marshal.AllocHGlobal((Int32)dwSize);
|
||
Marshal.StructureToPtr(DVR_IPPARACFG_V40, ptrIpParaCfgV40, false);
|
||
|
||
uint dwReturn = 0;
|
||
int iGroupNo = 0; //该Demo仅获取第一组64个通道,如果设备IP通道大于64路,需要按组号0~i多次调用NET_DVR_GET_IPPARACFG_V40获取
|
||
if (!CHCNetSDK.NET_DVR_GetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_GET_IPPARACFG_V40, iGroupNo, ptrIpParaCfgV40, dwSize, ref dwReturn))
|
||
{
|
||
LastMsgErr = GetLastError();
|
||
/*str1 = "NET_DVR_GET_IPPARACFG_V40 failed, error code= " + iLastErr; //*/
|
||
//获取IP资源配置信息失败,输出错误号
|
||
//MessageBox.Show(str1);
|
||
}
|
||
else
|
||
{
|
||
// succ
|
||
DVR_IPPARACFG_V40 = (CHCNetSDK.NET_DVR_IPPARACFG_V40)Marshal.PtrToStructure(ptrIpParaCfgV40, typeof(CHCNetSDK.NET_DVR_IPPARACFG_V40));
|
||
|
||
for (int i = 0; i < dwAChanTotalNum; i++)
|
||
{
|
||
//ListAnalogChannel(i + 1, DVR_IPPARACFG_V40.byAnalogChanEnable[i]);
|
||
iChannelNum[i] = i + (int)DVRDeviceInfoV30.byStartChan;
|
||
}
|
||
|
||
byte byStreamType;
|
||
uint iDChanNum = 64;
|
||
|
||
if (dwDChanTotalNum < 64)
|
||
{
|
||
iDChanNum = dwDChanTotalNum; //如果设备IP通道小于64路,按实际路数获取
|
||
}
|
||
|
||
for (int i = 0; i < iDChanNum; i++)
|
||
{
|
||
iChannelNum[i + dwAChanTotalNum] = i + (int)DVR_IPPARACFG_V40.dwStartDChan;
|
||
|
||
byStreamType = DVR_IPPARACFG_V40.struStreamMode[i].byGetStreamType;
|
||
DVR_GET_STREAM_UNION = DVR_IPPARACFG_V40.struStreamMode[i].uGetStream;
|
||
|
||
switch (byStreamType)
|
||
{
|
||
//目前NVR仅支持0- 直接从设备取流一种方式
|
||
case 0:
|
||
dwSize = (uint)Marshal.SizeOf(DVR_GET_STREAM_UNION);
|
||
IntPtr ptrChanInfo = Marshal.AllocHGlobal((Int32)dwSize);
|
||
Marshal.StructureToPtr(DVR_GET_STREAM_UNION, ptrChanInfo, false);
|
||
DVR_IPCHANINFO = (CHCNetSDK.NET_DVR_IPCHANINFO)Marshal.PtrToStructure(ptrChanInfo, typeof(CHCNetSDK.NET_DVR_IPCHANINFO));
|
||
|
||
ListNVRCamera.Add(new NVRCamera()
|
||
{
|
||
//ChNo = DVR_IPCHANINFO.byChannel,
|
||
ChNo = (i + 1),
|
||
IPID = DVR_IPCHANINFO.byIPID,
|
||
IsOnline = DVR_IPCHANINFO.byEnable
|
||
});
|
||
|
||
//列出IP通道
|
||
//ListIPChannel(i + 1, DVR_IPCHANINFO.byEnable, DVR_IPCHANINFO.byIPID);
|
||
Marshal.FreeHGlobal(ptrChanInfo);
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
Marshal.FreeHGlobal(ptrIpParaCfgV40);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据时间获取DVR 视频数据信息
|
||
/// </summary>
|
||
public (bool Result, string Msg) Sdk_NET_DVR_GetFileByTime_V40(DateTime startTime, DateTime endTime, string SaveVideFilePath)
|
||
{
|
||
if (m_lDownHandle >= 0)
|
||
{
|
||
return (Result: false, Msg: "正在下载,请先停止下载");
|
||
}
|
||
|
||
NET_DVR_PLAYCOND struDownPara = new NET_DVR_PLAYCOND();
|
||
struDownPara.dwChannel = (uint)iChannelNum[(int)iSelIndex];
|
||
|
||
// 设置下载的开始时间
|
||
struDownPara.struStartTime.dwYear = startTime.Year;
|
||
struDownPara.struStartTime.dwMonth = startTime.Month;
|
||
struDownPara.struStartTime.dwDay = startTime.Day;
|
||
struDownPara.struStartTime.dwHour = startTime.Hour;
|
||
struDownPara.struStartTime.dwMinute = startTime.Minute;
|
||
struDownPara.struStartTime.dwSecond = startTime.Second;
|
||
|
||
// 设置下载的结束时间
|
||
struDownPara.struStopTime.dwYear = endTime.Year;
|
||
struDownPara.struStopTime.dwMonth = endTime.Month;
|
||
struDownPara.struStopTime.dwDay = endTime.Day;
|
||
struDownPara.struStopTime.dwHour = endTime.Hour;
|
||
struDownPara.struStopTime.dwMinute = endTime.Minute;
|
||
struDownPara.struStopTime.dwSecond = endTime.Second;
|
||
|
||
// 按时间下载
|
||
m_lDownHandle = CHCNetSDK.NET_DVR_GetFileByTime_V40(m_lUserID, SaveVideFilePath, ref struDownPara);
|
||
if (m_lDownHandle < 0)
|
||
{
|
||
LastMsgErr = GetLastError();
|
||
return (Result: false, Msg: $"[NET_DVR_GetFileByTime_V40] 执行下载失败:{LastMsgErr}");
|
||
}
|
||
|
||
uint iOutValue = 0;
|
||
// 该接口指定了当前要下载的录像文件,调用成功后,还需要调用 NET_DVR_PlayBackControl_V40 接口的开始播放控制命令(NET_DVR_PLAYSTART)才能实现下载。
|
||
if (!CHCNetSDK.NET_DVR_PlayBackControl_V40(m_lDownHandle, CHCNetSDK.NET_DVR_PLAYSTART, IntPtr.Zero, 0, IntPtr.Zero, ref iOutValue))
|
||
{
|
||
LastMsgErr = GetLastError();
|
||
try { CHCNetSDK.NET_DVR_StopGetFile(m_lDownHandle); } catch { }
|
||
m_lDownHandle = -1;
|
||
return (Result: false, Msg: $"[NET_DVR_PlayBackControl_V40] 执行下载控制失败:{LastMsgErr}");
|
||
}
|
||
|
||
StartDownloadProgressMonitor();
|
||
return (Result: true, Msg: "下载OK!");
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
#region 跟踪下载
|
||
|
||
private CancellationTokenSource _downloadCts;
|
||
private const int _downloadPollIntervalMs = 500;
|
||
|
||
/// <summary>
|
||
/// 启动下载进度轮询,定期发布 NVRLoadVideoProcessEventHandler 事件
|
||
/// </summary>
|
||
public void StartDownloadProgressMonitor()
|
||
{
|
||
// 先确保没有旧的轮询任务
|
||
StopDownloadProgressMonitor();
|
||
|
||
_downloadCts = new CancellationTokenSource();
|
||
var token = _downloadCts.Token;
|
||
|
||
Task.Run(async () =>
|
||
{
|
||
try
|
||
{
|
||
while (!token.IsCancellationRequested && m_lDownHandle >= 0)
|
||
{
|
||
int progress = -1;
|
||
try
|
||
{
|
||
progress = CHCNetSDK.NET_DVR_GetDownloadPos(m_lDownHandle);
|
||
}
|
||
catch
|
||
{
|
||
progress = -1;
|
||
}
|
||
|
||
if (progress >= 0)
|
||
{
|
||
short percent = (short)Math.Min(100, progress);
|
||
try
|
||
{
|
||
NVRLoadVideoProcessEventHandler?.Invoke(this, percent);
|
||
}
|
||
catch
|
||
{
|
||
// 事件订阅者异常不应中断轮询
|
||
}
|
||
|
||
if (progress >= 100)
|
||
{
|
||
// 完成:停止下载,退出轮询
|
||
Sdk_NET_DVR_StopGetFile();
|
||
|
||
NVRLoadVideoCompleteEventHandler?.Invoke(this, "下载完成");
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 发生错误,尝试停止下载并退出
|
||
Sdk_NET_DVR_StopGetFile();
|
||
try { NVRLoadVideoCompleteEventHandler?.Invoke(this, "下载失败"); } catch { }
|
||
break;
|
||
}
|
||
|
||
try { await Task.Delay(_downloadPollIntervalMs, token); } catch { /* ignore */ }
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 轮询线程异常吞掉,避免影响上层逻辑
|
||
try { NVRLoadVideoCompleteEventHandler?.Invoke(this, $"下载失败:{ex.Message}"); } catch { }
|
||
}
|
||
}, token);
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 停止下载进度轮询
|
||
/// </summary>
|
||
private void StopDownloadProgressMonitor()
|
||
{
|
||
try
|
||
{
|
||
if (_downloadCts != null)
|
||
{
|
||
if (!_downloadCts.IsCancellationRequested)
|
||
{
|
||
_downloadCts.Cancel();
|
||
}
|
||
_downloadCts.Dispose();
|
||
_downloadCts = null;
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
// 忽略取消中的异常
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 停止当前下载并清理资源
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public (bool Result, string Msg) Sdk_NET_DVR_StopGetFile()
|
||
{
|
||
try
|
||
{
|
||
// 停止轮询
|
||
StopDownloadProgressMonitor();
|
||
|
||
if (m_lDownHandle >= 0)
|
||
{
|
||
bool stopOk = CHCNetSDK.NET_DVR_StopGetFile(m_lDownHandle);
|
||
m_lDownHandle = -1;
|
||
if (!stopOk)
|
||
{
|
||
LastMsgErr = GetLastError();
|
||
return (false, $"[NET_DVR_StopGetFile] 停止下载失败:{LastMsgErr}");
|
||
}
|
||
}
|
||
return (true, "停止下载成功");
|
||
}
|
||
catch (Exception)
|
||
{
|
||
return (false, "停止下载异常");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
|
||
|
||
public bool IsOnline()
|
||
{
|
||
try
|
||
{
|
||
return CHCNetSDK.NET_DVR_RemoteControl(_userId, CHCNetSDK.NET_DVR_CHECK_USER_STATUS, IntPtr.Zero, 0);
|
||
}
|
||
catch { return false; }
|
||
}
|
||
public void Logout()
|
||
{
|
||
try
|
||
{
|
||
if (_userId >= 0)
|
||
{
|
||
CHCNetSDK.NET_DVR_Logout(_userId);
|
||
_userId = -1;
|
||
}
|
||
}
|
||
catch { }
|
||
}
|
||
|
||
private bool CheckLogin()
|
||
{
|
||
if (IsOnline()) return true;
|
||
return Login(_loginInfo);
|
||
}
|
||
/// <summary>
|
||
/// 控制云台,设备接收到控制命令后直接返回成功。不关心云台是否进行相应的动作
|
||
/// </summary>
|
||
/// <param name="cmd"></param>
|
||
/// <param name="speed">取值范围[1,7] </param>
|
||
/// <returns></returns>
|
||
public bool StartPTZControl(PtzCommand cmd, Int32 speed = 4)
|
||
{
|
||
try
|
||
{
|
||
if (!CheckLogin()) return false;
|
||
|
||
var result = CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(_userId, _loginInfo.ChannelNo, (uint)cmd, 0, (uint)speed);
|
||
return result;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 停止云台
|
||
/// </summary>
|
||
/// <param name="cmd"></param>
|
||
/// <returns></returns>
|
||
public bool StopPTZControl(PtzCommand cmd)
|
||
{
|
||
try
|
||
{
|
||
if (!CheckLogin()) return false;
|
||
var result = CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(_userId, _loginInfo.ChannelNo, (uint)cmd, 1, 4);
|
||
return result;
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 抓图
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <returns></returns>
|
||
public bool CapturePicture(string fileName)
|
||
{
|
||
if (!CheckLogin()) return false;
|
||
|
||
try
|
||
{
|
||
FileInfo fi = new FileInfo(fileName);
|
||
if (fi.Exists)
|
||
{
|
||
File.Delete(fi.FullName);
|
||
}
|
||
if (!Directory.Exists(fi.DirectoryName))
|
||
{
|
||
Directory.CreateDirectory(fi.DirectoryName);
|
||
}
|
||
|
||
CHCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new CHCNetSDK.NET_DVR_JPEGPARA
|
||
{
|
||
wPicQuality = 0,
|
||
wPicSize = 0xff
|
||
};
|
||
|
||
return CHCNetSDK.NET_DVR_CaptureJPEGPicture(_userId, _loginInfo.ChannelNo, ref lpJpegPara, fileName);
|
||
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
public bool SetFocusMode(FocusModeType focusModeType)
|
||
{
|
||
bool res = false;
|
||
var destMode = focusModeType;
|
||
CHCNetSDK.NET_DVR_FOCUSMODE_CFG focusmode_cfg = new CHCNetSDK.NET_DVR_FOCUSMODE_CFG();
|
||
focusmode_cfg.byRes = new byte[48];
|
||
focusmode_cfg.byRes1 = new byte[2];
|
||
int nSize = Marshal.SizeOf(focusmode_cfg);
|
||
focusmode_cfg.dwSize = (uint)nSize;
|
||
IntPtr ptrDeviceCfg = Marshal.AllocHGlobal(nSize);
|
||
|
||
try
|
||
{
|
||
// 获取当前模式
|
||
Marshal.StructureToPtr(focusmode_cfg, ptrDeviceCfg, false);
|
||
uint rSize = (uint)nSize;
|
||
if (!CHCNetSDK.NET_DVR_GetDVRConfig(_userId, CHCNetSDK.NET_DVR_GET_FOCUSMODECFG, 1, ptrDeviceCfg, (uint)nSize, ref rSize))
|
||
{
|
||
var errorStr = CHCNetSDK.NET_DVR_GetLastError();
|
||
return res;
|
||
}
|
||
|
||
// 如果当前模式与请求模式相同,则直接返回true
|
||
CHCNetSDK.NET_DVR_FOCUSMODE_CFG getObj = (CHCNetSDK.NET_DVR_FOCUSMODE_CFG)Marshal.PtrToStructure(ptrDeviceCfg, typeof(CHCNetSDK.NET_DVR_FOCUSMODE_CFG));
|
||
var curMode = (FocusModeType)getObj.byFocusMode;
|
||
if (curMode == destMode)
|
||
{
|
||
res = true;
|
||
return res;
|
||
}
|
||
|
||
// 否则调用设置方法
|
||
getObj.fOpticalZoomLevel = 0;
|
||
getObj.byOpticalZoom = 32;
|
||
getObj.byFocusMode = (byte)destMode;
|
||
IntPtr ptrDeviceCfg1 = Marshal.AllocHGlobal((int)getObj.dwSize);
|
||
Marshal.StructureToPtr(getObj, ptrDeviceCfg1, false);
|
||
res = CHCNetSDK.NET_DVR_SetDVRConfig(_userId, CHCNetSDK.NET_DVR_SET_FOCUSMODECFG, 1, ptrDeviceCfg1, focusmode_cfg.dwSize);
|
||
if (!res)
|
||
{
|
||
var errorStr = CHCNetSDK.NET_DVR_GetLastError();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw ex;
|
||
}
|
||
finally
|
||
{
|
||
Marshal.FreeHGlobal(ptrDeviceCfg);
|
||
}
|
||
|
||
return res;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取对焦距模式
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public FocusModeType GetFocusMode()
|
||
{
|
||
FocusModeType retValue = FocusModeType.None;
|
||
|
||
CHCNetSDK.NET_DVR_FOCUSMODE_CFG focusmode_cfg = new CHCNetSDK.NET_DVR_FOCUSMODE_CFG
|
||
{
|
||
byRes = new byte[48],
|
||
byRes1 = new byte[2]
|
||
};
|
||
int nSize = Marshal.SizeOf(focusmode_cfg);
|
||
focusmode_cfg.dwSize = (uint)nSize;
|
||
IntPtr ptrDeviceCfg = Marshal.AllocHGlobal(nSize);
|
||
|
||
try
|
||
{
|
||
Marshal.StructureToPtr(focusmode_cfg, ptrDeviceCfg, false);
|
||
uint rSize = (uint)nSize;
|
||
if (CHCNetSDK.NET_DVR_GetDVRConfig(this._userId, CHCNetSDK.NET_DVR_GET_FOCUSMODECFG, 1, ptrDeviceCfg, (uint)nSize, ref rSize))
|
||
{
|
||
CHCNetSDK.NET_DVR_FOCUSMODE_CFG getObj = (CHCNetSDK.NET_DVR_FOCUSMODE_CFG)Marshal.PtrToStructure(ptrDeviceCfg, typeof(CHCNetSDK.NET_DVR_FOCUSMODE_CFG));
|
||
retValue = (FocusModeType)getObj.byFocusMode;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw ex;
|
||
}
|
||
finally
|
||
{
|
||
Marshal.FreeHGlobal(ptrDeviceCfg);
|
||
}
|
||
|
||
return retValue;
|
||
}
|
||
|
||
public bool Shutdown()
|
||
{
|
||
try
|
||
{
|
||
if (!CheckLogin()) return false;
|
||
|
||
return CHCNetSDK.NET_DVR_ShutDownDVR(_userId);
|
||
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
public bool Reboot()
|
||
{
|
||
try
|
||
{
|
||
if (!CheckLogin()) return false;
|
||
|
||
return CHCNetSDK.NET_DVR_RebootDVR(_userId);
|
||
}
|
||
catch
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
#region 释放接口
|
||
protected virtual void Dispose(bool disposing)
|
||
{
|
||
if (!_disposedValue)
|
||
{
|
||
if (disposing)
|
||
{
|
||
// TODO: 释放托管状态(托管对象)
|
||
}
|
||
|
||
if (_sdkInit)
|
||
{
|
||
if (_userId >= 0)
|
||
{
|
||
Logout();
|
||
}
|
||
try
|
||
{
|
||
CHCNetSDK.NET_DVR_Cleanup();
|
||
}
|
||
catch { }
|
||
}
|
||
|
||
_disposedValue = true;
|
||
}
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
Dispose(disposing: true);
|
||
GC.SuppressFinalize(this);
|
||
}
|
||
#endregion
|
||
}
|
||
}
|