using System.Net.Sockets; using System.Runtime.InteropServices; namespace Cis.Application.Core; /// /// Ptz Api /// public class PtzServerApi : IPtzApi, ISingleton { #region Attr private TcpClient _tcpClient { get; set; } private NetworkStream _stream { get; set; } #endregion Attr public PtzServerApi() { PtzServerOptions options = App.GetOptions(); _tcpClient = new TcpClient(options.Ip, options.Port); //创建一个 networkstream 用来写入和读取数据 _stream = _tcpClient.GetStream(); } public RequestRealControl GetPtzRrc(int cameraId) { RequestRealControl realControl = new(); try { string recieve_string = string.Empty; realControl.token = 666; realControl.CameraInfo.cameraid = cameraId; realControl.Status = true; realControl.realControlType = RealControlType.PTZINFO_GET_; byte[] data = StructToByte(realControl); _stream.Write(data, 0, data.Length); byte[] recieve_byte = new byte[_tcpClient.ReceiveBufferSize]; _stream.Read(recieve_byte, 0, (int)_tcpClient.ReceiveBufferSize); //stream.BeginRead(recieve_byte, 0, (int)tcp_client.ReceiveBufferSize,EndRead, stream); realControl = (RequestRealControl)BytetoStruct(recieve_byte, typeof(RequestRealControl)); if (realControl.PTZPositionInfo.FT < 0) { realControl.PTZPositionInfo.FT = 3600 + realControl.PTZPositionInfo.FT; } } catch (Exception) { realControl = default; } return realControl; } public PtzInfo GetPtzInfo(int cameraId) { RequestRealControl rrc = GetPtzRrc(cameraId); PtzInfo ptzInfo = PtzInfo.New(rrc.PTZPositionInfo.FP, rrc.PTZPositionInfo.FT, rrc.PTZPositionInfo.FZ); return ptzInfo; } public static byte[] StructToByte(object structObj) { //获取结构体大小 int size = Marshal.SizeOf(structObj); byte[] data = new byte[size]; //分配内存空间 IntPtr structPtr = Marshal.AllocHGlobal(size); // 将结构体数据复制到内存空间 Marshal.StructureToPtr(structObj, structPtr, false); // 将内存空间的数据拷贝到byte数组 Marshal.Copy(structPtr, data, 0, size); //释放内存 Marshal.FreeHGlobal(structPtr); return data; } public static object BytetoStruct(byte[] bytes, Type type) { object obj = new object(); try { byte[] temp = bytes; // 获取结构体大小 int size = Marshal.SizeOf(type); if (size > bytes.Length) return null; // 分配结构体内存空间 IntPtr structPtr = Marshal.AllocHGlobal(size); // 将byte数组内容拷贝到内存中 Marshal.Copy(temp, 0, structPtr, size); // 将内存空间转化为目标结构体 obj = Marshal.PtrToStructure(structPtr, type); //释放内存 Marshal.FreeHGlobal(structPtr); } catch (Exception) { } return obj; } } #region 与ptz服务交互使用结构体 //---------------------------------------------------------------------------------------- // 与ptz服务交互使用结构体 //---------------------------------------------------------------------------------------- //注意这个属性不能少 [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] public struct RequestRealControl { public int token; public CameraInfo CameraInfo; public RealControlType realControlType; //请求时 状态 true:开始;false:结束 答复时:true:成功;其他:失败 public bool Status; public PresentInfo PresentInfo; public PTZPosInfo PTZPositionInfo; //int数组,SizeConst表示数组的个数,在转换成 //byte数组前必须先初始化数组,再使用,初始化 //的数组长度必须和SizeConst一致,例test = new int[6]; //[MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] //public int[] test; } [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct CameraInfo { public int cameraid; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)] public char[] ip; public ushort port; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] private char[] user; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] private char[] password; } [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct PresentInfo { public int presentNo;//预置位编号 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] private char[] PresentName; // 预置位名称 } [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)] public struct PTZPosInfo { public int FP;//p信息 public int FT;//T信息 public int FZ;//Z信息 public int TitlePosMin;//描述点垂直参数min public int ZoomPosMin;//描述点变倍参数min public float FHorWidth;//水平宽度 精确到小数点后两位 *10000 public float FVerWidth;//垂直宽度 精确到小数点后两位 *10000 public float FFold;//zoom=1没变时的焦距 精确到小数点后两位 *100 public int CameraType; } public enum RealControlType { MOVE_UP_ = 1, MOVE_DOWN_, MOVE_LEFT_, MOVE_RIGHT_, MOVE_LEFTUP_, MOVE_LEFTDOWN_, MOVE_RIGHTUP_, MOVE_RIGHTDOWN_, ZOOM_IN_, ZOOM_OUT_, FOCUS_NEAR_, FOCUS_FAR_, IRIS_OPEN_, IRIS_CLOSE_, PRESET_SET_, PRESET_CALL_, PTZINFO_GET_, PTZINFO_SET_ } #endregion 与ptz服务交互使用结构体