C# 外接(网口)双摄像头视频获取
【注意事项】 ------------------------------------ 1. 更新设备网络SDK时,SDK开发包【库文件】里的HCNetSDK.dll、HCCore.dll、PlayCtrl.dll、SuperRender.dll、AudioRender.dll、HCNetSDKCom文件夹、ssleay32.dll、libeay32.dll、hlog.dll、hpr.dll、zlib1.dll、log4cxx.properties等文件均要加载到程序里面,【HCNetSDKCom文件夹】(包含里面的功能组件dll库文件)需要和HCNetSDK.dll、HCCore.dll一起加载,放在同一个目录下,且HCNetSDKCom文件夹名不能修改。
2. 如果自行开发软件不能正常实现相应功能,而且程序没有指定加载的dll库路径,请在程序运行的情况下尝试删除HCNetSDK.dll。如果可以删除,说明程序可能调用到系统盘Windows->System32目录下的dll文件,建议删除或者更新该目录下的相关dll文件;如果不能删除,dll文件右键选择属性确认SDK库版本。
3. 如按上述步骤操作后还是不能实现相应功能,请根据NET_DVR_GetLastError返回的错误号判断原因。
4.适用型号:DS-2CD2D15DWD 2.8MM,DS-2CD6424FWD-20 3.7MM,DS-2CD6425FWD-20 2.8MM B
5.dll和sdk可以上海康官网下载:https://www.hikvision.com/cn/download_61.html
Form1.cs:
using System;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
init();
}
public IntPtr PictureDev1Cam { get { return pictureBox1.Handle; } }
public IntPtr PictureDev2Cam { get { return pictureBox2.Handle; } }
IntPtr Cam1Handle = IntPtr.Zero;
IntPtr Cam2Handle = IntPtr.Zero;
Cam Camera1 = new Cam();
Cam Camera2 = new Cam();
static private string Cam1IP = "192.168.1.64";
static private string Cam2IP = "192.168.1.61";
void init()
{
Cam1Handle = PictureDev1Cam;
Cam2Handle = PictureDev2Cam;
}
private void ConnectCamera(int whitch)
{
string userName = "admin";
string password = "a123456.";
int PortCamera = 8000;
if (whitch == 1)
{
labelCamera1Status.Text = "摄像头连接中...";
Task.Run(() =>
{
if (!Camera1.ConnectCamera(Cam1IP, PortCamera, userName, password))
{
this.Invoke((Action)delegate { labelCamera1Status.Text = "摄像头连接失败"; });
}
else
{
this.Invoke((Action)delegate { labelCamera1Status.Text = ""; });
Camera1.Preview(Cam1Handle);
Camera1.AdjustMirrorPara(1);
Cam1ReconnectTimer.Stop();
}
});
}
else
{
labelCamera2Status.Text = "摄像头连接中...";
Task.Run(() =>
{
if (!Camera2.ConnectCamera(Cam2IP, PortCamera, userName, password))
{
this.Invoke((Action)delegate { labelCamera2Status.Text = "摄像头连接失败"; });
}
else
{
this.Invoke((Action)delegate { labelCamera2Status.Text = ""; });
Camera2.Preview(Cam2Handle);
Camera2.AdjustMirrorPara(1);
Cam2ReconnectTimer.Stop();
}
});
}
}
private void Cam1ReconnectTimer_Tick(object sender, EventArgs e)
{
ConnectCamera(1);
}
private void Cam2ReconnectTimer_Tick(object sender, EventArgs e)
{
ConnectCamera(2);
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
cam:
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace WindowsFormsApp1
{
class Cam
{
private bool initSDK = false;
private uint lastErr = 0;
private string debugMessage = "";
private bool err = false;
private Int32 userID = -1;
public bool Isconnected { get; private set; }
UInt32 dwReturn = 0;
Int32 nSize = 0;
IntPtr ptrPicCfg;
private CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX camPara = new CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX();
private CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
private Int32 realPlayHandle = -1;
public bool ConnectCamera(string deviceIP, int port, string userName, string password)
{
initSDK = CHCNetSDK.NET_DVR_Init();
if (initSDK == false)
{
lastErr = CHCNetSDK.NET_DVR_GetLastError();
debugMessage = "初始化过程失败, 错误码:" + lastErr;
err = true;
return false;
}
else
{
CHCNetSDK.NET_DVR_SetLogToFile(3, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "SdkLog\"), true);
}
CHCNetSDK.NET_DVR_DEVICEINFO_V30 DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V30();
userID = CHCNetSDK.NET_DVR_Login_V30(deviceIP, port, userName, password, ref DeviceInfo);
if (userID < 0)
{
lastErr = CHCNetSDK.NET_DVR_GetLastError();
debugMessage = "注册失败, 错误码:" + lastErr;
err = true;
return false;
}
Isconnected = true;
return true;
}
public void AdjustMirrorPara(byte type)
{
dwReturn = 0;
nSize = Marshal.SizeOf(camPara);
ptrPicCfg = Marshal.AllocHGlobal(nSize);
Marshal.StructureToPtr(camPara, ptrPicCfg, false);
if (CHCNetSDK.NET_DVR_GetDVRConfig(userID, 3368, DeviceInfo.byStartChan, ptrPicCfg, (uint)nSize, ref dwReturn))
{
camPara = (CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX)Marshal.PtrToStructure(ptrPicCfg, typeof(CHCNetSDK.NET_DVR_CAMERAPARAMCFG_EX));
Marshal.FreeHGlobal(ptrPicCfg);
camPara.byMirror = type;
ptrPicCfg = Marshal.AllocHGlobal(nSize);
Marshal.StructureToPtr(camPara, ptrPicCfg, false);
if (!CHCNetSDK.NET_DVR_SetDVRConfig(userID, 3369, DeviceInfo.byStartChan, ptrPicCfg, (uint)nSize))
{
lastErr = CHCNetSDK.NET_DVR_GetLastError();
debugMessage = "设置镜像关闭失败, 错误码:" + lastErr;
err = true;
}
}
else
{
lastErr = CHCNetSDK.NET_DVR_GetLastError();
debugMessage = "获取参数失败, 错误码:" + lastErr;
err = true;
}
Marshal.FreeHGlobal(ptrPicCfg);
}
public void Preview(IntPtr handle)
{
CHCNetSDK.NET_DVR_PREVIEWINFO previewInfo = new CHCNetSDK.NET_DVR_PREVIEWINFO();
previewInfo.hPlayWnd = handle;//预览窗口
previewInfo.lChannel = 1;//(int)DeviceInfo.byStartChan;//预览的设备通道
previewInfo.dwStreamType = 0;//码流类型:0-主码流,1-子码流,2-码流3,3-码流4,以此类推
previewInfo.dwLinkMode = 0;//连接方式:0- TCP方式,1- UDP方式,2- 多播方式,3- RTP方式,4-RTP/RTSP,5-RSTP/HTTP
previewInfo.bBlocked = true; //0- 非阻塞取流,1- 阻塞取流
previewInfo.dwDisplayBufNum = 0; //播放库播放缓冲区最大缓冲帧数
//CHCNetSDK.REALDATACALLBACK RealData = new CHCNetSDK.REALDATACALLBACK(RealDataCallBack);//预览实时流回调函数
IntPtr pUser = new IntPtr();//用户数据
//打开预览 Start live view
realPlayHandle = CHCNetSDK.NET_DVR_RealPlay_V40(userID, ref previewInfo, null/*RealData*/, pUser);
if (realPlayHandle < 0)
{
lastErr = CHCNetSDK.NET_DVR_GetLastError();
debugMessage = "预览失败, 错误码:" + lastErr; //预览失败,输出错误号
err = true;
//MessageBox.Show(str);
return;
}
}
}
}
CHCNetSDK.cs
这个太长,需要的可以上我的github下载,省略,我的账号zyr365
工程文件
bin目录
定时器:
运行结果:
- WCF技术剖析之三十一:WCF事务编程[上篇]
- 学习SpringMVC——你们要的REST风格的CRUD来了
- 并发中的同步--WCF并发体系的同步机制实现
- WCF 技术剖析之三十三:你是否了解WCF事务框架体系内部的工作机制?[下篇]
- 学习SpringMVC——从HelloWorld开始
- 小程序年底重磅更新,小游戏上线,最强入口也来了!
- 学习SpringMVC——如何获取请求参数
- 谈谈关于MVP模式中V-P交互问题
- 学习Spring——两个你熟悉的不能再熟悉的场景使用
- 学习Spring——依赖注入
- 机会真的多吗?
- 浅析Hadoop大数据分析与应用
- WCF技术剖析之三十三:你是否了解WCF事务框架体系内部的工作机制?[上篇]
- Java豆瓣电影爬虫——小爬虫成长记(附源码)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 快速上手Spring-Data-Redis
- Lua 5.1 参考手册
- 图文详解k8s自动化持续集成之GitLab CI/CD
- Harbor v2.0 镜像回收那些事
- redis实战第十四篇 redis cluster ask重定向
- Go命令官方指南【原译】
- 详解:如何监控小程序异常及处理错误?
- redis实战第十三篇 jedis连接redis cluster
- 哈工大李治军操作系统课程实验环境搭建
- 我用 OpenGL 实现了那些年流行的相机滤镜
- 使用minikube安装kubernetes和dashboard
- FFmpeg + OpenGLES 实现视频解码播放和视频滤镜
- 行为型设计模式:模板模式
- 容器中的隔离与限制:namespace和cgroups
- 行为型设计模式:策略模式