对接海康综合安防管理平台经验总结

前言:因业务需要对接海康威视的综合安防管理平台获得下属所管理的摄像头,根据摄像头code获得监控视频流信息

1、详情可以浏览海康开放平台,在官网上有对应的接入指南以及开放的API接口【前提是本地已部署了海康视频流媒体服务器】
2、通过海康开放平台我们看到相关的对接指南,进行开发前准备。如下图所示:

在这里插入图片描述

3、AK/SK可以要求甲方提供,如果是驻场开发可以在当前的局域网下通过运管中心的登录名/密码登陆该平台,通过下面的索引步骤来获得 AK/SK。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4、获得到 AK/SK后,通过参考开放的API文档,找到项目所需的对用接口,本文所用到的接口主要为:
5、相应开发代码
  • 引入海康依赖
        <!--海康依赖-->
        <dependency>
            <groupId>com.hikvision.ga</groupId>
            <artifactId>artemis-http-client</artifactId>
            <version>1.1.3</version>
        </dependency>
  • 对应接口的测试代码
import com.hikvision.artemis.sdk.ArtemisHttpUtil;
import net.sf.json.JSONObject;

import com.hikvision.artemis.sdk.config.ArtemisConfig;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Orange
 * @version 1.0
 * @Description:调用海康接口获得监控视频流
 * @date 2020/11/16 14:44
 */
public class HkTest {

    private static final Logger logger = LoggerFactory.getLogger(HkTest.class);

    static {
        ArtemisConfig.host = "10.*.1.99:443"; // artemis网关服务器ip端口
        ArtemisConfig.appKey = "25411867";  // 秘钥appkey
        ArtemisConfig.appSecret = "*************";// 秘钥appSecret
    }

    /**
     *设置OpenAPI接口的上下文
     */
    private static final String ARTEMIS_PATH = "/artemis";


    /*
     * @Description: 分页获取区域信息
     * @author: Orange
     * @Param: /api/resource/v1/regions/root
     * @Return: java.lang.String
     * @Date: 2020/11/17 11:21
     */
    public static String getRegionsPageList(int pageNo, int pageSize){

        //获取区域信息路径  /api/resource/v1/regions/root
        final String getRegionsList = ARTEMIS_PATH + "/api/resource/v1/regions";

        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getRegionsList);
            }
        };
        //定义提交类型
        String contentType = "application/json";
        //参数装换
        JSONObject jsonBody = new JSONObject();
        jsonBody.put("pageNo", pageNo);
        jsonBody.put("pageSize", pageSize);
        String body = jsonBody.toString();
        //传参调用方法
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);

        //返回编码信息
        return result;
    }

    /*
     * @Description: 根据区域编号获取下级监控点列表
     * @author: Orange
     * @Param:
     * @Return: java.lang.String
     * @Date: 2020/11/17 11:36
     */
    public static String getCamerasByRegionCode(String regionIndexCode, int pageNo, int pageSize) {

        //根据区域编号获取下级监控点列表路径
        final String getRootApi = ARTEMIS_PATH + "/api/resource/v1/regions/regionIndexCode/cameras";

        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getRootApi);
            }
        };

        String contentType = "application/json";

        JSONObject jsonBody = new JSONObject();
        jsonBody.put("pageNo", pageNo);
        jsonBody.put("pageSize", pageSize);
        jsonBody.put("regionIndexCode", regionIndexCode);
        String body = jsonBody.toString();

        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);

        //返回编码信息
        return result;
    }

    /*
     * @Description: 根据摄像头编码code获得播放流
     * @author: Orange
     * @Param:
     * @Return: java.lang.String
     * @Date: 2020/11/17 13:19
     */
    public static String getCamerasUrlByCode(String cameraIndexCode) {

        final String getCamsApi = ARTEMIS_PATH + "/api/video/v1/cameras/previewURLs";
        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCamsApi);
            }
        };

        String contentType = "application/json";

        net.sf.json.JSONObject jsonBody = new net.sf.json.JSONObject();
        jsonBody.put("cameraIndexCode", cameraIndexCode);//监控点唯一标识
        jsonBody.put("streamType", 0);//码流类型,0:主码流,1:子码流,2:第三码流,参数不填,默认为主码流
        jsonBody.put("protocol", "rtsp");//取流协议,“rtsp”:RTSP协议,“rtmp”:RTMP协议,“hls”:HLS协议
        jsonBody.put("transmode", 1);//传输协议,0:UDP,1:TCP,默认是TCP
        jsonBody.put("expand", "streamform=ps");//扩展内容,格式:key=value
        String body = jsonBody.toString();

        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);

        //返回编码信息
        return result;
    }

    /*
     * @Description: 获取摄像头列表
     * @author: Orange
     * @Param: int
     * @Return: java.lang.String
     * @Date: 2020/11/17 10:32
     */
    public static String getAllRegionInfo(int pageNo, int pageSize) {

        //获取摄像头列表路径
        final String getCameraList = ARTEMIS_PATH + "/api/resource/v1/cameras";

        Map<String, String> path = new HashMap<String, String>(2) {
            {
                put("https://", getCameraList);
            }
        };
        //定义提交类型
        String contentType = "application/json";
        //参数装换
        JSONObject jsonBody = new JSONObject();
        jsonBody.put("pageNo", pageNo);
        jsonBody.put("pageSize", pageSize);
        String body = jsonBody.toString();
        //传参调用方法
        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, contentType, null);
        //返回结果
        return result;
    }

    public static void main(String[] args) {

        //调用获取区域信息接口 JSONObject pa=JSONObject.parseObject(params)
        String regionsPageList = HKGetCamera.getRegionsPageList(1, 100);
        System.out.println( regionsPageList.getClass());

        //根据区域id来获取下属于摄像列表
        Object camerasByRegionCode = HkTest.getCamerasByRegionCode("e2a69da6-e406-4404-b7f5-6101357248fd", 1, 5);

        //根据摄像头code来获得视频流地址
        String camerasUrlByCode = HkTest.getCamerasUrlByCode("7ab2f03ffef245dca9345deb02d12997");

        //获得摄像头列表
        String cameraResult= HkTest.getAllRegionInfo(1,500);
        //打印查看返回信息
        System.out.println("获得区域信息列表:"+ regionsPageList);
        System.out.println("根据区域节点获得摄像头信息:"+ camerasByRegionCode);
        System.out.println("根据摄像头code来获得流:"+ camerasUrlByCode);
        System.out.println("获得摄像头列表:"+ cameraResult);
    }
}
  • 获得接口返回数组中的有效信息,下属代码以获取摄像头 code 以及 视频流 url 举例,
        String regionsPageList = HKGetCamera.getRegionsPageList(1, 100);
        JSONObject jsonObject = JSONObject.parseObject(regionsPageList);
        String data = jsonObject.getString("data");
        JSONObject jsonData = JSONObject.parseObject(data);
        String list = jsonData.getString("list");
        JSONArray jsonArray = JSONObject.parseArray(list);
        ArrayList<String> regionsResult = new ArrayList<>();
        if (Objects.nonNull(jsonArray) && jsonArray.size() > 0) {
            for (Object object : jsonArray) {
                JSONObject parseObject = JSONObject.parseObject(object.toString());
                String cameraIndexCode = parseObject.getString("indexCode");
                //2、将获得的地区信息编码封装到list中
                regionsResult.add(cameraIndexCode);
            }
        }
	for (String regionsCode : regionsResult) {
            String camerasByRegionCode = null;
            try{
                camerasByRegionCode = HKGetCamera.getCamerasByRegionCode(regionsCode, 10, 1);
                JSONObject json = JSONObject.parseObject(camerasByRegionCode);
                String resultData = json.getString("data");
                JSONObject da = JSONObject.parseObject(resultData);
                String url = da.getString("url");
            }catch (Exception e){}

        }
5、对接监控视频流的处理,可以根据接口传参来设置返回结果中的视频流格式。注意:rtsp格式的视频流无法直接在web端进行播放,但是 rtmp格式的视频流可以,部分摄像头支持返回的 rtmp流可以播放,部分不支持,所以要根据实际的业务需求来进行选择,若是摄像头不支持返回可直接播放的 rtmp流,可以将返回的 rtsp格式的视频流经ffmpeg+nginx进行装换为rtmp。但是效率很低,一般不推荐使用。

在这里插入图片描述
在这里插入图片描述

6、参考海康开放 API 时要注意对应海康综合安防管理平台的版本,不同版本间的 API 几乎不可通用,下图举例 1.10 版本对应 V1.0 版本接口

在这里插入图片描述

8、近期所使用的海康综合管理平台升级,由最初使用的1.1.0 升级为1.5.1,因此项目上需要更改视频信息的api版本,海康平台Hikvision AI Cloud默认显示的API为高版本,且支持向下兼容,对应历史版本api在如下位置

在这里插入图片描述

9、为了更快捷的将接口返回的数据信息进行分析整理入库,提供了如下代码,
/*                                           @Description: HkTest工具类补充代码                                         */
    /**
    * @Description: 数据处理
    * @author: 作者
    * @Param:
    * @Return:
    * @Date: 2021/2/3 14:52
    */
    public static JSONArray checkData(String regionsPageList) {
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(regionsPageList);
        String code = jsonObject.getString("code");
        if (StringUtils.isBlank(code) || !"0".equalsIgnoreCase(code)) {
            return null;
        }
        com.alibaba.fastjson.JSONObject data = jsonObject.getJSONObject("data");
        if (ObjectUtil.isNull(data)) {
            return null;
        }
        Integer total = data.getInteger("total");
        JSONArray list = data.getJSONArray("list");
        System.out.println("所有的list 的长度" + list.size());
        return list;
    }



    /**
     * @Description: 数据处理
     * @author: 作者
     * @Param:
     * @Return:
     * @Date: 2021/2/3 14:52
     */
    public static JSONArray checkCameraData(String cameraList) {
        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(cameraList);
        if (ObjectUtil.isNull(jsonObject)) {
            return null;
        }
        String code = jsonObject.getString("code");
        if (StringUtils.isBlank(code) || !"0".equalsIgnoreCase(code)) {
            return null;
        }
        com.alibaba.fastjson.JSONObject data = jsonObject.getJSONObject("data");
        if (ObjectUtil.isNull(data)) {
            return null;
        }
        Integer total = data.getInteger("total");
        JSONArray list = data.getJSONArray("list");
        System.out.println("所有的 list 的长度" + list.size() +"total:" + total +" list 的长度 和 total是否相等:"+ (total==list.size()) );
        return list;
    }
10、数据提取封装到对应的数据表实现入库存储
package cn.stylefeng.guns.base;

import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.modular.led.entity.LedCameraArea;
import cn.stylefeng.guns.modular.led.entity.LedCameraAreaCameras;
import cn.stylefeng.guns.modular.led.service.LedCameraAreaCamerasService;
import cn.stylefeng.guns.modular.led.service.LedCameraAreaService;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author Orange
 * @version 1.0
 * @Description:此类用于获得数据并解析入库
 * @date 2021/2/3 14:04
 *
 * 根节点:"root000000"
 */
public class HkOptainData {


    private Map getmap(List<LedCameraArea> allAreas) {
        Map<String, LedCameraArea> map = new HashMap<>();
        for (LedCameraArea allArea : allAreas) {
            map.put(allArea.getIndexCode(), allArea);
        }
        return map;
    }

    private void digui(List<LedCameraArea> ledCameraAreas, Map<String, LedCameraArea> noleaf, Map<String, String> map) {
        for (LedCameraArea ledCameraArea : ledCameraAreas) {
            StringBuffer namebuffer = new StringBuffer();
            StringBuffer codebuffer = new StringBuffer();
            diguitree(ledCameraArea, noleaf, map, namebuffer, codebuffer, ledCameraArea.getIndexCode());
        }
    }

    private void diguitree(LedCameraArea ledCameraArea, Map<String, LedCameraArea> noleaf, Map<String, String> map, StringBuffer namebuffer, StringBuffer codebuffer, String key) {
        String pid = ledCameraArea.getParentIndexCode();
        namebuffer.append(ledCameraArea.getName()).append(",");
        codebuffer.append(ledCameraArea.getIndexCode()).append(",");

        LedCameraArea ledCameraArea1 = noleaf.get(pid);
        if (ObjectUtil.isNotNull(ledCameraArea1)) {
            String parentIndexCode = ledCameraArea1.getParentIndexCode();
            if (!"root000000".equalsIgnoreCase(parentIndexCode)) {
                diguitree(ledCameraArea1, noleaf, map, namebuffer, codebuffer, key);
            } else {
                map.put(key, codebuffer.toString() + ";" + namebuffer.toString());
            }
        } else {
            map.put(key, codebuffer.toString() + ";" + namebuffer.toString());
            System.out.println(pid);
        }
    }

    @Autowired
    LedCameraAreaService ledCameraAreaService;

    @Autowired
    LedCameraAreaCamerasService ledCameraAreaCamerasService;

    @Test
    public void testHkRegions() {

        //初始化根节点
        String[] roots = new String[]{"root000000"};
        String regionsPageList = HkTest.getRegionsPageList(roots, 1, 1000);
        JSONArray objects = HkTest.checkData(regionsPageList);
        if (CollectionUtils.isNotEmpty(objects)) {
            for (Object object : objects) {
                com.alibaba.fastjson.JSONObject jsonObject = (com.alibaba.fastjson.JSONObject) object;
                LedCameraArea entity = JSONObject.parseObject(jsonObject.toJSONString(), LedCameraArea.class);
                ledCameraAreaService.add(entity);
            }
        }

    }

    @Test
    public void testHkCameros() {
        QueryWrapper<LedCameraArea> wrapper = new QueryWrapper<>();
        wrapper.eq("leaf", 1);//叶子节点筛选
        List<LedCameraArea> ledCameraAreas = ledCameraAreaService.selectLedCameraArea(wrapper);

        QueryWrapper<LedCameraArea> allwrapper = new QueryWrapper<>();
        List<LedCameraArea> allAreas = ledCameraAreaService.selectLedCameraArea(allwrapper);

        Map<String, LedCameraArea> noleaf = getmap(allAreas);

        //先把相应的 tree 弄出来
        for (LedCameraArea ledCameraArea : allAreas) {
            noleaf.put(ledCameraArea.getIndexCode(), ledCameraArea);
        }
        Map<String, String> map = new HashMap<>();

        digui(ledCameraAreas, noleaf, map);

        //初始化计数器
        int n=0;

        for (LedCameraArea ledCameraArea : ledCameraAreas) {
            String nameandcode = map.get(ledCameraArea.getIndexCode());
            String namepath="";
            String codepath="";
            if (StringUtils.isNotBlank(nameandcode)) {
                String[] split = nameandcode.split(";");
                codepath=split[0];
                namepath=split[1];
            }
            String name=ledCameraArea.getName();
            String code=ledCameraArea.getExternalIndexCode();
            Object camerasByRegionCode = HkTest.getCamerasByRegionCode(ledCameraArea.getIndexCode(), 1, 1000);
            JSONArray objects = HkTest.checkCameraData((String) camerasByRegionCode);
            if (ObjectUtil.isNull(objects)) {
                continue;
            }

            n+=objects.size();
            System.out.println(ledCameraArea.getName()+":"+ledCameraArea.getIndexCode()+";"+objects.size());

            for (Object object : objects) {
                com.alibaba.fastjson.JSONObject jsonObject = (com.alibaba.fastjson.JSONObject) object;
                LedCameraAreaCameras entity = JSONObject.parseObject(jsonObject.toJSONString(), LedCameraAreaCameras.class);
                entity.setRegionCode(code);
                entity.setRegionName(name);
                entity.setRegionPath(codepath);
                entity.setRegionPathName(namepath);
                ledCameraAreaCamerasService.add(entity);
            }

        }

        System.out.println("总共多少个摄像头:"+ n +" 总共多少个区域 :"+ledCameraAreas.size());
    }
}

11、实体类的创建可根据api返回的数据创建对应的属性,也可仅对部分可用数据进行封装
	/*此处举例部分属性*/
	@TableField("dept_id")
    private Long deptId;

    @TableField("indexCode")
    private String indexCode;

    @TableField("nodeType")
    private String nodeType;

    @TableField("name")
    private String name;

    @TableField("regionPath")
    private String regionPath;

    @TableField("parentIndexCode")
    private String parentIndexCode;

    @TableField("cascadeCode")
    private String cascadeCode;

    @TableField("cascadeType")
    private String cascadeType;

    @TableField("externalIndexCode")
    private String externalIndexCode;

    @TableField("available")
    private boolean available;

    @TableField("leaf")
    private boolean leaf;

    @TableField("catalogType")
    private Long catalogType;
12、平台版本升级后通过api所返回数据【json格式】内容变得更多,仅获取项目所需得内容即可
{
	"code": "0",
	"msg": "success",
	"data": {
		"total": 46,
		"pageNo": 1,
		"pageSize": 100,
		"list": [{
			"indexCode": "root000000",
			"nodeType": 0,
			"name": "根节点",
			"regionPath": "@root000000@",
			"parentIndexCode": "-1",
			"cascadeType": 0,
			"externalIndexCode": "370102",
			"sort": 1,
			"createTime": "2021-01-19T14:53:39.136+08:00",
			"updateTime": "2021-01-22T09:55:17.075+08:00",
			"regionCode": "",
			"available": true,
			"leaf": false,
			"catalogType": 10,
			"cascadeCode": "0"
		}]
	}
}
13、最后感谢一位CSDN博主,对我所提问题的耐心解答,这是他的博文地址,欢迎大家前去拜读!

https://blog.csdn.net/weixin_43716343/article/details/108054096#comments_13802942

14、话外:高版本的综合安防平台可以获得支持web端直接播放得rtmp格式视频流,如果返回的rtmp 视频流可以在第三方工具,如 VLC 上播放但是在页面使用 video.js 无法进行播放,可以考虑是否是视频码流所造成的影响。可以通过调用接口时指定码流格式 【0:为主码流】【1:为子码流】
  • 15
    点赞
  • 130
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
海康综合安防管理平台php是一种集成了海康安防产品的开发平台,通过使用php语言进行开发,提供全面的安防管理功能。该平台可以帮助用户实现对安防设备的集中化管理和控制,提高安防管理的效率和便捷性。 海康综合安防管理平台php具备以下特点和优势: 1. 全面的功能:平台提供了丰富的安防管理功能,包括视频监控、门禁控制、报警管理、人员定位等多个方面。用户可以通过一个统一的界面实现对各种设备和功能的管理和控制,大大简化了操作流程。 2. 强大的扩展性:海康综合安防管理平台php具备灵活的扩展性,可以根据用户的需求进行二次开发和定制。用户可以根据自身的实际情况,进行系统功能的扩展和改造,以满足特定的管理需求。 3. 高度集成化:该平台可以集成海康安防产品,如摄像机、录像机、门禁控制器等。通过与海康的硬件设备的无缝集成,可以实现对设备的实时监控、远程回放、报警处理等功能。 4. 可靠的安全性:海康综合安防管理平台php采用了严格的数据加密和安全验证机制,确保用户的数据和系统安全。同时,平台还提供完善的权限管理机制,用户可以根据实际需求设置用户权限,保障系统的安全和隐私。 总之,海康综合安防管理平台php将安防设备的管理和控制集成到一个平台上,实现了一体化的管理和操作,提高了安防管理的效率和便捷性,为用户提供了可靠的安全保障。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值