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服务交互使用结构体