随笔-377  评论-2091  文章-0  trackbacks-6

C# 视频监控系列(1):准备

 

 

前言

     偶尔的机会接触视频监控,一开始的也是无头苍蝇,买书,跑了几趟中关村买设备,找朋友帮忙接线,测试摄像头,总算是把海康SDK开发包里面的示例跑起来了!接下来又在源码网站、用Google疯狂的找代码,不是VC++的就是Delphi的源码(本人Delphi不会,VC++能看懂点点-_-#),最后算是找到了一个C#版开发的客户端文章,结果运行出错!跑到海康官方网站问也没人鸟,怒了!!冷静下来看自带的VC++客户端代码,看得出他也是调用的标准接口,只是使用VC++来调罢了,所以想干脆直接把自带VC++客户端的代码直接翻译成对应的C# WinForm程序,然后找了一篇C#封装的海康DVR客户端SDK 的文章,1个小时候后的结果证明我是对的——行了!!从我的WinForm程序中收到并显示了摄像头采集的视频数据!!接下来和大家一起分享和探讨我视频监控系统开发系列......

 

正文

     一、采购单

          1.     海康威视音视频采集卡

                    H.264视音频压缩卡,四路,直接去他公司拿700,可以打他网站客服联系下。

                     图1     图2

               2.     枪式红外摄像机

                    索尼的头,带电源200。用手捂着摄像头,从缝里面看要是能看见红色亮的那就表示通了。

                    图3  

          3.     拾音器

                    价格有18、38、50的,不带电源,不带转换头,线是裸的,所以自己得再买一电源,接头让他帮忙做或者回来直接焊接在音频口上。

                    图4

          4.     线、转接头

                    红线是接视频,白线是接音频,这是4路的接线,每个接头上面标了几通道。采集卡插到主板上之后用这个接出来,摄像机和拾音器都接到这个上面来。

                    图5

     二、下载

          1.     SDK开发包

               http://www.hikvision.com/uploadfile/4000HC_SDK_4.3.rar

     三、安装

          1.     硬件

               1.1     关机,把视频采集卡插到PCI插槽上

               1.2     接线,接电源线、把摄像机和拾音器都接到采集卡接出来的线上(图4),注意区分音频线和视频线以及路数。

          2.     软件          

               可直接运行DS-4000HC、HCS、HC+、HF、HS、MD Driver and SDK and Demo Install 4.3\install.exe,也可以按以下分开安装:

               2.1     安装驱动

                    DS-4000HC、HCS、HC+、HF、HS、MD Driver and SDK and Demo Install 4.3\Driver\Driver Install.exe

               2.2     安装SDK and Demo

                    DS-4000HC、HCS、HC+、HF、HS、MD Driver and SDK and Demo Install 4.3\SDK and Demo\setup.exe

     四、运行

          1.     运行服务器端:Bin\Net Server Demo.exe。如果一切正常,你现在就已经能够看到视频画面了,恭喜你!!你已经成功达到本文的目的!!如果没有,请重点检查线路接线

          2.     运行客户端:Bin\Net Client Demo(Soft Decdoe).exe,输入IP address 下面文本框输入本机IP,然后点击最左边的start按钮应该就可以看到画面了。

 

注意问题

     画面出不来,可能原因:

     1.     线过长,接头连接接触不良。

     2.     摄像头电源不通。

     3.     端口被占用了,服务器端和客户端默认开通端口是5050和6050.

     4.     据我的经验(- - 没有看到文档里有这说明),机器需要有独立显卡,否则即使服务器端能够访问,也不显示图像,但是客户端访问不受限制,仍然能看到画面,因为数据还是采集到了的。

 

结束

     过程是艰辛的,请大家一定要想尽一切办法,无助和烦恼的时候请冷静下来想想,收获离你不远: )

 

posted on 2009-02-18 08:33 农民伯伯 阅读(12945) 评论(27) 编辑 收藏

评论:
#1楼 2009-02-18 09:32 | 过江      
lz,可以把你写的代码分享下么?
 回复 引用 查看   
#2楼[楼主] 2009-02-18 10:31 | 农民伯伯      
--引用--------------------------------------------------
过江: lz,可以把你写的代码分享下么?
--------------------------------------------------------
请关注本系列文章,需要注意的是不提供源代码程序(- - # 涉及公司),但是我会贴主要实现的代码,并回答评论里面提到的问题,已保证能够根据文章写出例子: )

下一篇文章这周内会贴出来,感谢关注!!

 回复 引用 查看   
#3楼 2009-02-18 11:20 | 有所为,有所不为      
94
 回复 引用 查看   
#4楼 2009-03-25 11:46 | 地主[未注册用户]
好东东,比官方的还详细!多谢
 回复 引用   
#5楼 2009-04-07 09:38 | 渝雨愚[未注册用户]
好东西,谢谢你,这样的好文章多些.
 回复 引用   
#6楼 2009-04-07 14:54 | 逍遥海盗船      
这个系列好。
 回复 引用 查看   
#7楼 2009-08-29 17:34 | glgsy      
@农民伯伯
我看你的文章,做了个程序,成功了。
但我把panel控件改为4个,用以显示4个通道时,双击变大单个通道视频预览遇到了问题,panel控件大小改变了但,视频预览的窗口没有跟着变化,还是原来的大小。请问这是什么原因啊?

 回复 引用 查看   
#8楼[楼主] 2009-08-29 18:51 | 农民伯伯      
@glgsy
你在切换panel大小的时候把视频预览关闭下重新开一下看看

 回复 引用 查看   
#9楼 2009-12-26 16:02 | 285369675[未注册用户]
可以告诉我您QQ么,有的我看不懂,想向你请教一下不知道可以不
 回复 引用   
#10楼[楼主] 2009-12-26 16:21 | 农民伯伯      
@285369675
QQ: 36408253 加我时说下 视频的朋友 就行 :)

 回复 引用 查看   
#11楼 2010-01-11 09:04 | hyruur      
还不错,可惜没源码共享。
 回复 引用 查看   
#12楼 2010-01-11 09:05 | hyruur      
这篇文章很不错,正需要这方面的源码。
http://shop60194070.taobao.com

 回复 引用 查看   
#13楼 2010-05-04 10:18 | xuanfeng      
真是受益啦,正需要,谢谢啦
 回复 引用 查看   
#14楼 2010-05-25 11:39 | 小伟地方      
正需要,谢谢啦

 回复 引用 查看   
#15楼 2010-12-20 19:05 | badnewfish      
关于透明通道委托申明,根据本人测试得出,透明通道传输委托函数应该申明如下:
public delegate void SerialDataCallBack(int lSerialHandle, byte[] pRecvDataBuffer, uint dwBufSize, uint dwUser);
《C#封装的海康DVR客户端SDK》一文中将pRecvDataBuffer申明为string了,希望网友们注意。好像好多本该申明为byte[]类型的都整成string类型了。
我之前做过一些C++DLL转C#的研究,详情请看http://www.cnblogs.com/badnewfish/archive/2009/11/10/1599648.html

 回复 引用 查看   
#16楼[楼主] 2010-12-20 20:03 | 农民伯伯      
@badnewfish
感谢你的指正,这就更新 :)

 回复 引用 查看   
#17楼 2010-12-21 11:30 | badnewfish      
修正一下:
昨天透明通道的问题,byte[]还是不行的,只能得到第一个字节里面的值,值也是正确的。
终极解决方案,还是参照您的大作《C# 视频监控系列(9):服务器端——数据捕获(抓图 + 录像)》

终极的申明方式:
public delegate void SerialDataCallBack(int lSerialHandle, IntPtr pRecvDataBuffer, int dwBufSize, uint dwUser);

 回复 引用 查看   
#18楼 2010-12-21 11:31 | badnewfish      
在调研端获视频服务器发来的数据如下:
void SerialDataCallBack(int LSerialHandle, IntPtr DataBuf, int Length, uint dwUser)
{

//byte[] buffer = System.Text.Encoding..GetBytes(pRecvDataBuffer.ToString());
byte[] FileHeader = new byte[Length];
Marshal.Copy(DataBuf, FileHeader, 0, Length);}

 回复 引用 查看   
#19楼[楼主] 2010-12-21 15:58 | 农民伯伯      
@badnewfish
已经更正过了,不知道是否愿意分享DVR方面的开发经验,以补充DVR后续的文章,愿意的话加我QQ:36408253 :)

 回复 引用 查看   
#20楼 2011-01-08 16:33 | badnewfish      
@农民伯伯
可以哦!
我现在在做DVR和DVR的对讲调度,但是遇到了很大的问题,应该也是数据类型的问题,令我非常恼火。
以下是海康技术给的邮件:
设备采集的音频数据类型是PCM格式的,发送音频数据的缓冲中,存放的必须是编码以后的音频数据,首先采集到PCM数据,然后使用NET_DVR_EncodeG722Frame进行编码,经过编码以后的数据发给设备,设备才能进行播放。
1)初始化音频编码,调用接口NET_DVR_InitG722Encoder;
2)G722音频编码,调用接口NET_DVR_EncodeG722Frame,该接口的参数有一定的要求,详见接口说明;
3)当结束所有的编码过程需要调用NET_DVR_ReleaseG722Encoder接口释放编码音频资源。经过第二步的编码操作,我们可以每次得到固定大小的且经过编码后的数据,调用NET_DVR_VoiceComSendData接口发送这些数据给设备。等所有的转发操作完成后,调用NET_DVR_StopVoiceCom接口结束与设备的语音转发连接。

 回复 引用 查看   
#21楼 2011-01-08 16:39 | badnewfish      
这是我的方法
static void VoiceDataCallBack(int lVoiceComHandle, IntPtr pRecvDataBuffer, int dwBufSize, byte byAudioFlag, uint dwUser)
{
if (byAudioFlag == 1)
{
byte[] GetBuffer = new byte[dwBufSize];
Marshal.Copy(pRecvDataBuffer, GetBuffer, 0, dwBufSize);
byte[] OutBuffer = new byte[80];
if (lVoiceComHandle == ClientList[ClientA].LoginID)
{
IntPtr ptr = HCNetSDK.NET_DVR_InitG722Encoder();
HCNetSDK.NET_DVR_EncodeG722Frame(ptr, GetBuffer, OutBuffer);
HCNetSDK.NET_DVR_ReleaseG722Encoder(ptr);

HCNetSDK.NET_DVR_VoiceComSendData(ClientList[ClientB].LoginID, OutBuffer, 80);
}
else
{
IntPtr ptr = HCNetSDK.NET_DVR_InitG722Encoder();
HCNetSDK.NET_DVR_EncodeG722Frame(ptr, GetBuffer, OutBuffer);
HCNetSDK.NET_DVR_ReleaseG722Encoder(ptr);
HCNetSDK.NET_DVR_VoiceComSendData(ClientList[ClientA].LoginID, OutBuffer, 80);
}
}
}

 回复 引用 查看   
#22楼 2011-01-08 16:42 | badnewfish      
这是转发语音数据的函数申明,我怀疑是这里出了问题,到底char *pSendBuf 该转换成什么类型,愿高手解答:
[DllImport("HCNetSDK.dll")]
public static extern int NET_DVR_StartVoiceCom_MR(int lUserID, VoiceDataCallBack fVoiceDataCallBack, uint dwUser);
/// <summary>
/// 11.1.4 转发语音数据
/// 将客户端获取的数据转发给某台DVR,发送编码以后的音频数据(详见音频编解码)
/// NET_DVR_API BOOL __stdcall NET_DVR_VoiceComSendData(LONG lVoiceComHandle, char *pSendBuf, DWORD dwBufSize);
/// </summary>
/// <param name="lVoiceComHandle"></param>
/// <param name="pSendBuf"></param>
/// <param name="dwBufSize"></param>
/// <returns></returns>
[DllImport("HCNetSDK.dll")]
public static extern bool NET_DVR_VoiceComSendData(int lVoiceComHandle, byte[] pSendBuf, uint dwBufSize);

 回复 引用 查看   
#23楼 2011-01-08 19:13 | badnewfish      
问题解决了,原来是自己传参数传错了,应该传开启转发的函数的返回句柄,结果传成loginID了,晕倒,太低级的错误了;
还有DVR给上来的就是编码后的G.722数据,并不是海康技术所说了还需要编码,向下传输之间发生G.722的数据就可以了。
下是开启对讲的代码
public void StartVoiceCom_MR(int ASn, int BSn)
{
int low = 0, high = ClientList.Count, middle;
while (low <= high)
{
middle = (low + high) / 2;
if (ASn == ClientList[middle].SN)
{
//具体操作
ClientA = middle;
break;
}
if (ASn < ClientList[middle].SN)
{
high = middle - 1;
}
else
{
low = middle + 1;
}
}
low = 0;
high = ClientList.Count;
middle = 0;
while (low <= high)
{
middle = (low + high) / 2;
if (BSn == ClientList[middle].SN)
{
//具体操作
ClientB = middle;
break;
}
if (BSn < ClientList[middle].SN)
{
high = middle - 1;
}
else
{
low = middle + 1;
}
}
ClientList[ClientA].LVoiceComHandle = HCNetSDK.NET_DVR_StartVoiceCom_MR(ClientList[ClientA].LoginID, VC, 0);
ClientList[ClientB].LVoiceComHandle = HCNetSDK.NET_DVR_StartVoiceCom_MR(ClientList[ClientB].LoginID, VC, 0);
}
对讲回调:
static void VoiceDataCallBack(int lVoiceComHandle, IntPtr pRecvDataBuffer, int dwBufSize, byte byAudioFlag, uint dwUser)
{
if (byAudioFlag == 1)
{
byte[] GetBufferTemp = new byte[dwBufSize];
Marshal.Copy(pRecvDataBuffer, GetBufferTemp, 0, dwBufSize);
byte[] OutBuffer = new byte[80];
if (lVoiceComHandle == ClientList[ClientA].LoginID)
{
HCNetSDK.NET_DVR_VoiceComSendData(ClientList[ClientB].LVoiceComHandle, GetBufferTemp, 80);
}
else
{
HCNetSDK.NET_DVR_VoiceComSendData(ClientList[ClientA].LVoiceComHandle, GetBufferTemp, 80);
}
}
}

 回复 引用 查看   
#24楼[楼主] 2011-01-08 20:41 | 农民伯伯      
@badnewfish
谢谢你与大家分享 :)

 回复 引用 查看   
#25楼 2011-08-29 10:27 | Ni_Yang      
楼主。。我正在做海康的回放功能。在是在查找海康的录像文件的时候出错了。用的是HCNet_DVR_FindFile()这个方法。得到了通道好跟开始时间跟结束时间。但是在类型的时候说格式错误。因为如果按照全部查询的话。是用0xff来代替,一专程uint就报错了。 能看下你是怎么做的吗?
 回复 引用 查看   
#26楼[楼主] 2011-08-29 10:32 | 农民伯伯      
@Ni_Yang
我主要做的是板卡方面,DVR还没做到你说的这部分。

 回复 引用 查看   
#27楼 2011-08-29 10:34 | Ni_Yang      
哦。 这东西研究了几天了。 纠结呀。
 回复 引用 查看   
发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 1387448 DtGjW9lE1KM=
新浪微博分享Android中文Wiki
新浪微博分享Android翻译组官方网址
新浪微博分享Android中文翻译组官方微博
昵称:农民伯伯
园龄:4年5个月
荣誉:推荐博客
粉丝:860
关注:5

搜索

 
 

常用链接

随笔分类(396)

相册

积分与排名

  • 积分 - 642293
  • 排名 - 74

阅读排行榜

推荐排行榜