首先需要说的是我遇到的问题大部分是因为监控设备更新换代产生的。我们最初的设备的同轴电缆的监控,之后因为业务需要改成了新款的网络监控。但是对于海康官方给出的开发文档中并没有这些改变相应造成的程序方面的变动,或者说是新功能的api在开发文档中并不能找到。(现在不知道又没有完善,但是我是去年1月份做的软件修改,当时是没有的)
这个功能是新款网络监控默认有的,而且在我们项目中的那款主机上是没法去除的。当时联系过海康客服(这时候需要吐槽一点为什么没有技术支持电话,因为邮件太慢了),客服是给了我两个解决方案:一个是在PC端登陆网络监控后台去修改配置,第二是在移动端代码做修改。
按照客服给出的第一种方法,尝试了很多次可以修改但是无法保存修改。之后多次联系客服确认这个也没法去修改掉移动侦测的,最终只能在移动端代码上做修改。在代码上修改是真的不容易,首先是查阅开发文档并没有提及,然后就联系客服(不得不吐槽下邮件实在太慢了)需求解决方案。当时客服提出了一个解决流程和相关的api调用,但是很坑的就是我弄了整整一天一直没有调用出客服给出的api,联系客服也换过最新的sdk和so文件。最后耗费了我两天的时候最终客服给出的结果就是她提供的流程和相关api搞错了是pc端开发用的。
最后按照客服给出的新的移动端流程和api调用,只给出了几个api名称然后让我自己去看开发文档。头疼的是开发文档上面找不到诶,联系客服又得转述到研发那边帮我咨询。最后辗转几次终于在自己的摸索和客服的配合下终于去除了移动侦测。说实话这个咨询周期太长了,至少耗费了两个礼拜。
如果在预览时去除移动侦测,需要在PlaySurfaceView里面做处理
NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();
previewInfo.lChannel = iChan;
previewInfo.dwStreamType = 1;
previewInfo.bBlocked = 1;
previewInfo.hHwnd = m_hHolder;
// HCNetSDK start preview
m_iPreviewHandle = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(iUserID,
previewInfo, null);
if (m_iPreviewHandle < 0) {
Log.e(TAG, "NET_DVR_RealPlay is failed!Err:"
+ HCNetSDK.getInstance().NET_DVR_GetLastError());
}
//海康JNA调用去除移动侦测
m_iPort = HCNetSDKJNAInstance.getInstance().NET_DVR_GetRealPlayerIndex(iUserID);
HCNetSDKJNAInstance.getInstance().NET_DVR_GetRealPlayerIndex(m_iPreviewHandle);
Player.getInstance().renderPrivateData(m_iPort,Player.PRIVATE_RENDER.RENDER_MD,0);
如果在回放里面去除移动侦测,同样需要在回放的调用方法里面做处理
NET_DVR_VOD_PARA vod_para_1 = new NET_DVR_VOD_PARA();
vod_para_1.struBeginTime = startTime;
vod_para_1.struEndTime = endTime;
vod_para_1.byStreamType = 0;
vod_para_1.struIDInfo.dwChannel = m_iStartChan;
vod_para_1.hWnd = null;
vod_para_1.hWnd = playView[0].getHolder().getSurface();
m_iPlaybackID_1 = HCNetSDK.getInstance().NET_DVR_PlayBackByTime_V40(m_iLogID, vod_para_1);
//海康JNA调用去除移动侦测
m_iPort = HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iLogID);
HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iPlaybackID_1);
Player.getInstance().renderPrivateData(m_iPort, Player.PRIVATE_RENDER.RENDER_MD, 0);
其实就是这么很简单的方法处理,但是技术客服对于sdk的不熟悉还是什么原因。
需要修改海康官方demo中的loginNormalDevice方法,做预判断
private int loginNormalDevice() {
// get instance
m_oNetDvrDeviceInfoV30 = new NET_DVR_DEVICEINFO_V30();
if (null == m_oNetDvrDeviceInfoV30) {
Log.e(TAG, "HKNetDvrDeviceInfoV30 new is failed!");
return -1;
}
// call NET_DVR_Login_v30 to login on, port 8000 as default
int iLogID = HCNetSDK.getInstance().NET_DVR_Login_V30(strIP, nPort,
strUser, strPsd, m_oNetDvrDeviceInfoV30);
if (iLogID < 0) {
Log.e(TAG, "NET_DVR_Login is failed!Err:"
+ HCNetSDK.getInstance().NET_DVR_GetLastError());
return -1;
}
if (m_oNetDvrDeviceInfoV30.byChanNum > 0) {
m_iStartChan = m_oNetDvrDeviceInfoV30.byStartChan;
m_iChanNum = m_oNetDvrDeviceInfoV30.byChanNum;
} else if (m_oNetDvrDeviceInfoV30.byIPChanNum > 0) {
m_iStartChan = m_oNetDvrDeviceInfoV30.byStartDChan;
m_iChanNum = m_oNetDvrDeviceInfoV30.byIPChanNum + m_oNetDvrDeviceInfoV30.byHighDChanNum * 256;
}
NET_DVR_IPPARACFG_V40 struIP = new NET_DVR_IPPARACFG_V40();
HCNetSDK.getInstance().NET_DVR_GetDVRConfig(m_iLogID,
HCNetSDK.NET_DVR_GET_IPPARACFG_V40, m_iStartChan, struIP);
for (int i = 0; i < m_iChanNum; i++) {
if (struIP.struIPDevInfo[i].byEnable == 0) {
//i启用
switch (i) {
case 1:
m_enableChan_1 = false;
L("m_chan_1 enable");
break;
case 2:
m_enableChan_2 = false;
L("m_chan_2 enable");
break;
case 3:
m_enableChan_3 = false;
L("m_chan_3 enable");
break;
case 4:
m_enableChan_4 = false;
L("m_chan_4 enable");
break;
default:
break;
}
}
}
if (m_iChanNum > 1) {
ChangeSingleSurFace(false);
} else {
ChangeSingleSurFace(true);
}
Log.i(TAG, "NET_DVR_Login is Successful!");
return iLogID;
}
这个也是一个坑,因为在官方给出的demo中界面上是有这个按钮的,但是点击并没有任何反应。在研究源码无果的情况下联系客服,客服说这个回放demo中是没有做处理的,需要我们自己按照开发文档去自己开发。
public void playBack() {
try {
if (m_iLogID < 0) {
Log.e(TAG, "please login on a device first");
return;
}
if (m_iPlaybackID_1 < 0 || m_iPlaybackID_2 < 0
|| m_iPlaybackID_3 < 0 || m_iPlaybackID_4 < 0) {
if (m_iPlayID >= 0) {
Log.i(TAG, "Please stop preview first");
return;
}
NET_DVR_TIME startTime = new NET_DVR_TIME();
startTime.dwYear = bYear;
startTime.dwMonth = bMonth;
startTime.dwDay = bDay;
startTime.dwHour = bHour;
startTime.dwMinute = bMinute;
startTime.dwSecond = bSecond;
NET_DVR_TIME endTime = new NET_DVR_TIME();
endTime.dwYear = aYear;
endTime.dwMonth = aMonth;
endTime.dwDay = aDay;
endTime.dwHour = aHour;
endTime.dwMinute = aMinute;
endTime.dwSecond = aSecond;
if (m_enableChan_1) {
NET_DVR_VOD_PARA vod_para_1 = new NET_DVR_VOD_PARA();
vod_para_1.struBeginTime = startTime;
vod_para_1.struEndTime = endTime;
vod_para_1.byStreamType = 0;
vod_para_1.struIDInfo.dwChannel = m_iStartChan;
vod_para_1.hWnd = null;
vod_para_1.hWnd = playView[0].getHolder().getSurface();
m_iPlaybackID_1 = HCNetSDK.getInstance().NET_DVR_PlayBackByTime_V40(m_iLogID, vod_para_1);
//海康JNA调用去除移动侦测
m_iPort = HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iLogID);
HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iPlaybackID_1);
Player.getInstance().renderPrivateData(m_iPort, Player.PRIVATE_RENDER.RENDER_MD, 0);
}
if (m_enableChan_2) {
NET_DVR_VOD_PARA vod_para_2 = new NET_DVR_VOD_PARA();
vod_para_2.struBeginTime = startTime;
vod_para_2.struEndTime = endTime;
vod_para_2.byStreamType = 0;
vod_para_2.struIDInfo.dwChannel = m_iStartChan + 1;
vod_para_2.hWnd = null;
vod_para_2.hWnd = playView[1].getHolder().getSurface();
m_iPlaybackID_2 = HCNetSDK.getInstance().NET_DVR_PlayBackByTime_V40(m_iLogID, vod_para_2);
//海康JNA调用去除移动侦测
m_iPort = HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iLogID);
HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iPlaybackID_2);
Player.getInstance().renderPrivateData(m_iPort, Player.PRIVATE_RENDER.RENDER_MD, 0);
}
if (m_enableChan_3) {
NET_DVR_VOD_PARA vod_para_3 = new NET_DVR_VOD_PARA();
vod_para_3.struBeginTime = startTime;
vod_para_3.struEndTime = endTime;
vod_para_3.byStreamType = 0;
vod_para_3.struIDInfo.dwChannel = m_iStartChan + 2;
vod_para_3.hWnd = null;
vod_para_3.hWnd = playView[2].getHolder().getSurface();
m_iPlaybackID_3 = HCNetSDK.getInstance().NET_DVR_PlayBackByTime_V40(m_iLogID, vod_para_3);
//海康JNA调用去除移动侦测
m_iPort = HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iLogID);
HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iPlaybackID_3);
Player.getInstance().renderPrivateData(m_iPort, Player.PRIVATE_RENDER.RENDER_MD, 0);
}
if (m_enableChan_4) {
NET_DVR_VOD_PARA vod_para_4 = new NET_DVR_VOD_PARA();
vod_para_4.struBeginTime = startTime;
vod_para_4.struEndTime = endTime;
vod_para_4.byStreamType = 0;
vod_para_4.struIDInfo.dwChannel = m_iStartChan + 3;
vod_para_4.hWnd = null;
vod_para_4.hWnd = playView[3].getHolder().getSurface();
m_iPlaybackID_4 = HCNetSDK.getInstance().NET_DVR_PlayBackByTime_V40(m_iLogID, vod_para_4);
//海康JNA调用去除移动侦测
m_iPort = HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iLogID);
HCNetSDKJNAInstance.getInstance().NET_DVR_GetPlayBackPlayerIndex(m_iPlaybackID_4);
Player.getInstance().renderPrivateData(m_iPort, Player.PRIVATE_RENDER.RENDER_MD, 0);
}
if (m_iPlaybackID_1 >= 0 || m_iPlaybackID_2 >= 0
|| m_iPlaybackID_3 >= 0 || m_iPlaybackID_4 >= 0) {
NET_DVR_PLAYBACK_INFO struPlaybackInfo = null;
if (m_enableChan_1) {
if (!HCNetSDK
.getInstance()
.NET_DVR_PlayBackControl_V40(
m_iPlaybackID_1,
PlaybackControlCommand.NET_DVR_PLAYSTART,
null, 0, struPlaybackInfo)) {
Log.e(TAG, "net sdk playback start failed!");
return;
}
}
if (m_enableChan_2) {
if (!HCNetSDK
.getInstance()
.NET_DVR_PlayBackControl_V40(
m_iPlaybackID_2,
PlaybackControlCommand.NET_DVR_PLAYSTART,
null, 0, struPlaybackInfo)) {
Log.e(TAG, "net sdk playback start failed!");
return;
}
}
if (m_enableChan_3) {
if (!HCNetSDK
.getInstance()
.NET_DVR_PlayBackControl_V40(
m_iPlaybackID_3,
PlaybackControlCommand.NET_DVR_PLAYSTART,
null, 0, struPlaybackInfo)) {
Log.e(TAG, "net sdk playback start failed!");
return;
}
}
if (m_enableChan_4) {
if (!HCNetSDK
.getInstance()
.NET_DVR_PlayBackControl_V40(
m_iPlaybackID_4,
PlaybackControlCommand.NET_DVR_PLAYSTART,
null, 0, struPlaybackInfo)) {
Log.e(TAG, "net sdk playback start failed!");
return;
}
}
m_oPlaybackBtn.setText("停止回放");
} else {
Log.i(TAG,
"NET_DVR_PlayBackByName failed, error code: "
+ HCNetSDK.getInstance()
.NET_DVR_GetLastError());
}
} else {
if (m_enableChan_1){
if (!HCNetSDK.getInstance().NET_DVR_StopPlayBack(
m_iPlaybackID_1)) {
Log.e(TAG, "1 net sdk stop playback failed");
}
}
if (m_enableChan_2){
if (!HCNetSDK.getInstance().NET_DVR_StopPlayBack(
m_iPlaybackID_2)) {
Log.e(TAG, "2 net sdk stop playback failed");
}
}
if (m_enableChan_3){
if (!HCNetSDK.getInstance().NET_DVR_StopPlayBack(
m_iPlaybackID_3)) {
Log.e(TAG, "3 net sdk stop playback failed");
}
}
if (m_enableChan_4){
if (!HCNetSDK.getInstance().NET_DVR_StopPlayBack(
m_iPlaybackID_4)) {
Log.e(TAG, "4 net sdk stop playback failed");
}
}
// player stop play
m_oPlaybackBtn.setText("实时预览");
m_iPlaybackID_1 = -1;
m_iPlaybackID_2 = -1;
m_iPlaybackID_3 = -1;
m_iPlaybackID_4 = -1;
}
} catch (Exception err) {
Log.e(TAG, "error: " + err.toString());
}
}
这里需要提醒各位一下,因为我是做的四个通道的监控,所以如果不做通道判断的话,一旦有一个通道是不可用的情况时,进行四个通道的回放是会报错的。所以务必先处理通道的可用性判断,在进行相应通道的回放。
这个问题不知道是不是个别情况,反正我是遇到了。首先遇到这种情况先确定导入的so文件库是否正确,如果是放置在jnilibs里面,需要做资源的引入。
sourceSets.main {
jniLibs.srcDirs = ['src/main/libs']
}
如果资源文件引入正确,然后再确认是否将官方demo中的jna文件正确的导入到了自己的项目中
我一开始是直接引入到自己的项目目录中去的,但是没法调用到里面的方法。所以我改成了demo中的路径,可以成功调用到里面的方法。不知道是官方故意这样处理还是说有什么其他原因。当然我下面使用的指静脉识别器也是同样处理才能完成api调用。
最后附上我的同轴电缆版本的demo地址:https://download.csdn.net/download/d38825/10123402
另外这个是网络监控改版的demo地址:https://download.csdn.net/download/d38825/10388596