前言
本章将服务器端几个非主要但常用的功能分享一下。
注意
本系列文章限于学习交流,注重过程,由于涉及公司,所以不提供源代码下载,非常抱歉!!但是请大家放心,核心、实现以及其他能够贴出来的代码我都会贴出来,并且争取尽所能的回答留言里的每一个问题,感谢大家关注,欢迎交流 :)
系列
1. C# 视频监控系列(1):准备
2. C# 视频监控系列(2):客户端——封装API
3. C# 视频监控系列(3):客户端——连接服务器
4. C# 视频监控系列(4):客户端——音频接收和抓图
5. C# 视频监控系列(5):客户端——给服务器端发送字符串和录像(数据捕获)
6. C# 视频监控系列(6):服务器端——封装API(上) [HikServer.dll]
7. C# 视频监控系列(7):服务器端——封装API(下) [DS40xxSDK.dll]
8. C# 视频监控系列(8):服务器端——预览和可被客户端连接
9. C# 视频监控系列(9):服务器端——数据捕获(抓图 + 录像)
10. C# 视频监控系列(10):服务器端——验证、设置画面质量、字幕叠加、板卡序列号
正文
一、验证
1.1 IP验证
VC++ Code:
OnInitDialog方法
MP4_ServerCheckIP(CheckIP);
CheckIP委托
int
CALLBACK CheckIP(DWORD nChannel,
char
*
nIP)
{
/*
CString ctemp;
ctemp.Format("%s",nIP);
if (ctemp == "192.0.0.215")
return -1;
*/
return
0
;
}
代码说明:
1. 自带的例子IP验证部分注释掉了,但是可以看得出返回-1表示错误,返回0表示验证通过,并且实际证明如果返回-1的话客户端是不出图像的。
C# Code:
///
<summary>
///
验证IP
///
</summary>
///
<param name="nChannel">
通道号
</param>
///
<param name="nIP">
ip地址
</param>
///
<returns></returns>
public
int
CheckIP(
int
nChannel,
string
nIP)
{
//
验证代码
return
0
;
}
代码说明:
1. 比较简单,填写自己的验证代码,正确返回0,不正确反正-1就可以了。
1.2 用户名密码验证
VC++ Code:
OnInitDialog方法
MP4_ServerCheckPassword(checkpassword);
CheckPassword委托
int
CALLBACK checkpassword(
char
*
username,WORD namelen,
char
*
password,WORD passlen)
{
/*
if ((username[0] == '1') && (username[1] == '2') && (username[2] == '3') && (password[0] == 'w'))
return 0;
else
return -1;
*/
return
0
;
}
C# Code:
///
<summary>
///
验证用户名密码
///
</summary>
///
<param name="username">
用户名
</param>
///
<param name="namelen">
用户名长度
</param>
///
<param name="password">
密码
</param>
///
<param name="passlen">
密码长度
</param>
///
<returns></returns>
public
int
CheckPassword(
string
username,
ushort
namelen,
string
password,
ushort
passlen)
{
//
验证代码
return
0
;
}
这部分和验证IP差不多,唯一需要注意的是把委托写成成员变量!!
二、设置画面采集质量
从VC++例子中Settings中可以看到这个设置:
VC++ Code:
方法OnSettings()
switch
(dlg.m_iEncodeType)
{
case
0
:
encodeType
=
ENC_4CIF_FORMAT;
break
;
case
1
:
encodeType
=
ENC_2CIF_FORMAT;
break
;
case
2
:
encodeType
=
ENC_DCIF_FORMAT;
break
;
case
3
:
encodeType
=
ENC_CIF_FORMAT;
break
;
case
4
:
encodeType
=
ENC_QCIF_FORMAT;
break
;
default
:
encodeType
=
ENC_CIF_FORMAT;
break
;
}
for
(i
=
0
; i
<
GetTotalDSPs(); i
++
)
{
if
(encodeType
!=
ENC_4CIF_FORMAT)
{
SetEncoderPictureFormat(ChannelHandle[i],encodeType);
}
else
if
((i
%
4
==
0
)
||
(i
%
4
==
1
))
{
SetEncoderPictureFormat(ChannelHandle[i],encodeType);
}
}
C# Code:
///
<summary>
///
设置当前所有摄头录制的画面质量
///
</summary>
///
<param name="ChannelHandle"></param>
///
<param name="t">
编码图像分辨率
</param>
public
static
void
SetCurrentEncoderPictureFormat(IntPtr[] ChannelHandle, PictureFormat_t t)
{
for
(
int
i
=
0
; i
<
ChannelHandle.Length; i
++
)
{
HikVisionSDK.SetEncoderPictureFormat(ChannelHandle[i], t);
}
}
代码说明:
1. 枚举PictureFormat_t说明:
PictureFormat_t.ENC_QCIF_FORMAT 低质量
PictureFormat_t.ENC_CIF_FORMAT 中质量
PictureFormat_t.ENC_DCIF_FORMAT 中高质量
PictureFormat_t.ENC_4CIF_FORMAT 高质量
2. 设置后画面效果能实时改变。
三、设置字幕叠加
一般用于显示公司LOGO和日期,下图黄色区域所示
VC ++ Code:
方法OnSettings()
USHORT Format1[
40
]
=
{
48
,
16
,
'
H
'
,
'
I
'
,
'
K
'
,
'
V
'
,
'
I
'
,
'
S
'
,
'
I
'
,
'
O
'
,
'
N
'
,
'
\0
'
};
USHORT Format2[
40
]
=
{
24
,
50
, _OSD_YEAR4,
'
-
'
,_OSD_MONTH2,
'
-
'
,_OSD_DAY,
'
-
'
, _OSD_HOUR24,
'
:
'
, _OSD_MINUTE,
'
:
'
, _OSD_SECOND,
'
\0
'
};
//
其他代码
for
(i
=
0
; i
<
GetTotalDSPs(); i
++
){
SetOsdDisplayMode(ChannelHandle[i],
255
, TRUE,
0
, Format1, Format2);
SetOsd(ChannelHandle[i], TRUE);
}
C# Code:
private
const
ushort
_OSD_BASE
=
0x9000
;
private
const
ushort
_OSD_YEAR4
=
_OSD_BASE
+
0
;
private
const
ushort
_OSD_YEAR2
=
_OSD_BASE
+
1
;
private
const
ushort
_OSD_MONTH3
=
_OSD_BASE
+
2
;
private
const
ushort
_OSD_MONTH2
=
_OSD_BASE
+
3
;
private
const
ushort
_OSD_DAY
=
_OSD_BASE
+
4
;
private
const
ushort
_OSD_WEEK3
=
_OSD_BASE
+
5
;
private
const
ushort
_OSD_CWEEK1
=
_OSD_BASE
+
6
;
private
const
ushort
_OSD_HOUR24
=
_OSD_BASE
+
7
;
private
const
ushort
_OSD_HOUR12
=
_OSD_BASE
+
8
;
private
const
ushort
_OSD_MINUTE
=
_OSD_BASE
+
9
;
private
const
ushort
_OSD_SECOND
=
_OSD_BASE
+
10
;
///
<summary>
///
设置Osd
///
</summary>
///
<param name="ChannelHandle"></param>
///
<param name="setValue"></param>
public
void
SetOsd(IntPtr[] ChannelHandle,
bool
setValue)
{
if
(setValue)
{
ushort
[] Format1
=
new
ushort
[]{
48
,
16
,
'
H
'
,
'
I
'
,
'
K
'
,
'
V
'
,
'
I
'
,
'
S
'
,
'
I
'
,
'
O
'
,
'
N
'
,
'
\0
'
};
ushort
[] Format2
=
new
ushort
[]{
24
,
50
, _OSD_YEAR4,
'
-
'
, _OSD_MONTH2,
'
-
'
, _OSD_DAY,
'
-
'
, _OSD_HOUR24,
'
:
'
, _OSD_MINUTE,
'
:
'
, _OSD_SECOND,
'
\0
'
};
for
(
int
i
=
0
; i
<
ChannelHandle.Length; i
++
)
{
HikVisionSDK.SetOsdDisplayMode(ChannelHandle[i],
255
,
true
,
0
, Format1, Format2);
HikVisionSDK.SetOsd(ChannelHandle[i],
true
);
}
}
else
{
for
(
int
i
=
0
; i
<
ChannelHandle.Length; i
++
)
{
HikVisionSDK.SetOsd(ChannelHandle[i],
false
);
}
}
}
代码说明:
1. 注意设置中文字符有问题,暂时没有解决。
2. 关于时间显示可以翻阅API文档,说明得很详细。
四、获取板卡序列号
VC++ Code: 这段代码并不在Net Server Demo项目里面,而是在System Demo(Src\SysDemoSource)项目里。
BoardList.cpp
char
str[
100
];
char
sn[
12
+
1
];
m_list.DeleteAllItems();
boardCount
=
GetBoardCount();
for
(UINT board
=
0
;board
<
boardCount;board
++
)
{
GetBoardDetail(board,
&
boardDetail);
for
(UINT i
=
0
;i
<
12
;i
++
)
sn[i]
=
boardDetail.sn[i]
+
0x30
;
sn[
12
]
=
0
;
sprintf(str,
"
Board:%2u Type:%s,SN:%s
"
,
board,boardType[boardDetail.type],sn);
C# Code:
///
<summary>
///
获取板卡序号
///
</summary>
///
<returns></returns>
public
static
string
GetBoardSN()
{
uint
boardCount
=
HikVisionSDK.GetBoardCount();
StringBuilder sn
=
new
StringBuilder();
for
(
uint
i
=
0
; i
<
boardCount; )
{
DS_BOARD_DETAIL boardDetail
=
new
DS_BOARD_DETAIL();
HikVisionSDK.GetBoardDetail(i,
ref
boardDetail);
for
(
int
j
=
0
; j
<
12
; j
++
)
{
sn.Append((
char
)(boardDetail.sn[j]
+
0x30
));
}
break
;
}
return
sn.ToString();
}
代码说明:
1. 注意结构体用ref;以及boardDetail.sn[j]的类型转换。
五、文章后期维护
5.1 2010-10-9 OSD显示汉字办法
来自博客园的另一朋友站在巨人的肩上,如下可显示汉字:
汉字"保"的机器内码是"B1A3H",将如下代码替换:
替换前:new ushort[]{ 48, 16, 'H', 'I', 'K', 'V', 'I', 'S', 'I', 'O', 'N', '\0' };
替换后:new ushort[]{ 48, 16, 0xB1A3, 'I', 'K', 'V', 'I', 'S', 'I', 'O', 'N', '\0' };
这样就能显示汉字了,这里再次感谢,也欢迎大家分享和交流!
结束
服务器端和客户端一样三篇文章,至此结束,接下来是播放器。感谢大家继续关注该系列文章!!