本文主要是介绍种一棵Android海康摄像机Demo的树,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
项目中有监控模块,准备使用海康的摄像机,方一运行所提供的Demo,就程序崩溃。
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.test.demo/com.test.demo.DemoActivity}: android.content.res.Resources$NotFoundException: Resource ID #0x7f020000
低版本图标资源在手机上找不到的原因。
解决办法:重新更换一张存在的图标,重新运行即可
本Demo完成实时预览,回放,查找SD卡中的历史录像文件,截图功能。
1.登陆设备
public static boolean loginDevice(String ip, int port, String name, String psd) {NET_DVR_DEVICEINFO_V30 netDvrDeviceInfoV30 = new NET_DVR_DEVICEINFO_V30();int loginId = HCNetSDK.getInstance().NET_DVR_Login_V30(ip, port,name, psd, netDvrDeviceInfoV30);//登陆失败if (loginId < 0) {return false;}ExceptionCallBack exceptionCbf = getExceptionCbf();if (!HCNetSDK.getInstance().NET_DVR_SetExceptionCallBack(exceptionCbf)) {return false;}return true;
}
2.实时预览:
public boolean startRealTimePlay() {NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();previewInfo.lChannel = mStartChan;previewInfo.dwStreamType = 0;previewInfo.bBlocked = 1;previewInfo.hHwnd = mSvPlayer.getHolder();
/* mPlayId = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(mILogID,previewInfo, null);*/mPlayId = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(0,previewInfo, null);if (mPlayId < 0) {return false;}return true;
}
3.回放:
public boolean backPlay(NET_DVR_TIME beginDate, NET_DVR_TIME endDate) {if (mPlayId >= 0) {return false;}NET_DVR_VOD_PARA struVod = new NET_DVR_VOD_PARA();struVod.struBeginTime = beginDate;struVod.struEndTime = endDate;struVod.byStreamType = 0;struVod.struIDInfo.dwChannel = mStartChan;struVod.hWnd = mSvPlayer.getHolder().getSurface();mPlaybackId = HCNetSDK.getInstance().NET_DVR_PlayBackByTime_V40(mILogID, struVod);if (mPlaybackId >= 0) {if (!HCNetSDK.getInstance().NET_DVR_PlayBackControl_V40(mPlaybackId, PlaybackControlCommand.NET_DVR_PLAYSTART, null, 0, null)) {return false;}return true;}return false;
}
如果需要实现进度条拖动回放进度功能,只需先停止回放再传入新的开始时间,结束时间不变再调用该方法就行。但是发现这种方式有的时候会出现问题,造成程序崩溃。sdk并没有提供相应的解决方法,使用海康ivms-4500APP拖动回放没有问题,实现方式不一样,ivms-4500会黑屏再回放,不知道是不是缓存了多个SurfaceView来回切换回放。
4.查找录像文件:
public static List<NET_DVR_FINDDATA_V30> findAllFile(NET_DVR_TIME beginDate, NET_DVR_TIME endDate){List<NET_DVR_FINDDATA_V30> monitorFileList = new ArrayList<>(10);NET_DVR_FILECOND netDvrFilecond = new NET_DVR_FILECOND();netDvrFilecond.lChannel = 1;netDvrFilecond.dwFileType = 0;netDvrFilecond.dwIsLocked = 0xff;netDvrFilecond.struStartTime = beginDate;netDvrFilecond.struStopTime = endDate;int findStatus = HCNetSDK.getInstance().NET_DVR_FindFile_V30(0, netDvrFilecond);while (true) {NET_DVR_FINDDATA_V30 file = new NET_DVR_FINDDATA_V30();try {//延时一点时间才能找到文件Thread.sleep(150);} catch (InterruptedException e) {e.printStackTrace();}HCNetSDK.getInstance().NET_DVR_FindNextFile_V30(findStatus, file);if (file.dwFileSize == 0) {break;} else {monitorFileList.add(file);}}HCNetSDK.getInstance().NET_DVR_FindClose_V30(findStatus);return monitorFileList;
}
5.截图:
public boolean generateCapture() {NET_DVR_JPEGPARA jpeg = new NET_DVR_JPEGPARA();INT_PTR a = new INT_PTR();byte[] buffer = new byte[1024 * 1024];// 设置图片的分辨率0-2,越小质量越高jpeg.wPicSize = 2;jpeg.wPicQuality = 2;if (HCNetSDK.getInstance().NET_DVR_CaptureJPEGPicture_NEW(mILogID, mChanNum, jpeg, buffer, 1024 * 1024, a) && saveCapture(buffer)) {return true;}return false;
}
备注:
1.目前测试登陆和播放都可以异步,其余应该也可以。
2.直接用SurfaceView即可,不需要用Demo所封装的。
3.如果需要全屏和小屏播放,只需要让Activity旋转就可以,可以在View中重写onConfigurationChanged处理切换时候的逻辑:
@Override
protected void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);//横屏if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {}else {}
}
4.Activity,onStop()时会销毁SurfaceView,需要在SurfaceView的surfaceCreated()方法中处理恢复播放:
@Override
public void surfaceCreated(SurfaceHolder holder) {//恢复播放
}
5.如果需要做成列表播放,只需要在RecyclerView的父View嵌套SurfaceView就行:
//RecyclerViewAdapter中item点击回调
@Override
public void onClick(View v) {if(onVideoClickListener != null){int[] point = new int[2];v.getLocationOnScreen(point);onVideoClickListener.onVideoClick(point);}
}public void onVideoClick(final int[] point) {if (mPlayer == null) {mPlayer = (Player) LayoutInflater.from(mContext).inflate(R.layout.player_min, mFlMonitor, false);mPlayer.setOnSurfaceCreateCallBack(this);mFlMonitor.addView(mPlayer);mPlayer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {@Overridepublic void onGlobalLayout() {i++;if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ){return;}alertPlayerPosition(point);if(i == 2) {mPlayer.getViewTreeObserver().removeOnGlobalLayoutListener(this);}}});}
}private void alertPlayerPosition(int[] point) {int[] rlPoint = new int[2];//标题栏和状态栏高度总和if (mTitleStatusBarHeight <= 0) {mFlMonitor.getLocationOnScreen(rlPoint);mTitleStatusBarHeight = rlPoint[1];}int playItemY = point[1];int measuredHeight = mPlayer.getMeasuredHeight();int top = playItemY - mTitleStatusBarHeight;int bottom = top + measuredHeight;mPlayer.layout(mPlayer.getLeft(), top, mPlayer.getRight(), bottom);
}
6.由于特殊原因,恕不能提供完整Demo,有什么问题可以在论坛问我就行。
这篇关于种一棵Android海康摄像机Demo的树的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!