海康8800实时视频Android客户端集成总结

在接触海康之前有接触过大华视频的集成,萤石视频的集成,现在海康8800的视频是第一次集成,其中遇到了一个坑还是值得说一下的(个人认为还是很坑的)。
下载地址:海康8800所需jar 和so文件
Demo地址:海康视频AndroidDemo

海康8800的视频集成步骤如下:


1、导入jar和so文件 (如果自己没有的话,文章开头有下载链接)

在build.gradle 中配置如下代码:

repositories { flatDir { dirs 'libs' } }

2、在Application中注册,代码如下:

   OkHttpUtils.init(this);
        MCRSDK.init();
        RtspClient.initLib();
        MCRSDK.setPrint(1, null);
    }
  1. 你要有视频服务器的IP地址和端口,还需要登录视频平台的用户名和密码,这里我就不贴出公司的账号了,不然吃不了兜着走了:)。
    4.根据3 的IP和端口获取分支
 /*
  * 获取分支线
  */
    private void getFetchLine() {
        new Thread() {
            @Override
            public void run() {
                super.run();
                List<LineInfo> lineInfoList = new ArrayList<>();
                boolean ret = VMSNetSDK.getInstance().getLineList(SERVER_URL, lineInfoList);
                if (ret) {
                    Message message = new Message();
                    message.what = AppConfig.Login.GET_LINE_SUCCESS;
                    message.obj = lineInfoList;
                    handler.sendMessage(message);
                } else {
                    handler.sendEmptyMessage(AppConfig.Login.GET_LINE_FAILED);
                }
            }
        }.start();
    }

获取分之,需要在子线程中获取, 声明一个LineInfo 集合对象,用来存放获取到的分之,通过如下代码获取分之VMSNetSDK.getInstance().getLineList(SERVER_URL, lineInfoList); 该方法返回值是一个boolean类型,获取到分之返回true否则返回false, getLineList有两个参数,第一个是服务器地址,格式如下http://xxx.xxx.xxx.xxx:端口,第二个参数是获取到分支的集合。
z这里我用handler 处理几种状态,代码如下 代码2

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case AppConfig.Login.GET_LINE_SUCCESS://分支获取成功
                    List<LineInfo> list = (List<LineInfo>) msg.obj;
                    if (list.size() > 0) {
                        login(list.get(0)); //登录
                    }
                    break;
                case AppConfig.Login.GET_LINE_FAILED:
                    ToastUtils.showShort(getActivity(), "分支获取失败");
                    break;
                case AppConfig.Login.LOGIN_SUCCESS:
                     ToastUtils.showShort(getActivity(), "登录成功");
                    requestResource();//获取资源
                    break;
                case AppConfig.Login.LOGIN_FAILED:
                    ToastUtils.showShort(getActivity(), "视频登录失败");
                    break;
                case MsgIds.GET_SUB_F_R_SUC:
                    break;
            }
        }
    };

============================   ==============================================
//以下是状态类型
  /**
     * 登录逻辑相关常量
     */
    public interface Login {
        /**
         * 获取线路成功
         */
        int GET_LINE_SUCCESS = 0;
        /**
         * 获取线路失败
         */
        int GET_LINE_FAILED = 1;
        /**
         * 显示进度
         */
        int SHOW_LOGIN_PROGRESS = 2;
        /**
         * 取消进度提示
         */
        int CANCEL_LOGIN_PROGRESS = 3;
        /**
         * 登录成功
         */
        int LOGIN_SUCCESS = 4;
        /**
         * 登录失败
         */
        int LOGIN_FAILED = 5;
        /**
         * 获取线路中
         */
        int GET_LINE_IN_PROCESS = 6;
    }

4、分支获取成功后就可以登录了,代码如下:

  /**
     * 登录视频服务器
     *
     * @param lineInfo
     */
    private void login(final LineInfo lineInfo) {
        new Thread() {
            @Override
            public void run() {
                super.run();
                String macAddress = CommonUtils.getMac(getActivity());
                boolean ret = VMSNetSDK.getInstance().login(AppConfig.SERVER_URL, AppConfig.USERNAME, AppConfig.PASSWORD, lineInfo.lineID, macAddress, servInfo);

                if (servInfo != null) {
                    // 打印出登录时返回的信息
                    Log.i(TAG, "login ret : " + ret);
                        Log.i(TAG, "login response info[" + "sessionID:" + servInfo.sessionID + ",userID:"
                            + servInfo.userID + ",magInfo:" + servInfo.magInfo + ",picServerInfo:"
                            + servInfo.picServerInfo + ",ptzProxyInfo:" + servInfo.ptzProxyInfo + ",userCapability:"
                            + servInfo.userCapability + ",vmsList:" + servInfo.vmsList + ",vtduInfo:"
                            + servInfo.vtduInfo + ",webAppList:" + servInfo.webAppList + "]");
                }
                if (ret) {
                    TempData.getIns().setLoginData(servInfo);
                    handler.sendEmptyMessage(AppConfig.Login.LOGIN_SUCCESS);
                } else {
                    handler.sendEmptyMessage(AppConfig.Login.LOGIN_FAILED);
                }
            }
        }.start();
    }

登录时需要传入获取到的分支实体,因为当前我就一个分支,所以我取出来直接穿了一个LineInfo 对象。登录方法如下:VMSNetSDK.getInstance().login(AppConfig.SERVER_URL, AppConfig.USERNAME, AppConfig.PASSWORD, lineInfo.lineID, macAddress, servInfo)在这个方法里面一共有6个参数,第一个是服务器地址,第二个是登录视频平台的用户名,第三个是登录视频平台的密码,第四个是分支ID,第五个是手机的mac地址, 第六个是该方法登录成功后获取到的视频服务器信息,保存在servInfo里面。该方法返回一个boolean类型,true登录成功,false 登录失败。
同样我也是用handler 处理的几种状态,代码在上面的Login 接口中。
5、请求视频资源树

 public interface Resource {
        /**
         * 控制中心
         */
        int TYPE_CTRL_UNIT = 1;
        /**
         * 区域
         */
        int TYPE_REGION = 2;
        /**
         * 未知
         */
        int TYPE_UNKNOWN = 3;
    }

ResourceControl rc;
 private int pResType = AppConfig.Resource.TYPE_UNKNOWN;//获取资源
  private int pId = 0;
   /**
     * 请求资源
     */
    private void requestResource() {
        rc = new ResourceControl();
        rc.setCallback(this);
        rc.setCallback(new MsgCallback() {
            @Override
            public void onMsg(int msgId, Object data) {
                Message msg = new Message();
                msg.what = msgId;
                msg.obj = data;
                rcHandler.sendMessage(msg);
            }
        });

        new Thread(new Runnable() {
            @Override
            public void run() {
                rc.reqResList(pResType, pId);
            }
        }).start();


这段代码的意思是获取资源树  请求结果会反会到rc 注册的监听里面,然后通过handler具体处理,如下是整个rchandler

  Handler rcHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                // 获取控制中心列表成功
                case MsgIds.GET_C_F_NONE_SUC:
                    List<ControlUnitInfo> controlUnitInfoList = (List<ControlUnitInfo>) msg.obj;
                    if (controlUnitInfoList.size() > 0) {
                        pId = controlUnitInfoList.get(0).controlUnitID;
                        pResType = AppConfig.Resource.TYPE_CTRL_UNIT;
                        requestResource();
                    }
                    break;
                // 从控制中心获取下级资源列表成功
                case MsgIds.GET_SUB_F_C_SUC:
                    List<RegionInfo> regionInfoList = (List<RegionInfo>) msg.obj;
                    if (regionInfoList.size() > 0) {
                        pId = regionInfoList.get(0).controlUnitID;
                        pResType = AppConfig.Resource.TYPE_REGION;
                        requestResource();
                    }
                    break;
                // 从区域获取下级列表成功
                case MsgIds.GET_SUB_F_R_SUC:
                    cameraInfos = (List<CameraInfo>) msg.obj;
                    addrAdapter = new BaseAddrAdapter<>(getActivity(), cameraInfos);
                    spinner.setAdapter(addrAdapter);
                    break;
                // 获取控制中心列表失败
                case MsgIds.GET_C_F_NONE_FAIL:
                    // 调用getControlUnitList失败
                case MsgIds.GET_CU_F_CU_FAIL:
                    // 调用getRegionListFromCtrlUnit失败
                case MsgIds.GET_R_F_C_FAIL:
                    // 调用getCameraListFromCtrlUnit失败
                case MsgIds.GET_C_F_C_FAIL:
                    // 从控制中心获取下级资源列表成失败
                case MsgIds.GET_SUB_F_C_FAIL:
                    // 调用getRegionListFromRegion失败
                case MsgIds.GET_R_F_R_FAIL:
                    // 调用getCameraListFromRegion失败
                case MsgIds.GET_C_F_R_FAIL:
                    // 从区域获取下级列表失败
                case MsgIds.GET_SUB_F_R_FAILED:
                    ToastUtils.showShort(getActivity(), "获取资源列表失败");
                default:
                    break;
            }
        }
    };

z这里可以看到 GET_C_F_NONE_SUC,GET_SUB_F_C_SUC,这里可以看到 GET_C_F_NONE_SUC 获取控制中心和获取控制中心下级资源列表成功后,并没有终止,而是再次调用requestResource方法,知道获取到区域下级列表才会停止。

这里我把集合数据放到了一个spinner 里面展示, 通过选择Spinner的Item 播放选中的视频,代码如下:

    /**
     * 初始化视频
     */
    private void initData() {
        mRealPlayURL = new RealPlayURL();
        mLiveControl = new LiveControl();
        mLiveControl.setLiveCallBack(this);
        mDeviceID = cameraInfo.deviceID;
        mVmsNetSDK = VMSNetSDK.getInstance();
        DeviceInfo deviceInfo = new DeviceInfo();
        if (mVmsNetSDK == null) {
            CLog.e(TAG, "mVmsNetSDK is null");
            return;
        }
        boolean ret = mVmsNetSDK.getDeviceInfo(SERVER_URL,
                TempData.getIns().getLoginData().sessionID, mDeviceID, deviceInfo);
        if (ret) {
            name = deviceInfo.userName;
            password = deviceInfo.password;
        }
        startPlayVideo();
    }



 /**
     * 启动播放 void
     *
     * @since V1.0
     */
    private void startPlayVideo() {
        progressBar.setVisibility(View.VISIBLE);
        new Thread() {
            @Override
            public void run() {
                super.run();
                mLiveControl.setLiveParams(getPlayUrl(2), mName, mPassword);
                if (mLiveControl.LIVE_PLAY == mLiveControl.getLiveState()) {
                    mLiveControl.stop();
                }

                if (mLiveControl.LIVE_INIT == mLiveControl.getLiveState()) {
                    mLiveControl.startLive(surfaceView);
                }
            }
        }.start();
    }


    /**
     * 该方法是获取播放地址的,当mStreamType=2时,获取的是MAG,当mStreamType =1时获取的子码流,当mStreamType = 0时获取的是主码流
     * 由于该方法中部分参数是监控点的属性,所以需要先获取监控点信息,具体获取监控点信息的方法见resourceActivity。
     *
     * @param streamType 2、表示MAG取流方式;1、表示子码流取流方式;0、表示主码流取流方式;
     * @return String 播放地址 :2、表示返回的是MAG的播放地址;1、表示返回的是子码流的播放地址;0、表示返回的是主码流的播放地址。
     * @since V1.0
     */
    private String getPlayUrl(int streamType) {
        String url = "";
        // 登录平台地址
        String mAddress = SERVER_URL;
        // 登录返回的sessiond
        String mSessionID = TempData.getIns().getLoginData().sessionID;
        if (cameraInfo == null) {
            LogUtils.i(TAG, "getPlayUrl():: cameraInfo is null");
            return url;
        }
        if (streamType == 2) {
            // TODO 原有代码streamType传0
            VMSNetSDK.getInstance().getRealPlayURL(mAddress, mSessionID, cameraInfo.cameraID, streamType, mRealPlayURL);
            if (null == mRealPlayURL) {
                LogUtils.i(TAG, "getPlayUrl():: mRealPlayURL is null");
                return "";
            }
            // MAG地址
            url = mRealPlayURL.url2;
            LogUtils.i(TAG, "getPlayUrl():: url is " + url);
        } else {
            VMSNetSDK.getInstance().getRealPlayURL(mAddress, mSessionID, cameraInfo.cameraID, streamType, mRealPlayURL);
            if (null == mRealPlayURL) {
                LogUtils.i(TAG, "getPlayUrl():: mRealPlayURL is null");
                return "";
            }
            // mRealPlayURL.url1 是主码流还是子码流取决于 streamType,见上面注释
            url = mRealPlayURL.url1;
            LogUtils.i(TAG, "getPlayUrl():: url is " + url);
        }
        DeviceInfo deviceInfo = new DeviceInfo();
        boolean ret = VMSNetSDK.getInstance().getDeviceInfo(mAddress, mSessionID, cameraInfo.deviceID, deviceInfo);
        if (ret && deviceInfo != null) {
            mName = deviceInfo.userName;
            mPassword = deviceInfo.password;
        } else {
            LogUtils.i(TAG, "getPlayUrl():: deviceInfo is error");
        }
        return url;
    }

播放视频的代码没啥好讲的了, 注释写的比较清楚了,
啊如下是停止播放视频的代码:

    /**
     * 停止播放 void
     *
     * @since V1.0
     */
    private void stopLive() {
        if (null != mLiveControl) {
            mLiveControl.stop();
            hidePlayBtn(true);
        }
    }

到此,视频就集成完了, 如果顺利 播放就可以看到视频了。

海康威视 iVMS-8700 平台 SDK 简介 密级级别: 外部公开 杭州海康威视系统技术有限公司 1. 目标..................................................................................................................................................3 2. 内容..................................................................................................................................................3 3. 构成..................................................................................................................................................3 3.1 HTTP-OpenAPI...................................................................................................................................4 3.2 OCX-OpenApi ....................................................................................................................................4 3.3 DLL-OpenApi .....................................................................................................................................5 3.4 PMS-iOS-SDK.....................................................................................................................................5 3.5 PMS-Android-SDK .............................................................................................................................5 3.6 PMS-JS-SDK .......................................................................................................................................6 3.7 MCU-iOS-SDK ....................................................................................................................................6 3.8 MCU-Android-SDK.............................................................................................................................6 3.9 BLEOpenDoor-iOS-SDK ..................................................................................................................7 3.10 BLEOpenDoor-Android-SDK ............................................................................................................7 3.11 VideoIntercom-iOS-SDK ..................................................................................................................8 3.12 VideoIntercom-Android-SDK...........................................................................................................8 4. 典型对接方案 ..................................................................................................................................9 4.1 平台级对接典型方案 ......................................................................................................................9 4.2 模块级对接典型方案 ....................................................................................................................10 5. SDK 组件与业务关系 .....................................................................................................................10 6. SDK 组件对接适配关系..................................................................................................................11 7. SDK 组件属性.................................................................................................................................12 8. SDK 组件 Demo..............................................................................................................................12
### 回答1: SDL (Simple DirectMedia Layer) 是一个跨平台的多媒体库,用于处理音频、视频、图形以及用户输入。而海康SDK是指海康威视提供的用于监控设备的软件开发工具包。 使用SDL 2.0播放海康SDK提供的视频流,需要以下几个步骤: 1. 初始化SDL:在程序开始时,调用SDL_Init()函数进行SDL的初始化。 2. 创建窗口:调用SDL_CreateWindow()函数创建一个窗口用于显示视频流。 3. 创建渲染器:调用SDL_CreateRenderer()函数创建一个渲染器,将其与窗口关联。 4. 打开视频流:使用海康SDK提供的接口打开视频流,并获取视频流的相关信息。 5. 创建纹理:调用SDL_CreateTexture()函数创建一个纹理对象,用于将视频流数据渲染到窗口上。 6. 渲染视频帧:通过不断循环,在每一帧中,将视频流数据解码为图像帧,并将其更新到纹理对象中。 7. 渲染纹理到窗口:调用SDL_RenderCopy()函数将纹理渲染到窗口上。 8. 刷新窗口:调用SDL_RenderPresent()函数将窗口上的渲染结果显示出来。 9. 释放资源:在程序结束时,调用SDL_DestroyTexture、SDL_DestroyRenderer和SDL_DestroyWindow函数释放已创建的资源。 通过以上步骤,可以将海康SDK提供的视频流使用SDL 2.0库进行播放。当然,为了实现更加复杂的功能,可能还需要使用到其他的SDL函数和海康SDK的接口,具体根据实际需求来选择使用。 ### 回答2: SDL(Simple DirectMedia Layer)是一个跨平台的开源多媒体库,它提供了音频、视频、图形和事件处理等功能,并且非常易于使用。海康SDK(Software Development Kit)则是海康威视的开发工具包,提供了与海康设备进行通信和交互的功能。下面是使用SDL 2.0和海康SDK播放视频流的简要步骤。 1. 配置SDL环境:在SDL官方网站上下载并安装最新版本的SDL 2.0库,然后在项目中引用SDL的头文件和库文件。 2. 初始化SDL:在程序中调用SDL_Init()函数初始化SDL库,并检查是否成功初始化。 3. 创建窗口和渲染器:使用SDL_CreateWindow()函数创建一个窗口对象,并使用SDL_CreateRenderer()函数创建一个渲染器对象。 4. 初始化海康SDK:在程序中调用海康SDK提供的初始化函数,确保海康设备和SDK的连接正常。 5. 打开视频流:使用海康SDK提供的函数打开视频流,并获取视频流的句柄。 6. 播放视频流:使用SDL提供的函数循环从视频流中读取数据,并使用SDL_RenderPresent()函数将数据渲染到窗口上显示。 7. 释放资源:在程序结束前,调用SDL_DestroyRenderer()、SDL_DestroyWindow()、SDL_Quit()等函数释放创建的SDL相关资源,并调用海康SDK提供的函数关闭视频流连接。 需要注意的是,在具体的代码实现中,还需要处理SDL事件、设置渲染器的尺寸和位置、配置海康设备的IP地址和登录信息等额外的步骤。 综上所述,使用SDL 2.0和海康SDK播放视频流的过程包括配置SDL环境、初始化SDL、创建窗口和渲染器、初始化海康SDK、打开视频流、播放视频流、释放资源等步骤。这样我们就可以通过SDL来实现简单地播放海康设备的视频流。 ### 回答3: SDL(Simple DirectMedia Layer)是一款开源跨平台的多媒体库,可用于软件开发中处理音频、图形、视频等多媒体元素。而海康SDK则是海康威视公司提供的一套用于实现视频监控系统的开发工具包。 要使用SDL2.0播放海康SDK提供的视频流,首先需要导入SDL2.0相关的开发库和头文件,并进行相应的配置。然后,可以通过与海康SDK进行通信,获取视频流数据,并使用SDL2.0进行解码和播放。 具体步骤如下: 1. 导入SDL2.0开发库和头文件至项目中。 2. 进行SDL2.0的初始化操作,包括初始化视频子系统、创建窗口和渲染器等。 3. 通过海康SDK的接口获取视频流数据,并将数据传递给SDL2.0进行解码和渲染。 4. 在主循环中,使用SDL2.0提供的函数进行视频的播放和显示。 5. 在程序结束时,进行资源的释放,包括停止视频播放、销毁窗口和渲染器,最后关闭SDL2.0。 需要注意的是,具体的代码实现可能因开发环境、操作系统和海康SDK版本的不同而有所差异。在实际开发中,可以参考SDL2.0和海康SDK的官方文档和示例代码,以了解更详细的操作步骤和调用方法。 总之,通过整合SDL2.0和海康SDK,可以方便地实现对海康视频流的播放。这样的应用可在视频监控系统、安防领域等多个领域中发挥重要作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值