当前位置:   article > 正文

海康摄像头二次开发

海康摄像头二次开发

硬件介绍

请添加图片描述

参考资料

下载网址
这个专栏讲的挺不错的
完整程序代码
在这里插入图片描述

在这里插入图片描述

连接

在这里插入图片描述

登录激活,在网页上使用的时候需要下载插件,不然无法实现预览功能。
在这里插入图片描述
在这里插入图片描述
下载玩插件就能显示 能用了

基础知识

码流

1、码流(Data Rate)是指视频文件在单位时间内使用的数据流量,也叫码率,是视频编码中画面质量控制中最重要的部分。同样分辨率下,视频文件的码流越大,压缩比就越小,画面质量就越好。

2、主码流与子码流的区别

  • 海康威视首家提出了主码流与子码流这样的概念,是为了解决在网络情况不好时为了满足远程预览的流畅性降低码率,而不影响本地录像提出的双码流技术,即一路视频进入NVR(Network Video Recorder即网络硬盘录像机)后,NVR可以编码提供两种码流,主码流和子码流,主码流分辨率高于子码流,主码流用来录像,子码流用来网传。这就叫双码流技术。目的是用于解决监控录像的本地存储和网络传输的图像的质量问题。
  • 主码流一般码流较大,清晰度高,占用的带宽也就高。子码流在主码流的图像环境下降低了图像格式,清晰度较主码流要低,占用带宽小。主码流一般用于存储,子码流用于网传。主码流本地存储,子码流适用于图像在低带宽网络上传输。
  • 总结:主码流图像清晰,所以占用带宽大,因此更适用于保存。而子码流图像不清晰一点,更适用于网络传输。

代码

1、适用型号
在这里插入图片描述

2、分为三个部分,登录 预览 对讲

功能实现

在这里插入图片描述
云台控制
在这里插入图片描述

加载dll

1、海康提供的设备网络SDK是封装的动态链接库(Windows的dll或者Linux的so),各种开发语言对接SDK,都是通过加载动态库链接,调用动态库中的接口实现功能模块对接,因此,设备网络SDK的对接不区分开发语言,而且对接的流程和对应的接口都是通用的,各种语言调用动态库的方式有所不同。本文重点介绍C#开发语言如何对接设备网络SDK。

2、使用DllImport方式加载封装好的.dll动态库(DllImport是System.Runtime.InteropServices命名空间下的一个属性类,因此要使用DllImport,必须在HCNetSDK.cs类中在先导入这个类“using System.Runtime.InteropServices;”),从而调用动态库里封装好的方法。我们需要做的只是将dll导入release/debug目录中;因为C/C++的类型与C#的数据类型是不一样的,动态库中的C/C++的数据类型必须转换成C#对应类型;然后声明;然后调用就可以了。

3、需要注意的是,程序编译环境位数于加载的SDK动态库位数需要保持一致。可以右键项目,在属性–生成–目标平台,选择对应的位数。如果是”Any CPU”则加载的库文件需要和操作系统位数一致(64位操作系统下加载64位库文件,32位操作系统下加载32位库文件),如果是“X86”则只能加载32位的SDK动态库,如果是“X64”则只能加载64位的SDK动态库。

在这里插入图片描述
在这里插入图片描述

下面是直接copy 官方的demo中已经弄好了的

下载链接,想直接copy进来的 太多了放不下 稍微放一点点吧

using System;
using System.Runtime.InteropServices;

namespace LoginTest
{
    public class HCNetSDK
    {
        #region HCNetSDK.dll function definition
        // function definition
        /* The SDK initialization function */

        // 初始化SDK,调用其他SDK函数的前提
        [DllImport(@"HCNetSDK.dll")]
        public static extern bool NET_DVR_Init();

        // 启用日志文件写入接口
        [DllImport(@"HCNetSDK.dll")]
        public static extern bool NET_DVR_SetLogToFile(int nLogLevel, IntPtr strLogDir, bool bAutoDel);

        // 返回最后操作的错误码
        [DllImport(@"HCNetSDK.dll")]
        public static extern uint NET_DVR_GetLastError();

        // 释放SDK资源,在程序结束之前调用
        [DllImport(@"HCNetSDK.dll")]
        public static extern bool NET_DVR_Cleanup();

        // 登录接口
        [DllImport(@"HCNetSDK.dll")]
        public static extern int NET_DVR_Login_V40(ref NET_DVR_USER_LOGIN_INFO pLoginInfo, ref NET_DVR_DEVICEINFO_V40 lpDeviceInfo);

        // 用户注销
        [DllImport(@"HCNetSDK.dll")]
        public static extern bool NET_DVR_Logout(int lUserID);

        // 回调函数声明,登录状态回调函数
        public delegate void LoginResultCallBack(int lUserID, uint dwResult, ref NET_DVR_DEVICEINFO_V30 lpDeviceInfo, IntPtr pUser);
        #endregion
    }
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
#region HCNetSDK.dll structure definition

[StructLayout(LayoutKind.Sequential)]
public struct NET_DVR_USER_LOGIN_INFO
{
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NET_DVR_DEV_ADDRESS_MAX_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sDeviceAddress;
    public byte byUseTransport;
    public ushort wPort;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NET_DVR_LOGIN_USERNAME_MAX_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sUserName;
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = NET_DVR_LOGIN_PASSWD_MAX_LEN, ArraySubType = UnmanagedType.I1)]
    public byte[] sPassword;
    public LoginResultCallBack cbLoginResult;
    public IntPtr pUser;
    public bool bUseAsynLogin;
    public byte byProxyType; //0:不使用代理,1:使用标准代理,2:使用EHome代理
    public byte byUseUTCTime;    //0-不进行转换,默认,1-接口上输入输出全部使用UTC时间,SDK完成UTC时间与设备时区的转换,2-接口上输入输出全部使用平台本地时间,SDK完成平台本地时间与设备时区的转换
    public byte byLoginMode; //0-Private, 1-ISAPI, 2-自适应
    public byte byHttps;    //0-不适用tls,1-使用tls 2-自适应
    public uint iProxyID;    //代理服务器序号,添加代理服务器信息时,相对应的服务器数组下表值
    public byte byVerifyMode;  //认证方式,0-不认证,1-双向认证,2-单向认证;认证仅在使用TLS的时候生效;    
    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 119, ArraySubType = UnmanagedType.I1)]
    public byte[] byRes3;
}

public const int NET_DVR_DEV_ADDRESS_MAX_LEN = 129; //device address max length
public const int NET_DVR_LOGIN_USERNAME_MAX_LEN = 64;   //login username max length
public const int NET_DVR_LOGIN_PASSWD_MAX_LEN = 64; //login password max length

#endregion


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

登录

分为以下几个步骤

1、在构造函数中,初始化SDK:NET_DVR_Init()

 private bool m_bInitSDK = false;
  • 1
        public Form1()
        {
            InitializeComponent();
            m_bInitSDK = CHCNetSDK.NET_DVR_Init();//就这么一句 下面是调用成功或者失败进行的操作
            if (m_bInitSDK == false)
            {
                MessageBox.Show("NET_DVR_Init error!");
                return;
            }
            else
            {
                //保存SDK日志 To save the SDK log
                CHCNetSDK.NET_DVR_SetLogToFile(3, "C:\\SdkLog\\", true);
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

2、登录(注册)设备.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo);

  • 前面都是登录api中的结构体进行设置
  • 登录有两种模式:同步和异步,同步比较简单,直接调用API就可以了,缺点是需要阻塞界面,用户体验不好;异步,无需阻塞界面,登录状态通过回调函数告知,相对比较麻烦一些详解
        public static  Int32 m_lUserID = -1;//用户ID 登录句柄 登录成功就为非负数 否则为负数
        public CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLogInfo;//登录信息结构体
        CHCNetSDK.LOGINRESULTCALLBACK LoginCallBack = null;
        public CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo;
        private uint iLastErr = 0;
        private string str;
        string conState = "登录状态";
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

        private void uiButton2_Click(object sender, EventArgs e)
        {
            if (m_lUserID < 0)
            {
                //1、struLogInfo  结构体的创建与赋值
                struLogInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO();

                //设备IP地址或者域名
                string nip = "192.168.1.64";
                byte[] byIP = System.Text.Encoding.Default.GetBytes(nip);
                struLogInfo.sDeviceAddress = new byte[129];
                byIP.CopyTo(struLogInfo.sDeviceAddress, 0);

                //设备用户名
                string nusername = "admin";
                byte[] byUserName = System.Text.Encoding.Default.GetBytes(nusername);
                struLogInfo.sUserName = new byte[64];
                byUserName.CopyTo(struLogInfo.sUserName, 0);

                //设备密码
                string npassword = "*******";//这里输密码
                byte[] byPassword = System.Text.Encoding.Default.GetBytes(npassword);
                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- 是 


                //2、DeviceInfo: 结构体的创建与赋值
                DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();

                //3、登录设备 Login the device
                //m_lUserID:就是用户ID
                m_lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLogInfo, ref DeviceInfo);//NET_DVR_Login_V40用户注册设备
               
                
                if (m_lUserID < 0)
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();//获得错误码
                    str = "NET_DVR_Login_V40 failed, error code= " + iLastErr; //登录失败,输出错误号
                    MessageBox.Show(str);
                    return;
                }
                else
                {
                    //登录成功
                    MessageBox.Show("Login Success!");
                    uiLabel1.Text = string.Concat(conState, "成功");
                }

            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
        public delegate void UpdateTextStatusCallback(string strLogStatus, IntPtr lpDeviceInfo);
        /**
         * lUserID 
              [out] 用户ID,NET_DVR_Login_V40的返回值 
            dwResult 
              [out] 登录状态:0- 异步登录失败,1- 异步登录成功 
            lpDeviceInfo 
              [out] 设备信息,设备序列号、通道、能力等参数 
            pUser 
              [out] 用户数据 
         */  
        public 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;
            }

            //下面代码注释掉也会崩溃
            if (InvokeRequired)
            {
                object[] paras = new object[2];
                paras[0] = strLoginCallBack;
                paras[1] = lpDeviceInfo;
                uiLabel1.BeginInvoke(new UpdateTextStatusCallback(UpdateClientList), paras);
            }
            else
            {
                //创建该控件的主线程直接更新信息列表 
                UpdateClientList(strLoginCallBack, lpDeviceInfo);
            }

        }
        public void UpdateClientList(string strLogStatus, IntPtr lpDeviceInfo)
        {
            //列表新增报警信息
            uiLabel1.Text = "登录状态:" + strLogStatus;
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

3、注销 释放资源

            //注销登录 Logout the device
            if (m_lUserID >= 0)
            {
                CHCNetSDK.NET_DVR_Logout(m_lUserID);
                m_lUserID = -1;
            }

            CHCNetSDK.NET_DVR_Cleanup();//释放SDK资源
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

预览

登录之后使用
直接demo和SDK一起看 等需要高端应用的时候再研究 不然直接复制demo的代码就可以正常使用了
我增加了一段预览后 切到一个预置点,这个点的位置通过云台控制设置(云台设置这里需要点击保存)

        public static Int32 m_lRealHandle = -1;//预览api 句柄 失败就是小于-1
        CHCNetSDK.REALDATACALLBACK RealData = null;

        private void uiButton5_Click(object sender, EventArgs e)
        {
            if (m_lUserID < 0)
            {
                MessageBox.Show("Please login the device firstly");
                return;
            }

            if (m_lRealHandle < 0)
            {
                CHCNetSDK.NET_DVR_PREVIEWINFO lpPreviewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();
                lpPreviewInfo.hPlayWnd = pictureBox1.Handle;//预览窗口
                lpPreviewInfo.lChannel = Int16.Parse(textBoxChannel.Text);//预te览的设备通道
                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 (textBoxID.Text != "")
                {
                    lpPreviewInfo.lChannel = -1;
                    byte[] byStreamID = System.Text.Encoding.Default.GetBytes(textBoxID.Text);
                    lpPreviewInfo.byStreamID = new byte[32];
                    byStreamID.CopyTo(lpPreviewInfo.byStreamID, 0);
                }


                if (RealData == null)
                {
                    RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数
                }

                IntPtr pUser = new IntPtr();//用户数据

                //打开预览 Start live view 
                m_lRealHandle = CHCNetSDK.NET_DVR_RealPlay_V40(m_lUserID, ref lpPreviewInfo, null/*RealData*/, pUser);
                if (m_lRealHandle < 0)
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_RealPlay_V40 failed, error code= " + iLastErr; //预览失败,输出错误号
                    MessageBox.Show(str);
                    return;
                }
                else
                {
                    //预览成功
                    uiButton5.Text = "Stop Live View";
                }

                //调用预设点
                    if (!CHCNetSDK.NET_DVR_PTZPreset_Other(m_lUserID, 1, CHCNetSDK.GOTO_PRESET,ptzC.PresetPoint))
                    {
                        iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                        str = "NET_DVR_PTZPreset_Other failed, error code= " + iLastErr;
                        MessageBox.Show(str);
                        return;
                    }
                    else
                    {
                       // MessageBox.Show("调用成功");
                    }
                    return;
            }
            else
            {
                //停止预览 Stop live view 
                if (!CHCNetSDK.NET_DVR_StopRealPlay(m_lRealHandle))
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_StopRealPlay failed, error code= " + iLastErr;
                    MessageBox.Show(str);
                    return;
                }
                m_lRealHandle = -1;
                uiButton5.Text = "Live View";

            }
            return;
        }

        public 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);//System.Runtime.InteropServices

                string str = "实时流数据.ps";
                FileStream fs = new FileStream(str, FileMode.Create);
                int iLen = (int)dwBufSize;
                // 将字节块写入文件流。
                fs.Write(sData, 0, iLen);
                fs.Close();
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100

语音

登录之后使用
直接demo和SDK一起看 等需要高端应用的时候再研究 不然直接复制demo的代码就可以正常使用了

      private bool m_bTalk = false;
        private int lVoiceComHandle = -1;
        //开始语音对讲 Start two-way talk
        CHCNetSDK.VOICEDATACALLBACKV30 VoiceData = new CHCNetSDK.VOICEDATACALLBACKV30(VoiceDataCallBack);//预览实时流回调函数

        private void uiButton1_Click(object sender, EventArgs e)
        {
            if (m_bTalk == false)
            {

                lVoiceComHandle = CHCNetSDK.NET_DVR_StartVoiceCom_V30(m_lUserID, 1, true, VoiceData, IntPtr.Zero);
                //bNeedCBNoEncData [in]需要回调的语音数据类型:0- 编码后的语音数据,1- 编码前的PCM原始数据

                GC.KeepAlive(VoiceData);
                GC.KeepAlive(lVoiceComHandle);

                if (lVoiceComHandle < 0)
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_StartVoiceCom_V30 failed, error code= " + iLastErr;
                    MessageBox.Show(str);
                    return;
                }
                else
                {
                    //uiButton1.FillColor = Color.FromArgb(255, 140, 222, 217);
                    //uiButton1.FillPressColor = Color.FromArgb(255, 140, 222, 217);
                    //uiButton1.FillSelectedColor = Color.FromArgb(255, 140, 222, 217);
                    //uiButton1.Text = "停止对讲";
                    uiButton1.BackgroundImage = Image.FromFile(path + "\\img\\分组 2.png");
                    m_bTalk = true;
                }
            }
            else
            {
                GC.KeepAlive(VoiceData);
                GC.KeepAlive(lVoiceComHandle);

                //停止语音对讲 Stop two-way talk
                if (!CHCNetSDK.NET_DVR_StopVoiceCom(lVoiceComHandle))
                {
                    iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                    str = "NET_DVR_StopVoiceCom failed, error code= " + iLastErr;
                    MessageBox.Show(str);
                    return;
                }
                else
                {
                    //uiButton1.FillColor = Color.FromArgb(255, 5, 28, 62);
                    //uiButton1.FillPressColor = Color.FromArgb(255, 5, 28, 62);
                    //uiButton1.FillSelectedColor = Color.FromArgb(255, 5, 28, 62);
                    //uiButton1.Text = "开始对讲";
                    uiButton1.BackgroundImage = Image.FromFile(path + "\\img\\确定 copy_1.png");
                    m_bTalk = false;
                }
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

回调函数

      public static void VoiceDataCallBack(int lVoiceComHandle, IntPtr pRecvDataBuffer, uint dwBufSize, byte byAudioFlag, System.IntPtr pUser)
        {
            byte[] sString = new byte[dwBufSize];
            Marshal.Copy(pRecvDataBuffer, sString, 0, (Int32)dwBufSize);
            
            if (byAudioFlag == 0)
            {
                //将缓冲区里的音频数据写入文件 save the data into a file
                string str = "PC采集音频文件.pcm";
                FileStream fs = new FileStream(str, FileMode.Create);
                int iLen = (int)dwBufSize;
                fs.Write(sString, 0, iLen);
                fs.Close();
            }
            if (byAudioFlag == 1)
            {
                //将缓冲区里的音频数据写入文件 save the data into a file
                string str = "设备音频文件.pcm";
                FileStream fs = new FileStream(str, FileMode.Create);
                int iLen = (int)dwBufSize;
                //MessageBox.Show("1");
                fs.Write(sString, 0, iLen);
                fs.Close();
            }
         

        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

云台控制

控制函数再mouse up和down中。保存就是保存当前设置位置到某一个预置点中。在点击
在这里插入图片描述

        private void UpPtz_MouseDown(object sender, MouseEventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                if (Form1.liveIndex)
                {
                    //带速度的云台控制操作(需先启动图象预览)
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed(Form1.m_lRealHandle, CHCNetSDK.TILT_UP, 0, (uint)uiComboBox1.SelectedIndex + 1);
                }
                else
                {
                    //带速度的云台控制操作(不用启动图象预览)。
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(Form1.m_lUserID, 1, CHCNetSDK.TILT_UP, 0, (uint)uiComboBox1.SelectedIndex + 1);
                }
            }
            else
            {
                MessageBox.Show("请先登录");
            }
        }

        private void UpPtz_MouseUp(object sender, MouseEventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                if (Form1.liveIndex)
                {
                    //带速度的云台控制操作(需先启动图象预览)
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed(Form1.m_lRealHandle, CHCNetSDK.TILT_UP, 1, (uint)uiComboBox1.SelectedIndex + 1);
                }
                else
                {
                    //带速度的云台控制操作(不用启动图象预览)。
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(Form1.m_lUserID, 1, CHCNetSDK.TILT_UP, 1, (uint)uiComboBox1.SelectedIndex + 1);
                }
            }
            else
            {
                MessageBox.Show("请先登录");
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
        private void DownPtz_MouseDown(object sender, MouseEventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                if (Form1.liveIndex)
                {
                    //带速度的云台控制操作(需先启动图象预览)
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed(Form1.m_lRealHandle, CHCNetSDK.TILT_DOWN, 0, (uint)uiComboBox1.SelectedIndex + 1);
                }
                else
                {
                    //带速度的云台控制操作(不用启动图象预览)。
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(Form1.m_lUserID, 1, CHCNetSDK.TILT_DOWN, 0, (uint)uiComboBox1.SelectedIndex + 1);
                }
            }
            else
            {
                MessageBox.Show("请先登录");
            }
        }

        private void DownPtz_MouseUp(object sender, MouseEventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                if (Form1.liveIndex)
                {
                    //带速度的云台控制操作(需先启动图象预览)
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed(Form1.m_lRealHandle, CHCNetSDK.TILT_DOWN, 1, (uint)uiComboBox1.SelectedIndex + 1);
                }
                else
                {
                    //带速度的云台控制操作(不用启动图象预览)。
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(Form1.m_lUserID, 1, CHCNetSDK.TILT_DOWN, 1, (uint)uiComboBox1.SelectedIndex + 1);
                }
            }
            else
            {
                //MessageBox.Show("请先登录");
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
        private void LeftPtz_MouseDown(object sender, MouseEventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                if (Form1.liveIndex)
                {
                    //带速度的云台控制操作(需先启动图象预览)
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed(Form1.m_lRealHandle, CHCNetSDK.PAN_LEFT, 0, (uint)uiComboBox1.SelectedIndex + 1);
                }
                else
                {
                    //带速度的云台控制操作(不用启动图象预览)。
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(Form1.m_lUserID, 1, CHCNetSDK.PAN_LEFT, 0, (uint)uiComboBox1.SelectedIndex + 1);
                }
            }
            else
            {
                MessageBox.Show("请先登录");
            }
        }

        private void LeftPtz_MouseUp(object sender, MouseEventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                if (Form1.liveIndex)
                {
                    //带速度的云台控制操作(需先启动图象预览)
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed(Form1.m_lRealHandle, CHCNetSDK.PAN_LEFT, 1, (uint)uiComboBox1.SelectedIndex + 1);
                }
                else
                {
                    //带速度的云台控制操作(不用启动图象预览)。
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(Form1.m_lUserID, 1, CHCNetSDK.PAN_LEFT, 1, (uint)uiComboBox1.SelectedIndex + 1);
                }
            }
            else
            {
                //MessageBox.Show("请先登录");
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
        private void RightPtz_MouseDown(object sender, MouseEventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                if (Form1.liveIndex)
                {
                    //带速度的云台控制操作(需先启动图象预览)
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed(Form1.m_lRealHandle, CHCNetSDK.PAN_RIGHT, 0, (uint)uiComboBox1.SelectedIndex + 1);
                }
                else
                {
                    //带速度的云台控制操作(不用启动图象预览)。
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(Form1.m_lUserID, 1, CHCNetSDK.PAN_RIGHT, 0, (uint)uiComboBox1.SelectedIndex + 1);
                }
            }
            else
            {
                MessageBox.Show("请先登录");
            }
        }

        private void RightPtz_MouseUp(object sender, MouseEventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                if (Form1.liveIndex)
                {
                    //带速度的云台控制操作(需先启动图象预览)
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed(Form1.m_lRealHandle, CHCNetSDK.PAN_RIGHT, 1, (uint)uiComboBox1.SelectedIndex + 1);
                }
                else
                {
                    //带速度的云台控制操作(不用启动图象预览)。
                    CHCNetSDK.NET_DVR_PTZControlWithSpeed_Other(Form1.m_lUserID, 1, CHCNetSDK.PAN_RIGHT, 1, (uint)uiComboBox1.SelectedIndex + 1);
                }
            }
            else
            {
                //MessageBox.Show("请先登录");
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

保存

        private uint iLastErr = 0;
        string str="";
        public static UInt32 PresetPoint = 2;
        private void uiButton1_Click(object sender, EventArgs e)
        {
            if (Form1.m_lUserID >= 0)
            {
                DialogResult dr;
                dr = MessageBox.Show("确认将当前点设置为预置点", "设置", MessageBoxButtons.YesNo,
                         MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
                if (dr == DialogResult.Yes)
                {

                    if (!CHCNetSDK.NET_DVR_PTZPreset_Other(Form1.m_lUserID, 1, CHCNetSDK.SET_PRESET, PresetPoint))
                    {
                        iLastErr = CHCNetSDK.NET_DVR_GetLastError();
                        str = "NET_DVR_PTZPreset_Other failed, error code= " + iLastErr;
                        MessageBox.Show(str);
                        return;
                    }
                    else
                    {
                        MessageBox.Show("设置成功");
                    }
                    return;
                }
                else return;
            }
            else
            {
                //MessageBox.Show("请先登录");
            }
        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

镜像

可实现上下左右中心的画面切换。

  • 直接在SDK里面搜索镜像,看到包含这个的结构体,和更改结构体的函数。
  • 首先通过NET_DVR_GetDVRConfig获取配置信息,在他传过来的结构体的基础上,进行镜像的修改
  • 一系列结构体的操作。首先申请一段指针内存,将传入的数据被指针指向,然后将指针转成结构体,再修改结构体的值,最后将结构体转换成指针,然后发送出去。参考
  • NET_DVR_SetDVRConfig将修改后的结构体发送出去
        //当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
        //如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
        public static   CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX VideoConf=new CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX();      
        private void uiButton6_Click_1(object sender, EventArgs e)
        {
            try
            {
                uint lpBytesReturned = 0;
                //申请指针内存
                IntPtr iptr = Marshal.AllocHGlobal(Marshal.SizeOf(VideoConf));
                //获取设备的配置信息。
                NET_DVR_GetDVRConfig(m_lUserID, 3368, 1, iptr, (uint)Marshal.SizeOf(VideoConf), ref lpBytesReturned);
                //将指针转换成结构体
                CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX entries = (CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX)Marshal.PtrToStructure(iptr, typeof(CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX));
                /* 镜像:0 off,1- leftright,2- updown,3-center */
                if (uiComboBox2.SelectedItem.ToString()=="上下")
                {
                    entries.byMirror =2;
                }
                else if (uiComboBox2.SelectedItem.ToString() == "左右")
                {
                    entries.byMirror = 1;
                }
                else if (uiComboBox2.SelectedItem.ToString() == "中心")
                {
                    entries.byMirror = 3;
                }
                else if (uiComboBox2.SelectedItem.ToString() == "关闭")
                {
                    entries.byMirror = 0;
                }
                Marshal.StructureToPtr(entries, iptr, true);
                NET_DVR_SetDVRConfig(m_lUserID, 3369, 1, iptr, (uint)Marshal.SizeOf(VideoConf));
            }
            catch (Exception)
            {
                throw;
            }

        }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

在这里插入图片描述

错误码

CHCNetSDK.NET_DVR_GetLastError();
  • 1

返回值为错误码。错误码主要分为网络通讯库、RTSP通讯库、软硬解库、语音对讲库等错误码,详见下表。他有两百多个 详细见 设备网络SDK使用手册
在这里插入图片描述
在这里插入图片描述

出现的问题

回调函数导致崩溃

反复点击语音按钮后出现奔溃,加一行代码就可以了,大致的原因是:c#把回调函数资源回收了,导致api收到事件的时候执行回调出错。

 GC.KeepAlive(VoiceData);
  GC.KeepAlive(lVoiceComHandle);//可能只需要其中的一句 我加了两句
  • 1
  • 2

请添加图片描述
解决方案详解
解决方案对口

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/887671
推荐阅读
相关标签
  

闽ICP备14008679号