using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using static Guidaoji.Camera.CHCNetSDK; namespace Guidaoji.Camera { public class CHNetHelp { private int counter = 0; private static CHNetHelp _instance; // 私有构造函数以防止外部实例化 public CHNetHelp() { } //海康辅助函数:add by lee start private static uint iLastErr = 0; private static Int32 m_lUserID = -1; private static bool m_bInitSDK = false; private static bool m_bRecord = false; private static bool m_bTalk = false; private static Int32 m_lRealHandle = -1;//m_lRealHandle private static int lVoiceComHandle = -1; private static string str; //相机参数通过PtzGet()获得 private static float WPanPos, WTiltPos, WZoomPos; private static bool m_param_get_flag = false;//当获取成功后设置为true private static int[] iChannelNum = new int[96]; // 公共静态方法用于获取类的实例 public static CHNetHelp GetInstance() { if (_instance == null) { _instance = new CHNetHelp(); } return _instance; } //登录相关 static CHCNetSDK.REALDATACALLBACK RealData = null; static CHCNetSDK.LOGINRESULTCALLBACK LoginCallBack = null; public static CHCNetSDK.NET_DVR_PTZPOS m_struPtzCfg; public static CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLogInfo; public static CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo; public delegate void UpdateTextStatusCallback(string strLogStatus, IntPtr lpDeviceInfo); //云台相关 private bool bAuto = false; //private uint iLastErr = 0; public static int PreSetNo = 0; //public CHCNetSDK.NET_DVR_PTZPOS m_struPtzCfg; public static CHCNetSDK.NET_DVR_PTZSCOPE m_struPtzCfg1; public static CHCNetSDK.NET_DVR_PRESET_NAME[] m_struPreSetCfg = new CHCNetSDK.NET_DVR_PRESET_NAME[300]; public static void cbLoginCallBack(int lUserID, int dwResult, IntPtr lpDeviceInfo, IntPtr pUser) { string strLoginCallBack = "登录设备,lUserID:" + lUserID + ",dwResult:" + dwResult; if (dwResult == 0) { uint iErrCode = CHCNetSDK.NET_DVR_GetLastError(); strLoginCallBack = strLoginCallBack + ",错误号:" + iErrCode; } } //初始化并用固定IP的登录 public static bool CameraInit(string sIP, string sPassword) { PrintInfo("登录....."); for (int i = 0; i < 64; i++) { iChannelNum[i] = i; } m_bInitSDK = CHCNetSDK.NET_DVR_Init(); if (m_bInitSDK == false) { //MessageBox.Show("NET_DVR_Init error!"); return false; } else { //保存SDK日志 To save the SDK log CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true); } //MessageBox.Show("camera Init m_bInitSDK=="+ m_bInitSDK); //登录 // 固定的设备IP地址192.168.10.102 string fixedIP = sIP; byte[] byIP = System.Text.Encoding.Default.GetBytes(fixedIP); struLogInfo.sDeviceAddress = new byte[129]; byIP.CopyTo(struLogInfo.sDeviceAddress, 0); //设备用户名 string fixedName = "admin"; byte[] byUserName = System.Text.Encoding.Default.GetBytes(fixedName); struLogInfo.sUserName = new byte[64]; byUserName.CopyTo(struLogInfo.sUserName, 0); //设备密码ch123456 string fixedPassword = sPassword; byte[] byPassword = System.Text.Encoding.Default.GetBytes(fixedPassword); struLogInfo.sPassword = new byte[64]; byPassword.CopyTo(struLogInfo.sPassword, 0); struLogInfo.wPort = ushort.Parse("8000");//设备服务端口号 if (LoginCallBack == null) { LoginCallBack = new CHCNetSDK.LOGINRESULTCALLBACK(cbLoginCallBack);//注册回调函数 } struLogInfo.cbLoginResult = LoginCallBack; struLogInfo.bUseAsynLogin = false; //是否异步登录:0- 否,1- 是 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40(); //登录设备 Login the device m_lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo); if (m_lUserID < 0) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_Login_V40 failed, error code= " + iLastErr; //登录失败,输出错误号 //MessageBox.Show(str); } else { //登录成功 //MessageBox.Show("Login Success!"); } PrintInfo("登录结束....."); return true; } //显示视频画面 //public static void StartStopLiveView(System.Windows.Forms.Panel panel, string channel, bool isStreamID = false, string streamID = "") //{ // if (m_lUserID < 0) // { // MessageBox.Show("Please login to the device first."); // return; // } // if (m_lRealHandle < 0) // { // CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO(); // lpPreviewInfo.hPlayWnd = panel.Handle; // 预览窗口 // lpPreviewInfo.lChannel = Int16.Parse(channel); // 预览的设备通道 // lpPreviewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推 // lpPreviewInfo.dwLinkMode = 0;//连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP // lpPreviewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流 // lpPreviewInfo.dwDisplayBufNum = 1; //播放库播放缓冲区最大缓冲帧数 // lpPreviewInfo.byProtoType = 0; // lpPreviewInfo.byPreviewMode = 0; // if (isStreamID) // { // lpPreviewInfo.lChannel = -1; // byte[] byStreamID = System.Text.Encoding.Default.GetBytes(streamID); // lpPreviewInfo.byStreamID = new byte[32]; // byStreamID.CopyTo(lpPreviewInfo.byStreamID, 0); // } // // ... 实时流回调函数和预览逻辑 ... // if (RealData == null) // { // RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数 // } // m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, RealData, IntPtr.Zero); // if (m_lRealHandle < 0) // { // // ... 处理预览失败逻辑 ... // iLastErr = CHCNetSDK.NET_DVR_GetLastError(); // str = "NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败,输出错误号 // MessageBox.Show(str); // return; // } // } // else // { // // 停止预览 // if (CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle)) // { // m_lRealHandle = -1; // } // else // { // // ... 处理停止预览失败逻辑 ... // } // } //} //你可以定义一个方法 RealDataCallBack,它将在有新的视频数据到达时被调用。 public static void RealDataCallBack(Int32 lRealHandle, UInt32 dwDataType, IntPtr pBuffer, UInt32 dwBufSize, IntPtr pUser) { if (dwBufSize > 0) { byte[] sData = new byte[dwBufSize]; Marshal.Copy(pBuffer, sData, 0, (Int32)dwBufSize); string str = "实时流数据.ps"; FileStream fs = new FileStream(str, FileMode.Create); int iLen = (int)dwBufSize; fs.Write(sData, 0, iLen); fs.Close(); } } /// /// 抓拍并保存图片 /// /// 选择通道 /// 照片存放路径 /// public static bool JPEG(int iSelIndex, string sFilePath) { PrintInfo("抓图开始....."); int lChannel = iChannelNum[iSelIndex]; //通道号 Channel number CHCNetSDK.NET_DVR_JPEGPARA lpJpegPara = new CHCNetSDK.NET_DVR_JPEGPARA(); lpJpegPara.wPicQuality = 0; //图像质量 Image quality lpJpegPara.wPicSize = 0xff; //抓图分辨率 Picture size: 0xff-Auto(使用当前码流分辨率) //抓图分辨率需要设备支持,更多取值请参考SDK文档 //JPEG抓图保存成文件 Capture a JPEG picture //string sJpegPicFileName; //sJpegPicFileName = "filetest.jpg";//图片保存路径和文件名 the path and file name to save if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture(m_lUserID, lChannel, ref lpJpegPara, sFilePath)) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_CaptureJPEGPicture failed, error code= " + iLastErr; PrintInfo(str); return false; } else { str = "NET_DVR_CaptureJPEGPicture succ and the saved file is " + sFilePath; PrintInfo(str); } //JEPG抓图,数据保存在缓冲区中 Capture a JPEG picture and save in the buffer uint iBuffSize = 400000; //缓冲区大小需要不小于一张图片数据的大小 The buffer size should not be less than the picture size byte[] byJpegPicBuffer = new byte[iBuffSize]; uint dwSizeReturned = 0; if (!CHCNetSDK.NET_DVR_CaptureJPEGPicture_NEW(m_lUserID, lChannel, ref lpJpegPara, byJpegPicBuffer, iBuffSize, ref dwSizeReturned)) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_CaptureJPEGPicture_NEW failed, error code= " + iLastErr; PrintInfo(str); return false; } else { //将缓冲区里的JPEG图片数据写入文件 save the data into a file FileStream fs = new FileStream(sFilePath, FileMode.Create); int iLen = (int)dwSizeReturned; fs.Write(byJpegPicBuffer, 0, iLen); fs.Close(); str = "NET_DVR_CaptureJPEGPicture_NEW succ and save the data in buffer to 'buffertest.jpg'."; PrintInfo(str); } PrintInfo("抓图结束....."); return true; } /// /// 设置摄像头移动 /// /// 运动类型 /// 水平移动 /// 垂直移动 /// 焦距 public static bool PtzSet(OperationType operationType, float fP, float fT, float fZ) { PrintInfo("摄像头移动开始....."); int flag = 1; String str1, str2, str3; switch ((int)operationType)//操作类型 { case 0: flag = 0; m_struPtzCfg.wAction = 1; str1 = Convert.ToString(fP * 10); m_struPtzCfg.wPanPos = (ushort)(Convert.ToUInt16(str1, 16)); str2 = Convert.ToString(fT * 10); m_struPtzCfg.wTiltPos = (ushort)(Convert.ToUInt16(str2, 16)); str3 = Convert.ToString(fZ * 10); m_struPtzCfg.wZoomPos = (ushort)(Convert.ToUInt16(str3, 16)); break; case 1: flag = 0; m_struPtzCfg.wAction = 2; str1 = Convert.ToString(fP * 10); m_struPtzCfg.wPanPos = (ushort)(Convert.ToUInt16(str1, 16)); break; case 2: flag = 0; m_struPtzCfg.wAction = 3; str2 = Convert.ToString(fT * 10); m_struPtzCfg.wTiltPos = (ushort)(Convert.ToUInt16(str2, 16)); break; case 3: flag = 0; m_struPtzCfg.wAction = 4; str3 = Convert.ToString(fZ * 10); m_struPtzCfg.wZoomPos = (ushort)(Convert.ToUInt16(str3, 16)); break; case 4: flag = 0; m_struPtzCfg.wAction = 5; str1 = Convert.ToString(fP * 10); m_struPtzCfg.wPanPos = (ushort)(Convert.ToUInt16(str1, 16)); str2 = Convert.ToString(fT * 10); m_struPtzCfg.wTiltPos = (ushort)(Convert.ToUInt16(str2, 16)); break; } bool bFlag = false; if (flag == 0) { Int32 nSize = Marshal.SizeOf(m_struPtzCfg); IntPtr ptrPtzCfg = Marshal.AllocHGlobal(nSize); Marshal.StructureToPtr(m_struPtzCfg, ptrPtzCfg, false); if (!CHCNetSDK.NET_DVR_SetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_SET_PTZPOS, 1, ptrPtzCfg, (UInt32)nSize)) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_SetDVRConfig failed, error code= " + iLastErr; //设置POS参数失败 //MessageBox.Show(str); } else { bFlag = true; //MessageBox.Show("设置成功!"); } Marshal.FreeHGlobal(ptrPtzCfg); } PrintInfo("摄像头移动结束....."); return bFlag; } //获取相机焦距位置相关,P,T(ilt),zoom,m_param_get_flag 设置为true; public static float[] PtzGet() { float[] ret = { -1F, -1F, -1F }; UInt32 dwReturn = 0; Int32 nSize = Marshal.SizeOf(m_struPtzCfg); IntPtr ptrPtzCfg = Marshal.AllocHGlobal(nSize); Marshal.StructureToPtr(m_struPtzCfg, ptrPtzCfg, false); //获取参数失败 if (!CHCNetSDK.NET_DVR_GetDVRConfig(m_lUserID, CHCNetSDK.NET_DVR_GET_PTZPOS, -1, ptrPtzCfg, (UInt32)nSize, ref dwReturn)) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_GetDVRConfig failed, error code= " + iLastErr; //MessageBox.Show(str); return ret; } else { m_struPtzCfg = (CHCNetSDK.NET_DVR_PTZPOS)Marshal.PtrToStructure(ptrPtzCfg, typeof(CHCNetSDK.NET_DVR_PTZPOS)); //成功获取显示ptz参数 ushort wPanPos = Convert.ToUInt16(Convert.ToString(m_struPtzCfg.wPanPos, 16)); ret[0] = WPanPos = wPanPos * 0.1f; //textBoxPanPos.Text = Convert.ToString(WPanPos); ushort wTiltPos = Convert.ToUInt16(Convert.ToString(m_struPtzCfg.wTiltPos, 16)); ret[1] = WTiltPos = wTiltPos * 0.1f; // textBoxTiltPos.Text = Convert.ToString(WTiltPos); ushort wZoomPos = Convert.ToUInt16(Convert.ToString(m_struPtzCfg.wZoomPos, 16)); ret[2] = WZoomPos = wZoomPos * 0.1f; //textBoxZoomPos.Text = Convert.ToString(WZoomPos); m_param_get_flag = true; return ret; } } /// /// 保存录像 /// /// true:开始录像;false:停止录像 /// 选择通道 /// 视频保存路径 public static bool SaveViedo(bool bTranscribe, int iSelIndex, string sViedoPath) { PrintInfo(sViedoPath); if (bTranscribe == true) { PrintInfo("保存录像开始....."); //强制I帧 Make one key frame int lChannel = iChannelNum[iSelIndex]; //通道号 Channel number CHCNetSDK.NET_DVR_MakeKeyFrame(m_lUserID, lChannel); //开始录像 Start recording if (!CHCNetSDK.NET_DVR_SaveRealData(m_lRealHandle, sViedoPath)) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_SaveRealData failed, error code= " + iLastErr; PrintInfo(str); return false; } else { PrintInfo("NET_DVR_SaveRealData succ!"); return true; } } else { PrintInfo("保存录像结束....."); //停止录像 Stop recording if (!CHCNetSDK.NET_DVR_StopSaveRealData(m_lRealHandle)) { iLastErr = CHCNetSDK.NET_DVR_GetLastError(); str = "NET_DVR_StopSaveRealData failed, error code= " + iLastErr; PrintInfo(str); return false; } else { str = "NET_DVR_StopSaveRealData succ and the saved file is " + sViedoPath; PrintInfo(str); return true; } } } /// /// 移动摄像头过程 /// /// 控制类型 /// 水平移动 /// 垂直移动 /// 焦距 /// 选择通道 /// 抓拍路径 /// public static bool SetCameraProcess(OperationType operationType, float fP, float fT, float fZ, int iSelIndex, string sFilePath) { //移动摄像头 if (PtzSet(operationType, fP, fT, fZ)) { while (true) { float[] fCameraPose = PtzGet(); if (fCameraPose[0] == fP && fCameraPose[1] == fT && fCameraPose[2] == fZ) { break; } Thread.Sleep(100); } //拍照 if (JPEG(iSelIndex, sFilePath)) return true; else return false; } else return false; } public static void PrintInfo(string str) { string Folder = Environment.CurrentDirectory + @"\Logs"; string FileNamme = Environment.CurrentDirectory + @"\Logs\Info_" + DateTime.Now.ToString("yyyyMMdd") + ".txt"; if (!System.IO.Directory.Exists(Folder)) { System.IO.Directory.CreateDirectory(Folder); } using (TextWriter fw = new StreamWriter(FileNamme, true)) { try { FileInfo fi = new FileInfo(FileNamme); fw.WriteLine(str); } catch (Exception ex) { fw.WriteLine(ex.Message); } finally { fw.Close(); fw.Dispose(); } } } } /// /// 操作类型 /// public enum OperationType { PTZ, //倾斜+焦距 P, //水平运动 T, //上下运动 Z, //焦距 PT //倾斜运动 } }