Unity调用大华相机SDK采集图像及基本功能设定

您所在的位置:网站首页 相机推荐5000以下 Unity调用大华相机SDK采集图像及基本功能设定

Unity调用大华相机SDK采集图像及基本功能设定

2022-12-04 14:05| 来源: 网络整理| 查看: 265

unity平台对视频播放不是很友好,而大华的SDK只有c#版本的并没有专门为unity做出来SDK,最开始尝试过使用SDK里面的方式获取YUV格式的视频流,再讲YUV格式的视频流转换为unity可以播放的格式,但是这个格式转换经常出现问题,而且很卡顿,所以呢我就用了ump插件进行rtsp视频流播放,还算是比较流畅的。

    ump插件下载链接:https://pan.baidu.com/s/1AW50i41MgGHR9npdgJOf6Q 提取码:ahez  (仅供学习,请勿商用)

    大华的设备rtsp流构成分析:

    rtsp://[username]:[password]@[address]:[port]/cam/realmonitor?channel=[id]&subtype=[type]       rtsp://   => 协议格式头     username  => 用户名,例如:admin     password  => 密码,例如:123456     address   => IPC设备的网络地址,例如:192.168.1.65     port      => IPC设备的RTSP输出端口,默认为554,若为默认可不填写     id        => 通道号,起始为1。例如通道2,则为channel=2。     type      => 码流类型,主码流为0(即subtype=0),辅码流为1(即subtype=1)。 

原文链接:https://blog.csdn.net/haoyitech/article/details/79563281  (原文介绍了大华和海康的rtsp视频流构成,我这里只用了大华的,如果有需要海康的,请自行查找)

   插件非常好用,只需要将UniversalMediaPlayer预制体拖放至场景中,将脚本上的rtsp流修改之后就可以查看视频了。

  但是!由于我们需要的功能执法记录仪上没有,我们就定制了我们需要的功能,然后将执法记录仪设备系统升级了,结果升级之后,之前的获取rtsp视频流的功能,居然无法使用了,我在和大华的技术部联系过之后,得到的结论是升值后确实不能使用rtsp来播放视频流了,如果有需要可以定制。emm... ... 这就很尴尬了,定制是不可能的,但是问题还是要解决的,在热心同时的提示和帮助之下,我们采取了使用开启一个winform程序专门用来播放视频,虽然界面丑了点,但是还是完成了需要的功能。

  winform代码:

调用大华SDK

using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using NetSDKCS; using System.Diagnostics; using System.Runtime.InteropServices; using System.IO; using System; using System.Collections.Generic; namespace MeshDaHuaTool { public class DaHuaManager { #region Field 字段,属性 private const int m_WaitTime = 5000; private const int SyncFileSize = 5 * 1024 * 1204; private static fDisConnectCallBack m_DisConnectCallBack; private static fHaveReConnectCallBack m_ReConnectCallBack; private static fRealDataCallBackEx2 m_RealDataCallBackEx2; private static fSnapRevCallBack m_SnapRevCallBack; private static fAudioDataCallBack m_AudioDataCallBack; private IntPtr m_LoginID = IntPtr.Zero; private IntPtr m_TalkID = IntPtr.Zero; private NET_DEVICEINFO_Ex m_DeviceInfo; private IntPtr m_RealPlayID = IntPtr.Zero; private uint m_SnapSerialNum = 1; private bool m_IsInSave = false; private bool m_Islogin = false; //对讲参数 private const int SampleRate = 8000; private const int AudioBit = 16; private const int PacketPeriod = 25; private const int SendAudio = 0; private const int ReviceAudio = 1; //回放参数 private IntPtr m_PlayBackID = IntPtr.Zero; //下载录像参数 IntPtr m_DownloadID = IntPtr.Zero; fTimeDownLoadPosCallBack m_DownloadPosCallBack; /// /// 步长速度 /// private int SpeedValue = 4; /// /// 最大步长速度 /// private const int MaxSpeed = 8; /// /// 最小步长速度 /// private const int MinSpeed = 1; /// /// 抓图保存根目录 /// private string m_CaptureImageDirectory; /// /// 获取SDK错误 /// private string LastError { get { return NETClient.GetLastError(); } } /// /// 是否正在保存视频 /// public bool IsinSave { get { return m_IsInSave; } } #endregion #region 回调 public Action OnSucess; public Action OnError; public Action OnCaptureSucced; #endregion /// /// 初始化 /// public void Init() { m_DisConnectCallBack = new fDisConnectCallBack(DisConnectCallBack); m_ReConnectCallBack = new fHaveReConnectCallBack(ReConnectCallBack); m_RealDataCallBackEx2 = new fRealDataCallBackEx2(RealDataCallBackEx); m_SnapRevCallBack = new fSnapRevCallBack(SnapRevCallBack); m_AudioDataCallBack = new fAudioDataCallBack(AudioDataCallBack); m_DownloadPosCallBack = new fTimeDownLoadPosCallBack(TimeDownLoadPosCallBack); try { //注册回调函数 NETClient.Init(m_DisConnectCallBack, IntPtr.Zero, null); NETClient.SetAutoReconnect(m_ReConnectCallBack, IntPtr.Zero); NETClient.SetSnapRevCallBack(m_SnapRevCallBack, IntPtr.Zero); //抓图路径赋值 m_CaptureImageDirectory = @"C:\img"; if (!Directory.Exists(m_CaptureImageDirectory)) { Directory.CreateDirectory(m_CaptureImageDirectory); } } catch (Exception ex) { OnError?.Invoke(new ErrorArgs(ErrorType.None, ex.Message)); Process.GetCurrentProcess().Kill(); } } /// /// 登录大华平台 /// /// IP地址 /// 端口 /// 用户名 /// 密码 public void Login(string ip, ushort port, string username, string password) { if (IntPtr.Zero == m_LoginID) { m_DeviceInfo = new NET_DEVICEINFO_Ex(); m_LoginID = NETClient.Login(ip, port, username, password, EM_LOGIN_SPAC_CAP_TYPE.TCP, IntPtr.Zero, ref m_DeviceInfo); if (IntPtr.Zero == m_LoginID) { OnError?.Invoke(new ErrorArgs(ErrorType.Login, LastError)); return; } OnSucess?.Invoke(ErrorType.Login); m_Islogin = true; } } /// /// 登出 /// public void Logout() { if (!m_Islogin) { return; } //关闭对讲 if (IntPtr.Zero != m_TalkID && IntPtr.Zero != m_LoginID) { NETClient.RecordStop(m_LoginID); NETClient.StopTalk(m_TalkID); } if (IsinSave) { StopSaveVideo(); } if (m_RealPlayID != IntPtr.Zero) { StopRealPlay(); } m_Islogin = false; if (m_LoginID == IntPtr.Zero) { OnError?.Invoke(new ErrorArgs(ErrorType.Logout, "m_LoginID zero")); return; } bool result = NETClient.Logout(m_LoginID); if (!result) { OnError?.Invoke(new ErrorArgs(ErrorType.Logout, LastError)); return; } m_LoginID = IntPtr.Zero; m_RealPlayID = IntPtr.Zero; OnSucess?.Invoke(ErrorType.Logout); } /// /// 开始实时播放 /// /// public void StartRealPlay(PictureBox realplay_pictureBox) { if (!m_Islogin) { OnError?.Invoke(new ErrorArgs(ErrorType.StartRealPlay, "未登录")); return; } if (IntPtr.Zero == m_RealPlayID) { // realplay 监视 EM_RealPlayType type = GetRealPlayType(); m_RealPlayID = NETClient.RealPlay(m_LoginID, GetChanel(), realplay_pictureBox.Handle, type); if (IntPtr.Zero == m_RealPlayID) { OnError?.Invoke(new ErrorArgs(ErrorType.StartRealPlay, LastError)); return; } } } /// /// 打开声音 /// public void OpenSound() { if (!NETClient.OpenSound(m_RealPlayID)) { OnError?.Invoke(new ErrorArgs(ErrorType.None, "打开声音错误: " + LastError)); } } /// /// 关闭声音 /// public void StopSound() { if (!NETClient.CloseSound()) { OnError?.Invoke(new ErrorArgs(ErrorType.None, "关闭声音失败: " + LastError)); } } /// /// 停止播放 /// public void StopRealPlay() { if (!m_Islogin) { OnError?.Invoke(new ErrorArgs(ErrorType.StopRealPlay, "未登录")); return; } if (IntPtr.Zero == m_RealPlayID) { OnError?.Invoke(new ErrorArgs(ErrorType.StopRealPlay, "未开始播放,无法停止")); return; } bool ret = NETClient.StopRealPlay(m_RealPlayID); if (!ret) { OnError?.Invoke(new ErrorArgs(ErrorType.StopRealPlay, LastError)); return; } m_RealPlayID = IntPtr.Zero; OnSucess?.Invoke(ErrorType.StopRealPlay); } /// /// 抓图 /// /// false 本地抓图,true 远程抓图 public void CaptureImage(bool isRemote = false) { //重新设置远程抓图的回调 NETClient.SetSnapRevCallBack(m_SnapRevCallBack, IntPtr.Zero); if (!m_Islogin) { OnError?.Invoke(new ErrorArgs(ErrorType.CaptureImage, "未登录")); return; } if (isRemote) { NET_SNAP_PARAMS asyncSnap = new NET_SNAP_PARAMS(); asyncSnap.Channel = (ushort)GetChanel(); asyncSnap.Quality = 6; asyncSnap.ImageSize = 2; asyncSnap.mode = 0; asyncSnap.InterSnap = 0; asyncSnap.CmdSerial = m_SnapSerialNum; bool ret = NETClient.SnapPictureEx(m_LoginID, asyncSnap, IntPtr.Zero); if (!ret) { OnError?.Invoke(new ErrorArgs(ErrorType.CaptureImage, LastError)); return; } m_SnapSerialNum++; } else { if (IntPtr.Zero == m_RealPlayID) { Console.WriteLine("没有打开实时预览,无法抓图"); return; } string fileName = "local_" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss") + ".jpg"; string filePath = @"C:\img" + "\\" + "client_" + fileName; bool result = NETClient.CapturePicture(m_RealPlayID, filePath, EM_NET_CAPTURE_FORMATS.JPEG); if (!result) { OnError?.Invoke(new ErrorArgs(ErrorType.CaptureImage, LastError)); return; } } } /// /// 保存视频 /// public void SaveVideo() { if (IntPtr.Zero == m_RealPlayID) { OnError?.Invoke(new ErrorArgs(ErrorType.StartSaveVideo, "未打开预览,无法保存录像")); return; } if (m_IsInSave) { OnError?.Invoke(new ErrorArgs(ErrorType.StartSaveVideo, "保存中,不要重复操作")); return; } SaveFileDialog saveFileDialog = new SaveFileDialog(); saveFileDialog.FileName = "video_" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"); saveFileDialog.Filter = "|*.dav"; string path = @"C:\savedata"; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } saveFileDialog.InitialDirectory = path; var res = saveFileDialog.ShowDialog(); if (res == System.Windows.Forms.DialogResult.OK) { m_IsInSave = NETClient.SaveRealData(m_RealPlayID, saveFileDialog.FileName); //call saverealdata function. if (!m_IsInSave) { saveFileDialog.Dispose(); OnError?.Invoke(new ErrorArgs(ErrorType.StartSaveVideo, LastError)); } OnSucess?.Invoke(ErrorType.StartSaveVideo); } saveFileDialog.Dispose(); } /// /// 停止保存视频 /// public void StopSaveVideo() { if (m_IsInSave) { bool ret = NETClient.StopSaveRealData(m_RealPlayID); if (!ret) { Console.WriteLine(LastError); return; } m_IsInSave = false; OnSucess?.Invoke(ErrorType.StopSaveVideo); } } #region 云台控制 /// /// 设置步长,范围在1-8 /// /// 步长速度 public void SetStepSpeed(int speedValue) { SpeedValue = Utility.Math.Clamp(speedValue, MinSpeed, MaxSpeed); } /// /// 云台控制消息 正上方为0 顺时针递增 0-7 是方向控制 /// 8-9是zoom, 8+ ,9- /// 10-11是变焦,10+,11- /// 12-13是光圈,12+,13- /// public void PTZControl(string type) { switch (type) { case "0": PTZControl(EM_EXTPTZ_ControlType.UP_CONTROL, 0, SpeedValue, true); break;//上 case "1": PTZControl(EM_EXTPTZ_ControlType.RIGHTTOP, SpeedValue, SpeedValue, true); break;//右上 case "2": PTZControl(EM_EXTPTZ_ControlType.RIGHT_CONTROL, 0, SpeedValue, true); break;//右 case "3": PTZControl(EM_EXTPTZ_ControlType.RIGHTDOWN, SpeedValue, SpeedValue, true); break;//右下 case "4": PTZControl(EM_EXTPTZ_ControlType.DOWN_CONTROL, 0, SpeedValue, true); break;//下 case "5": PTZControl(EM_EXTPTZ_ControlType.LEFTDOWN, SpeedValue, SpeedValue, true); break;//左下 case "6": PTZControl(EM_EXTPTZ_ControlType.LEFT_CONTROL, 0, SpeedValue, true); break;//左 case "7": PTZControl(EM_EXTPTZ_ControlType.LEFTTOP, SpeedValue, SpeedValue, true); break;//左上 case "8": PTZControl(EM_EXTPTZ_ControlType.ZOOM_ADD_CONTROL, 0, SpeedValue, true); break;//zoom+ case "9": PTZControl(EM_EXTPTZ_ControlType.ZOOM_DEC_CONTROL, 0, SpeedValue, true); break;//zoom- case "10": PTZControl(EM_EXTPTZ_ControlType.FOCUS_ADD_CONTROL, 0, SpeedValue, true); break;//变焦+ case "11": PTZControl(EM_EXTPTZ_ControlType.FOCUS_DEC_CONTROL, 0, SpeedValue, true); break;//变焦- case "12": PTZControl(EM_EXTPTZ_ControlType.APERTURE_ADD_CONTROL, 0, SpeedValue, true); break;//光圈+ case "13": PTZControl(EM_EXTPTZ_ControlType.APERTURE_DEC_CONTROL, 0, SpeedValue, true); break;//光圈- } } /// /// 云台控制 /// /// /// /// /// private void PTZControl(EM_EXTPTZ_ControlType type, int param1, int param2, bool isStop) { bool ret = NETClient.PTZControl(m_LoginID, GetChanel(), type, param1, param2, 0, isStop, IntPtr.Zero); if (!ret) { OnError?.Invoke(new ErrorArgs(ErrorType.PTZControl, LastError)); } } /// /// 开始对讲 /// public void SatrTalk() { if (IntPtr.Zero != m_TalkID) { OnError?.Invoke(new ErrorArgs(ErrorType.None, "正在对讲")); return; } IntPtr talkEncodePointer = IntPtr.Zero; IntPtr talkSpeakPointer = IntPtr.Zero; IntPtr talkTransferPointer = IntPtr.Zero; IntPtr channelPointer = IntPtr.Zero; NET_DEV_TALKDECODE_INFO talkCodeInfo = new NET_DEV_TALKDECODE_INFO(); talkCodeInfo.encodeType = EM_TALK_CODING_TYPE.PCM; talkCodeInfo.dwSampleRate = SampleRate; talkCodeInfo.nAudioBit = AudioBit; talkCodeInfo.nPacketPeriod = PacketPeriod; talkCodeInfo.reserved = new byte[60]; talkEncodePointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NET_DEV_TALKDECODE_INFO))); Marshal.StructureToPtr(talkCodeInfo, talkEncodePointer, true); // set talk encode type 设置对讲编码类型 NETClient.SetDeviceMode(m_LoginID, EM_USEDEV_MODE.TALK_ENCODE_TYPE, talkEncodePointer); NET_SPEAK_PARAM speak = new NET_SPEAK_PARAM(); speak.dwSize = (uint)Marshal.SizeOf(typeof(NET_SPEAK_PARAM)); speak.nMode = 0; speak.bEnableWait = false; speak.nSpeakerChannel = 0; talkSpeakPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NET_SPEAK_PARAM))); Marshal.StructureToPtr(speak, talkSpeakPointer, true); //set talk speak mode 设置对讲模式 NETClient.SetDeviceMode(m_LoginID, EM_USEDEV_MODE.TALK_SPEAK_PARAM, talkSpeakPointer); NET_TALK_TRANSFER_PARAM transfer = new NET_TALK_TRANSFER_PARAM(); transfer.dwSize = (uint)Marshal.SizeOf(typeof(NET_TALK_TRANSFER_PARAM)); transfer.bTransfer = false; talkTransferPointer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NET_TALK_TRANSFER_PARAM))); Marshal.StructureToPtr(transfer, talkTransferPointer, true); //set talk transfer mode 设置对讲是否转发模式 NETClient.SetDeviceMode(m_LoginID, EM_USEDEV_MODE.TALK_TRANSFER_MODE, talkTransferPointer); m_TalkID = NETClient.StartTalk(m_LoginID, m_AudioDataCallBack, IntPtr.Zero); Marshal.FreeHGlobal(talkEncodePointer); Marshal.FreeHGlobal(talkSpeakPointer); Marshal.FreeHGlobal(talkTransferPointer); Marshal.FreeHGlobal(channelPointer); if (IntPtr.Zero == m_TalkID) { OnError?.Invoke(new ErrorArgs(ErrorType.None, "对讲失败:" + LastError)); return; } bool ret = NETClient.RecordStart(m_LoginID); if (!ret) { NETClient.StopTalk(m_TalkID); m_TalkID = IntPtr.Zero; OnError?.Invoke(new ErrorArgs(ErrorType.None, "对讲失败:" + LastError)); return; } } /// /// 停止对讲 /// public void StopTalk() { NETClient.RecordStop(m_LoginID); NETClient.StopTalk(m_TalkID); m_TalkID = IntPtr.Zero; } #endregion /// /// 当前播放模式 /// /// private EM_RealPlayType GetRealPlayType() { return EM_RealPlayType.Realplay; } /// /// 当前播放通道 /// /// private int GetChanel() { return 0; } #region 初始化回调函数 /// /// network disconnection callback function original shape /// 断线回调函数 /// /// user LoginID:Login's returns value 登陆ID /// device IP 设备IP /// device prot 设备端口 /// user data from Init function 用户数据 private void DisConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser) { } /// /// network re-connection callback function original shape /// 重连回调函数 /// /// user LoginID:Login's returns value 登陆ID /// device IP,string type 设备IP /// device prot 设备端口 /// user data from SetAutoReconnect function 用户数据 private void ReConnectCallBack(IntPtr lLoginID, IntPtr pchDVRIP, int nDVRPort, IntPtr dwUser) { } /// /// real-time monitor data callback function original shape---extensive. support 32bit and 64bit /// 实时监视数据回调函数.支持32位和64位. /// /// monitor handle 监视句柄 /// callback data type ,only data set in dwFlag will be callback:回调数据类型 /// 0 original data (identicla SaveRealData saveddata) /// 1 frame data /// 2 yuv data /// 3 pcm audio data /// byte array, length is dwBufSize 回调数据缓存 /// callback data, except type 0, other type is base on frame, one frame data per callback /// pBuffer's size 回调数据的缓存大小 /// pointer to parameter structure,based on different type 参数结构体的指针 /// if type is 0(original) or 2(yuv), param is 0 /// if callback data is frame data, pointer to NET_VideoFrameParam /// if callback data is PCM data, pointer to NET_CBPCMDataParam /// user data,which input above private void RealDataCallBackEx(IntPtr lRealHandle, uint dwDataType, IntPtr pBuffer, uint dwBufSize, IntPtr param, IntPtr dwUser) { //do something such as save data,send data,change to YUV. 比如保存数据,发送数据,转成YUV等. } /// /// snapshot callback function original shape /// 远程抓图数据回调 /// /// loginID,login returns value 登陆ID /// byte array, length is RevLen 数据缓存 /// pointer to data /// pBuf's size 数据缓存大小 /// image encode type:0:mpeg4 I frame;10:jpeg 编码类型 /// operation NO.,not used in Synchronous capture conditions 序列号 /// user data,which input above 用户数据 private void SnapRevCallBack(IntPtr lLoginID, IntPtr pBuf, uint RevLen, uint EncodeType, uint CmdSerial, IntPtr dwUser) { if (EncodeType == 10) //.jpg// type:0:mpeg4 I frame;10:jpeg { DateTime now = DateTime.Now; string fileName = "async_" + now.ToString("yyyy-MM-dd-HH-mm-ss") + ".jpg"; string filePath = m_CaptureImageDirectory + "\\" + fileName; byte[] data = new byte[RevLen]; Marshal.Copy(pBuf, data, 0, (int)RevLen); File.WriteAllBytes(filePath, data); OnCaptureSucced?.Invoke(filePath); } } /// /// 语音数据回调函数 /// /// /// /// /// /// private void AudioDataCallBack(IntPtr lTalkHandle, IntPtr pDataBuf, uint dwBufSize, byte byAudioFlag, IntPtr dwUser) { if (lTalkHandle == m_TalkID) { if (SendAudio == byAudioFlag) { //send talk data 发送语音数据 NETClient.TalkSendData(lTalkHandle, pDataBuf, dwBufSize); } else if (ReviceAudio == byAudioFlag) { //here call netsdk decode audio,or can send data to other user.这里调用netsdk解码语音数据,或也可以把语音数据发送给另外的用户 try { NETClient.AudioDec(pDataBuf, dwBufSize); } catch (Exception ex) { Console.WriteLine(ex.Message); } } } } /// /// 下载进度的回调 /// /// 下载句柄 /// 下载总大小 /// 已下载大小 /// 文件序列 /// 录像文件信息 /// 用户数据 private void TimeDownLoadPosCallBack(IntPtr lPlayHandle, uint dwTotalSize, uint dwDownLoadSize, int index, NET_RECORDFILE_INFO recordfileinfo, IntPtr dwUser) { } #endregion } }

界面按钮添加功能及外部调用接口

/**************************** * * *发布时关闭Test宏定义 * * */ #define Test using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace MeshDaHuaTool { public partial class Form1 : Form { DaHuaManager m_DhaMgr; CommandArg m_Arg = null; public Form1() { InitializeComponent(); } public Form1(params string[] args ) { #if false m_Arg = new CommandArg("192.168.0.105", 37777, "name", "password","");//直接使用winform程序登录 #else GetCommandArg(args);//外部程序调用 #endif InitializeComponent(); this.Closed += Form1_Closed; } private void Form1_Load(object sender, EventArgs e) { this.Size = new Size(560,420); if (m_Arg == null) { MessageBox.Show("启动参数错误,点击关闭"); this.Close(); return; } if(m_Arg.Mode == "Hide") { this.Hide(); this.MinimizeBox = true; this.ShowInTaskbar = false; } m_DhaMgr = new DaHuaManager(); m_DhaMgr.OnError = OnErrorCallback; m_DhaMgr.Init(); m_DhaMgr.Login(m_Arg.IP, m_Arg.Port, m_Arg.UserName, m_Arg.Password); m_DhaMgr.StartRealPlay(pictureBox1); m_DhaMgr.OpenSound(); } //外部调用接口 private void GetCommandArg(params string[] args) { if (args.Length < 2) { return; } m_Arg = CommandArg.Parse(args[1]); } private void OnErrorCallback(ErrorArgs error) { MessageBox.Show($"错误类型:{error.APIType} ,详情: {error.Msg}"); this.Close(); } private void Form1_Closed(object sender, EventArgs e) { if (m_DhaMgr == null) return; m_DhaMgr.StopSound(); m_DhaMgr.Logout(); } //抓图 private void button1_Click(object sender, EventArgs e) { m_DhaMgr.CaptureImage(); } //保存视频 private void button2_Click(object sender, EventArgs e) { if (m_DhaMgr.IsinSave) { m_DhaMgr.StopSaveVideo(); button2.Text = "保存视频"; } else { m_DhaMgr.SaveVideo(); button2.Text = "停止保存"; } } private void pictureBox1_Click(object sender, EventArgs e) { } } }

Unity内调用:

public void VideoPlay(string IP,bool isHide) { string Mode = ""; if (isHide) { Mode = "Hide"; } var s = new CommandArg(IP, 37777, UserName, Password, Mode); //运行程序 System.Diagnostics.Process pr = new System.Diagnostics.Process();//声明一个进程类对象 pr.StartInfo.UseShellExecute = false; Debug.Log(Application.streamingAssetsPath + "/winform/MeshDaHuaTool.exe" ); //到时候放在Application.streamingAssetsPath 或其他目录中 pr.StartInfo.FileName = Application.streamingAssetsPath + "/winform/MeshDaHuaTool.exe";//指定运行的程序 pr.StartInfo.Arguments = s.ToString(); pr.Start();//运行 }

unity 调用大华设备视频_我有一支仙女棒的博客-CSDN博客



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3