种一棵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() {
            @Override
            public 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,有什么问题可以在论坛问我就行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值