海康威视视频监控demo源码+库⽂件
⼀个朋友做监控,⽤的海康威视的设备,海康威视本⾝⾃⼰有Android客户端,但朋友想开发⼀款⾃⼰的软件,配合硬件⼀起销售,还可以进⾏定制化开发,所以应朋友之请,就研究了下海康威视的相关SDK开发。
研究后发现,要实现上述功能,需要⽤到两个SDK:
1、海康威视android ⽹络库
2、海康威视android 播放库
问题马上来了,海康威视的官⽹只有android 播放库下载,没有android ⽹络库下载,通过400电话联系了海康威视的技术⼈员,对⽅说请和当时销售联系索取,联系了销售,说了半天对⽅也没听懂我们要什么,这可能就是做技术的和做市场的不同。
没有办法,只能在⽹上,⽹海茫茫,个sdk可真是费了⽜劲,终于在“程序员”联合开发⽹上到⼀
个“hone_Monitor_SDK(android)”,介绍说:“海康威视android⼿机监控SDK,对想做android视频监控程序的朋友作⽤会很⼤,欢迎下载”,着实兴奋了⼀下,注册、下载,⼀⽓呵成,下载下来后因为没有sdk
使⽤说明,⼜从海康威视官⽹下载了liunx版的⽹络库sdk使⽤说明(想着应该⼤同⼩异,可以参考),研究后,捣⿎出⼀个demo,运⾏后,连接服务器、登录设备都没有问题,可以看到监控点数量、设备序列号,但死活⽆法播放,⼀调⽤实时预览,就返回失败7,使⽤说明上解释说是⽹络故障,再怎么折腾也⽆济于事。sdk
于是⼜开始研究海康威视⾃⼰的android客户端(IVMS-4500),看着⼈家这个连接⼀点问题没的,怀疑可能我下的sdk版本太⽼(那个上⾯介绍⽀持android1.5,应该是2011年以前的)或者调⽤⽅法不对,想着⼲脆把他这个客户端反编译了看看,如果没有混淆,可以好好研究研究,即使混淆了,有些地⽅也能看个⼤概,说⼲就⼲,反编译后发现竟然没有混淆,哈哈,他⾃⾝sdk的调⽤看个⼀清⼆楚,仔细研究后,发现我的写法没有问题,基本可以肯定我下的sdk版本太⽼,可能现在的设备都不⽀持了,突发奇想:他这个反编译的结果是个jar包,如果我直接引⽤的话,不是他调⽤的功能、函数、类、接⼝什么的我都可以⽤么,呵呵,ok,直接导⼊我的demo⼯程,把我之前的sdk删掉,运⾏,哈哈,⼤功告成!
好了,讲了这么多,步⼊正题,先介绍下为什麽要⽤两个sdk,海康威视android ⽹络库是⽤来与设备建⽴远程连接,⾳、视频解码,进⾏实时预览、回放等等功能的,但是它所得到的仅仅是⼆进制的⾳、视频数据⽽已,要真正的显⽰到⼿机界⾯上,还需要海康威视android 播放库sdk得⽀持,通过播放库sdk,才可以将视频显⽰到SurfaceView之上。也就是下⾯的结构:
//上代码
//sdk定义
private Player myPlayer = null;
private HCNetSDK videoCtr;
//******************************************************************
//sdk初始化
videoCtr = new HCNetSDK(); //实例化⽹络库SDK
videoCtr.NET_DVR_Init(); //初始化⽹络库SDK
//******************************************************************
连接服务器,登录,实时预览代码⽰例:
videoHolder = Holder(); //获取视频显⽰窗⼝(SurfaceView对象)的Holder
myPlayer = Instance(); //实例话播放库对象
playPort = Port(); //获取播放端⼝
///关于播放库SDK的使⽤海康威视官⽹有详细说明
// 登录服务器
NET_DVR_DEVICEINFO_V30 deviceInfo = new NET_DVR_DEVICEINFO_V30();
int userid = videoCtr.NET_DVR_Login_V30(cameraInfo.serverip,
cameraInfo.serverport, cameraInfo.username, cameraInfo.userpwd,
deviceInfo);
System.out.println("下⾯是设备信息************************");
System.out.println("通道开始=" + deviceInfo.byStartChan);
System.out.println("通道个数=" + deviceInfo.byChanNum);
System.out.println("设备类型=" + deviceInfo.byDVRType);
System.out.println("ip通道个数=" + deviceInfo.byIPChanNum);
byte[] snByte = deviceInfo.sSerialNumber;
String sNo = "";
for (int i = 0; i < snByte.length; i++) {
sNo += String.valueOf(snByte[i]);
}
System.out.println("设备序列号=" + sNo);
System.out.println("************************");
NET_DVR_CLIENTINFO clientInfo = new NET_DVR_CLIENTINFO();
clientInfo.lChannel = 1; //需要打开的通道(可以参考通道开始序号和通道个数,⼀般从1开始)
clientInfo.lLinkMode = 0x80000000; //⼦码流(保证图像连续性),tcp连接⽅式,如果要保证图像清晰度,可选⽤主码流(值全改为0:0x00000000)clientInfo.sMultiCastIP = null;
int playFlag = videoCtr.NET_DVR_RealPlay_V30(userid, clientInfo,
mRealDataCallback, false); //mRealDataCallback即为数据回传回掉函数
//******************************************************************
数据回传回掉函数定义代码:
注意,函数中的videoHolder变量即为要显⽰视频的SurfaceView的Holder,通过SurfaceView对象的getHolder()⽅法获得
private RealPlayCallBack mRealDataCallback = new RealPlayCallBack() {
@Override
public void fRealDataCallBack(int arg0, int dataType,
byte[] paramArrayOfByte, int byteLen) {
// TODO Auto-generated method stub
// 回掉函数
switch (dataType) {
case 1: // 头数据
if (myPlayer.openStream(playPort, paramArrayOfByte, byteLen,
1024 * 1024)) {
if (myPlayer.setStreamOpenMode(playPort, 1)) {
if (myPlayer.play(playPort, videoHolder)) {
playFlag = true;
} else {
playError(3);
}
} else {
playError(2);
}
} else {
playError(1);
}
break;
case 2:
case 4:
if (playFlag
&& myPlayer.inputData(playPort, paramArrayOfByte,
byteLen)) {
playFlag = true;
} else {
playError(4);
playFlag = false;
}
}
}
};
另外要注意的是调⽤顺序:
1、sdk实例话及初始化
2、在要显⽰视频的SurfaceView对象创建完成后(即surfaceCreated()⽅法被触发)再连接服务器,进⾏实时预览,否则在实时预览时可能会出现SurfaceView尚未完全加载成功,导致调调数据显⽰异常。
3、关于SurfaceView对象的使⽤,可以参考的资料很多,此处不再说明。
4、demo源码直接传上:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论