python调用海康视频汇聚平台API,获得所有摄像头设备编号、实时播放rtsp地址、回放rtsp地址

news2024/11/24 11:27:26

目录

      • 1. 需求
      • 2. 思路
      • 3. 实现
        • 3.1. 确保服务器上安装视频汇聚平台(iSecure Center)
        • 3.2. 查看API网关是否安装成功
        • 3.3. 分配身份认证信息AK/SK
        • 3.4. 利用认证信息,python demo开发

1. 需求

海康视频汇聚平台(综合安防管理平台(iSecure Center)V2.1.0)的openAPI的demo均为c++/java代码,官方没有python代码。

需通过汇聚平台获得所有摄像头的设备编号,利用设备编号获得摄像头IP地址和rtsp地址。

2. 思路

根据海康开放平台官方文档《资源中心>综合安防管理平台(iSecure Center)>开发前准备》,通过平台获得摄像头信息,需遵循以下步骤:

  1. 确保服务器上安装视频汇聚平台(iSecure Center);
  2. 查看API网关是否安装成功;
  3. 分配身份认证信息AK/SK;
  4. 利用认证信息,撰写python demo

3. 实现

3.1. 确保服务器上安装视频汇聚平台(iSecure Center)

对接前需要先部署海康威视综合安防管理平台 iSecure Center
V1.5.100或更高版本的产品。

产品的安装过程请参考产品的《iSecure Center
综合安防管理平台 安装部署指南》,该文档可以在产品安装光盘中获取。

3.2. 查看API网关是否安装成功

  1. 登入运管中心,如下
    在这里插入图片描述

  2. 进入“状态监控”页面,如下
    在这里插入图片描述

  3. 左侧菜单搜索API网关,如下
    在这里插入图片描述

  4. 在API网关的监控详情选项卡中查看服务的运行状态,如下
    在这里插入图片描述

  5. 运行状态显示“正在运行”表示API网关安装成功,如下
    在这里插入图片描述

3.3. 分配身份认证信息AK/SK

开发前需要先获取对接的身份认证信息,AK/SK——平台会通过AK/SK认证方式来验证请求发送者的身份。

获取接口调用权限,资源操作权限——平台会判断某个请求者是否有某个接口的调用权限,以及资源的操作权限。

在平台的OpenAPI管理中心新增合作方来生成AK/SK并分配权限。

  1. 进入运行管理中心,点击“状态监控”选项卡,搜索API网关,点击“API管理”,如下

在这里插入图片描述
2. 进入OpenAPI管理中心,点击“合作方管理”菜单,如下
在这里插入图片描述
3. 点击“创建合作方”,如下
在这里插入图片描述
4. 输入合作方名称和描述,如下
在这里插入图片描述
5. 配置合作方的参数,配置userId的值,userId的值对应平台内部的一个用户;如果使用admin的话,默认所有资源权限都有,如下
在这里插入图片描述
6. 配置合作方的参数,配置domainId的值,domainId对应对接平台所在的网域,如下
在这里插入图片描述
7. 配置合作方的参数,配置tagId的值,为保证接口兼容性,tagId的值请配为frs,如下

在这里插入图片描述
8. 配置完上述信息后,点击创建按钮,如下

在这里插入图片描述
9. 创建完新的合作方,进入合作方管理列表,选择其中一个合作方点击授权,如下
在这里插入图片描述
10. 对接口进行授权,如下
在这里插入图片描述
11. 接口授权完成后,到合作方列表,点击合作方进入详情页,如下
在这里插入图片描述
12. 在合作方详情页面获取AK/SK,合作方Key就是AK,合作方Secret就是SK,如下
在这里插入图片描述

3.4. 利用认证信息,python demo开发

  1. 获得artemis网关服务器ip端口 ,即API网关的ip地址,端口默认为443,如下
    在这里插入图片描述
  2. 获得秘钥appkey和秘钥appSecret ,如下
    在这里插入图片描述
  3. 获得设备编号的openAPI获取方式,需确定请求方式和Body内容,如下
    在这里插入图片描述
    在这里插入图片描述
请求:/api/irds/v2/deviceResource/resources

Body示例(这里为摄像头camera):
{
    "pageNo": 1,
    "pageSize": 100,
    "resourceType": "camera"
}
  1. 获得指定设备编号的回放url的openAPI获取方式,需确定请求方式和Body内容,如下

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

请求:/api/video/v2/cameras/playbackURLs

Body示例:
{
    "cameraIndexCode": "90ad77d8057c43dab140b77361606927",
    "recordLocation": "0",
    "protocol": "rtsp",
    "transmode": 0,
    "beginTime": "2017-06-15T00:00:00.000+08:00",
    "endTime": "2017-06-18T00:00:00.000+08:00",
    "uuid": "",
    "expand": "streamform=rtp",
    "streamform": "ps",
    "lockType": 0
}
  1. python demo

主要参考博客《海康综合安防管理平台python版sdk》和《利用Python调用海康威视综合管理平台openAPI接口》

# coding=gb2312

import os
import base64
import json
import time
import uuid
import hmac  # hex-based message authentication code 哈希消息认证码
import hashlib  # 提供了很多加密的算法
import requests
import cv2 
 

class OpenApiISC: # 调用视频汇聚平台的openAPI
    def __init__(self, gatewayIp, appKey, appSecret):
        self.gatewayIp = gatewayIp # API网关IP
        self.appKey = appKey # 合作方key
        self.appSecret = appSecret # 合作方秘钥
        self.base_url = "https://{}:443".format(self.gatewayIp) # api网关ip和端口号
        self.http_method = "POST"
        self.ARTEMIS_PATH = "/artemis"
        
        self.cameraDataDict = {} # 最后输出的摄像头数据字典
        
    def init(self, api_get_address_url): # 每次执行操作,都要初始化
        appKey = self.appKey
        appSecret = self.appSecret
        x_ca_nonce = str(uuid.uuid4())
        x_ca_timestamp = str(int(round(time.time()) * 1000))
        signature = self.generateSignature( appKey, appSecret, x_ca_nonce, x_ca_timestamp, api_get_address_url)
        
        self.headers = {
            "Accept": "*/*",
            "Content-Type": "application/json",
            "x-ca-key": appKey,  # appKey,即 AK
            "x-ca-signature-headers": "x-ca-key,x-ca-nonce,x-ca-timestamp",
            "x-ca-signature": signature,  # 需要计算得到的签名,此处通过后台得到
            "x-ca-timestamp": x_ca_timestamp,  # 时间戳
            "x-ca-nonce": x_ca_nonce  # UUID,结合时间戳防重复
        }
        
    def sign(self, key, value):
        temp = hmac.new(key.encode(), value.encode(), digestmod=hashlib.sha256)
        return base64.b64encode(temp.digest()).decode()
    
    def generateSignature(self, appKey, appSecret, x_ca_nonce, x_ca_timestamp, api_get_address_url): # 生成签名值
        # sign_str 的拼接很关键,不然得不到正确的签名
        sign_str = "POST\n*/*\napplication/json" + "\nx-ca-key:" + appKey + "\nx-ca-nonce:" + \
                   x_ca_nonce + "\nx-ca-timestamp:" + x_ca_timestamp + "\n" + \
                   api_get_address_url
        signature = self.sign(appSecret, sign_str)
        print("[INFO] 获取到的签名值为:", signature)
        return signature
    
    def getDeviceIndexCodeListOperation(self): # 获取设备列表,可获得设备编码和名称
        api_get_address_url = "{}{}".format(self.ARTEMIS_PATH, "/api/irds/v2/deviceResource/resources") # 
        self.init(api_get_address_url) # 获得设备编码的操作前的初始化
    
        body = {
            "pageNo": 1,
            "pageSize": 100,
            "resourceType": "camera"
        }
        
        url = self.base_url + api_get_address_url
        results = requests.post(url, data=json.dumps(body), headers=self.headers,  verify=False)
        print(results.json())
        
        for i in range(len(results.json()['data']['list'])): # 遍历所有设备
            data = results.json()['data']['list'][i]
            if data['resourceType'] != 'camera': continue # 仅考虑摄像头
            
            cameradata = {} # 单个摄像头数据
            cameradata.setdefault('indexCode', data['indexCode']) # 摄像头的设备编码
            cameradata.setdefault('name', data['name']) # 摄像头的名称
            cameradata.setdefault('regionIndexCode', data['regionIndexCode']) # 摄像头所属区域的编码
            cameradata.setdefault('regionName', data['regionName']) # 摄像头所属区域的名称
            
            self.cameraDataDict.setdefault(i, cameradata)
        
        print("获取设备编码和名称:", self.cameraDataDict)
        
    
    def getSingleRealtimeURL(self, indexCode): # 根据设备编码indexCode,获取摄像头的实时播放url
        api_get_address_url = "{}{}".format(self.ARTEMIS_PATH, "/api/video/v2/cameras/previewURLs")
        self.init(api_get_address_url) # 获得设备实时播放url的操作前的初始化
        
        body = {
            "cameraIndexCode": indexCode,
            "streamType": 0,
            "protocol": "rtsp",
        }
        
        url = self.base_url + api_get_address_url
        results = requests.post(url, data=json.dumps(body), headers=self.headers,  verify=False)
        #print("根据设备编码{},获得实时播放url:{}".format(indexCode, results.json()['data']['url']))
        
        return results.json()['data']['url']
        
    
    def getSinglePlaybackURL(self, indexCode, beginTime, endTime,  name): # 根据设备编码indexCode, 获取摄像头给定时间段内的回放播放url
        if 'NVR' not in name: return '' # 只有nvr设备才有回放
    
        api_get_address_url = "{}{}".format(self.ARTEMIS_PATH, "/api/video/v2/cameras/playbackURLs")
        self.init(api_get_address_url) # 获得设备实时播放url的操作前的初始化
        
        body = {
                  "cameraIndexCode": indexCode,
                  "recordLocation": "1",
                  "protocol": "rtsp",
                  "transmode": 0,
                  "beginTime": beginTime,
                  "endTime": endTime,
                  "expand": "streamform=rtp"
              }
        
        url = self.base_url + api_get_address_url
        results = requests.post(url, data=json.dumps(body), headers=self.headers,  verify=False)
        print("根据设备编码{}和时间段,获得回放播放url:{}".format(indexCode, results.json()['data']))
        
        return results.json()['data']['url']
    
    
    def getCameraDataDictOperation(self, beginTime, endTime): # 根据设备编码,获得摄像头的实时播放url
        for key, camerainfo in self.cameraDataDict.items(): # 遍历摄像头
            indexCode = camerainfo['indexCode'] # 设备编码
            name = camerainfo['name'] # 设备名称
            url = self.getSingleRealtimeURL(indexCode) # 实时播放url
            playback_url = self.getSinglePlaybackURL(indexCode, beginTime, endTime, name) # 回放信息
            
            
            self.cameraDataDict[key].setdefault('url', url) # 添加url数据
            self.cameraDataDict[key].setdefault('playback', {'beginTime': beginTime, 'endTime': endTime, 'url': playback_url}) # 添加回放url
        
        print("根据设备编码列表,获得摄像头数据:", self.cameraDataDict)
            
            
      
        
            
if __name__ == '__main__':     
    gatewayIp = '' # 请填写自己的
    appKey = "" # 请填写自己的
    appSecret = "" # 请填写自己的
           
    openAPIs = OpenApiISC(gatewayIp, appKey, appSecret)
    openAPIs.getDeviceIndexCodeListOperation() 
    
    beginTime = "2023-05-23T13:44:04.000+08:00"
    endTime = "2023-05-23T15:44:04.000+08:00"
    openAPIs.getCameraDataDictOperation(beginTime, endTime) 



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/565026.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习之集成学习

一、介绍 集成学习(Ensemble Learning)是一种机器学习技术,通过结合多个学习器(例如决策树、神经网络、支持向量机等)的预测结果,来达到更好的分类或回归预测性能。集成学习可以通过降低模型的方差&#x…

探究 Android 14 新功能之 TextView 搜索高亮和焦点移动~

前言 之前写的文章《Android 14 新功能之 HighLights》里,讲到 Android 14 里推出的 HighLights 新功能可以快速实现 TextView 文字的高亮效果,并支持动态更新。 本文将继续介绍 TextView 的另 2 处新功能: 使用 searchResultHighlight 等…

(转载)从0开始学matlab(第14天)—while循环结构

循环(loop) 是一种 matlab 结构,它允许我们多次执行一系列的语句。循环结构有两种基本形式 :while 循环和 for 循环。两者之间的最大不同在于代码的重复是如何控制的。在while 循环中,代码的重复的次数是不能确定的,只要满足用户定义的条件…

Metabase可视化BI系统部署安装及简单使用

metabase 是国外开源的一个可视化系统,语言使用了Clojure TypeScript。 Clojure(/ˈkloʊʒər/)是Lisp程式語言在Java平台上的現代、動態及函數式方言。来自维基百科。 我也是第一次看到这个语言,知道它是可以运行在Java环境上的…

脱离文档流和半脱离文档流(详解)

脱离文档流和半脱离文档流(详解)_脱离文档流是什么意思_大前端工程师的博客-CSDN博客 脱离文档流 脱离文档流是指,该元素脱离了文档中。不再占据默认分配的空间,它下面的元素会上去补位。 可以理解为脱离文档流的元素离开了它的座…

1720_Linux学习中的问题处理

全部学习汇总:GreyZhang/little_bits_of_linux: My notes on the trip of learning linux. (github.com) 这个有点学习的方法论的意思,画个滋味导图顺便整理一下。 遇到问题的时候,解决的方法大致有3中,而针对学习的建议有一部分是…

STL-queue和priority_queue的模拟实现

回顾 对于STL,我们已经知道了vector和list,而它们是STL中被称为六大组件之一的容器,我们还学习了模拟实现stack,而stack在STL中被称为六大组件之一的适配器,今天,我们来学习queue的模拟实现和priority_que…

分布式运用之ELK企业级日志分析系统

1.ELK的相关知识 1.1 ELK的概念与组件 ELK平台是一套完整的日志集中处理解决方案,将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用, 完成更强大的用户对日志的查询、排序、统计需求。 ElasticSearch: 是基于Lucene&#xff0…

Tomcat服务器、Servlet生命周期、上传下载文件、使用XHR请求数据、注解使用

文章目录 Servlet认识Tomcat服务器使用Maven创建Web项目创建Servlet探究Servlet的生命周期解读和使用HttpServletWebServlet注解详解使用POST请求完成登陆上传和下载文件下载文件上传文件 使用XHR请求数据重定向与请求转发重定向请求转发 ServletContext对象初始化参数 Servlet…

基于自营配送模式的车辆路径规划设计与实现_kaic

摘要 近年来,随着我国消费水平逐渐提升,消费者在网上购物的频率也越来越高,电商发展速度迅猛,加大了物流配送的压力,促使物流企业以更大的运力,更短的时间将货物送达。在货品的运输过程中,成本居…

TCP 连接未必都是用TCP协议沟通

确实,一般来说 TCP 连接是标准的 TCP 三次握手完成的: 1.客户端发送 SYN; 2.服务端收到 SYN 后,回复 SYNACK; 3.客户端收到 SYNACK 后,回复 ACK。 SYN 会在两端各发送一次,表示“我准备好了&…

MicroBlaze系列教程(9):xilisf串行Flash驱动库的使用

文章目录 1. xilisf库简介2. xilisf库函数3. xilisf配置4. xilisf应用示例工程下载本文是Xilinx MicroBlaze系列教程的第9篇文章。 1. xilisf库简介 xilisf库(Xilinx In-system and Serial Flash Library) 是Xilinx 提供的一款串行Flash驱动库,支持常用的 Atmel 、Intel、S…

Linux基本指令介绍

目录 前言 指令操作与图形化界面的对比 adduser passwd whoami ls指令 pwd指令 cd指令 touch指令 mkdir指令 rmdir指令 && rm 指令 man指令 cp指令 mv指令 cat(显示文件内容(全部),且不可修改的)…

【1++的C++初阶】之模板

👍作者主页:进击的1 🤩 专栏链接:【1的C初阶】 文章目录 一,浅谈模板二,函数模板三,类模板 一,浅谈模板 在前面的文章【【1的C初阶】之C入门篇1】中我们对函数重载有了一定的认识&a…

Python-web开发学习笔记(3):Flask Demo,一个网站开发小案例

☕️ 推荐关注我的另一个专栏系列:大道至简,该系列收录了许多优质的人工智能算法博文,包括机器学习和自然语言处理等,持续更新中,欢迎各位关注~ 介绍完HTML标签,我们来搞一个简单的网站小案例,带…

一、CNNs网络架构-基础网络架构

目录 1.LeNet 2.AlexNet 2.1 激活函数:ReLU 2.2 随机失活:Droupout 2.3 数据扩充:Data augmentation 2.4 局部响应归一化:LRN 2.5 多GPU训练 2.6 论文 3.ZFNet 3.1 网络架构 3.2 反卷积 3.3 卷积可视化 3.4 ZFNet改…

6.4.6拓扑排序

用DAG&#xff08;有向无环图&#xff09;表示一个工程。顶点表示活动&#xff0c;有向边<Vi&#xff0c;Vj>表示活动Vi活动必须先与Vj活动进行。 所谓的拓扑排序&#xff1a;找到做事的先后顺序 以上根据拓扑排序的实现&#xff1a; 加入对有回路的图进行拓扑排序&#…

重磅,ChatGPT App 来了!(附保姆级教程)

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了人工智能中文站https://ai.weoknow.com 每天给大家更新可用的国内可用chatGPT资源 日前&#xff0c;OpenAI宣布推出iOS移动版ChatGPT&#xff0c;为iPhone和iPad用户提供免费下载和使用机会。 总体而言&#xff0…

视频转换芯片MS7200概述 HDMI转数字RGB/YUV/HDMI RXReceive/替代IT66021FN

1. 基本介绍 MS7200 是一款 HDMI 接收芯片&#xff0c;兼容 HDMI1.4b 及 HDMI 1.4b 以下标准的视频 3D 传输格 式&#xff0c;最高分辨率可支持到 4K30Hz&#xff0c;最高采样率达到 300MHz。MS7200 支持 YUV 和 RGB 之 间的色彩空间转换&#xff0c;数字接口支持 YUV 及 RGB 格…

动态规划-完全平方数

动态规划-完全平方数 1 题目描述2 示例2.1 示例 1&#xff1a;2.2 示例 2&#xff1a;2.3 提示&#xff1a; 3 解题思路及方法3.1 解题思路3.1.1 确定状态3.1.2 转移方程3.1.3 初始条件和边界情况3.1.4 计算顺序 3.2 算法代码实现 跟着九章侯老师学习了动态规划专题之后根据学习…