uniapp微信小程序通过萤石云接入海康摄像机

需求:在uniapp微信小程序上查看海康威视的摄像机监控视频和和操作摄像机拍摄方向

在萤石云接入海康摄像机设备,由于不同品牌设备在不同时间段接入方式可能不一致,具体接入方式查看官方文档或咨询官方客服。

海康摄像机官方客服热线:4008005998

接入方式:官方提供多种接入方式,在此选择通过“半屏”(https://open.ys7.com/help/502)接入

操作流程:

  • 先确保该设备未在海康互联、海康云耀、海康威视等平台接入。如有接入,请先退出。确保该设备已购买流量套餐。
  • 萤石云开放平台:注册平台账号并创建好应用,https://open.ys7.com/console/application.html
  • “萤石云视频”APP:在通过“萤石云视频”APP,添加设备,扫描摄像机底部专属二维码或输入设备序列号,根据提示的步骤操作…(选择SIM设备添加,无需验证码)
  • 海康威视摄像机:在摄像机摄像头的安置SIM卡的地方(该款摄像机提供内置和外置SIM卡),扭开螺丝钉,找到“reset”键,接通电源,按下重置键,等待摄像机提示“等待注册平台”等提示音…
  • 接入完毕

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

代码实现:

单独js文件存放萤石云appKey和appSecret,也可直接写在vue文件中,在此选择第一种js导入方式

@/common/config.js

// 萤石云(https://open.ys7.com/console/application.html)
export const appKey = 'xxx'

export const appSecret = 'xxx'

摄像机设备列表页

萤石云接口:

  • accessToken过期获取:https://open.ys7.com/api/lapp/token/get
  • 获取所有设备:https://open.ys7.com/api/lapp/camera/list,获取设备序列号和名字
  • 获取抓拍图:https://open.ys7.com/api/lapp/device/capture,获取当前抓拍图

微信小程序半屏跳转:wx.openEmbeddedMiniProgram( )

@/pages/videoSurveillanceList/videoSurveillanceList

<template>
<view class="videoSurveillanceList">
	<!-- 设备列表 -->
	<view class="container" v-if="equipmentList">
		<view class="item" v-for="item in equipmentList" :key="item.deviceSerial">
			<view class="item-t" @click="toYXYApplet(item.deviceSerial)">
				<image v-if="item.imgUrl" :src="item.imgUrl" mode=""></image>
				<image v-else src="@/static/defaule/jk.png" mode=""></image>
			</view> 
			<view class="item-b">
				<view class="text">
					<view class="">{{ item.channelName }}</view>
					<view class="">{{ item.deviceSerial }}</view>
				</view>
				<view class="icon" @click="open(item.deviceSerial)">
					<uni-icons type="more-filled" size="30"></uni-icons>
				</view>
			</view>
			
		</view>
	</view>
	
	<!-- 编辑按钮弹出 -->
	<uni-popup ref="popup" type="center">
		<view class="popup_content">
			<view class="title">{{currentId}}</view>
			<view class="popup_item" @click="editName"> 
				<uni-icons type="gear" size="26"></uni-icons>
				<text> 修改名称 </text>
			</view>
			<view class="popup_item" @click="remove"> 
				<uni-icons type="trash" size="26"></uni-icons>
				<text> 移除设备 </text>
			</view>
		</view>
	</uni-popup>
	
	<!-- 右下角添加设备按钮 -->
	<uni-fab ref="fab"  horizontal="right" @fabClick="addEquipment" />
</view>
</template>

<script>
import {appKey, appSecret} from '@/common/config.js'
export default{
	data(){
		return {
			accessTokenObj: uni.getStorageSync("accessTokenObj"),
			accessToken: uni.getStorageSync("accessTokenObj").accessToken,
			// 需要跳转的半屏小程序的id:萤石云微信小程序id
			XYYAppId: 'wxf2b3a0262975d8c2',
			equipmentList:[
				// {
				// 	// 序列号
				// 	deviceSerial: '',
				// 	// 添加时间
				// 	bindingTime: '',
				// 	// 监控图片(用于展示监控)
				// 	imgUrl: '',
				// 	// 设备名称
				// 	channelName: ''
				// },
			],
			currentId: '',
		}
	},
	
	mounted(){
		uni.removeStorageSync('accessTokenObj');
		this.getEquipmentList();
		uni.showLoading({
			title: '加载中'
		});
	},
	
	methods:{
		open(e) {
			this.$refs.popup.open()
			this.currentId = e
		},
		
		close() {
			this.$refs.popup.close()
		},
		
		// 修改名称
		editName(){
            // ...
			this.$refs.popup.close()
		},
		
		// 删除设备
		remove(){
			// ...
			this.$refs.popup.close()
		},
		
		// 添加设备
		addEquipment(validateCode='', deviceSerial=''){
			...
		},
		

		// 更新accessToken
		async upToken(){
			return new Promise((resolve, reject)=>{
				uni.request({
					url:'https://open.ys7.com/api/lapp/token/get',
					data:{
						appKey,
						appSecret,
					},
					method :"POST",
					header:{
						"Content-Type": "application/x-www-form-urlencoded"
					},
					success:res=>{
						if(res.data?.code==200){
							uni.setStorageSync('accessTokenObj', res.data.data)
							this.accessTokenObj = res.data.data
							this.accessToken = res.data.data.accessToken
							resolve('ok');
						}else{
							uni.showToast({ title: "获取萤石云token失败", icon: "error"})
							reject(new Error("获取token失败"));
						}
					},
					fail:err=>{
						uni.showToast({ title: "获取萤石云token发生错误", icon: "error"})
						reject(new Error("获取token失败"));
					}
				})
			})

		},
		
		
		// 获取设备列表
		async getEquipmentList(){
			if(!this.accessTokenObj || this.accessTokenObj.expireTime <= Date.now()){
				await this.upToken()
			}
			uni.request({
				url:'https://open.ys7.com/api/lapp/camera/list',
				data:{
					accessToken: this.accessToken,
				},
				method:'POST',
				header:{
					"Content-Type": "application/x-www-form-urlencoded"
				},
				success: (res) => {
					if(res.data?.code == 200){
						this.getEquipmentsImgs(res.data.data)
					}else{
						uni.showToast({ title: "请求失败", icon: "none" })
					}
				},
				fail: (err) => {
					uni.showToast({ title: "请求错误", icon: "none" })
				}
			})
		},
		
		// 遍历调用reqEquipmentsImg,获取所有设备图片
		async getEquipmentsImgs(list){
			let newsArr = list.map(async item=>{
				return await this.reqEquipmentsImg(item.deviceSerial)
			})
			
			await Promise.all(newsArr).then( r =>{
			    r.forEach((item,i)=>{
					if(item.data?.code == 200){
						list[i].imgUrl = item.data.data.picUrl
					}else{
						uni.showToast({ title: "抓拍图请求失败", icon: "none" })
					}
			    })
			}).catch( e =>{
			    uni.showToast({ title: "图片获取失败,请重试", icon: "none" })
			})
            
			uni.hideLoading()
			this.equipmentList = list
		},
		
		// 获取单个设备图片
		async reqEquipmentsImg(deviceSerial){
			if(!this.accessTokenObj || this.accessTokenObj.expireTime <= Date.now()){
				await this.upToken()
			}
			return await uni.request({
				// 图片抓拍
				url:'https://open.ys7.com/api/lapp/device/capture',
				data:{
					deviceSerial,
					channelNo: 1,
					accessToken: this.accessToken,
				},
				method:'POST',
				header:{
					"Content-Type": "application/x-www-form-urlencoded"
				}
			})
		},
		
		// 跳转萤石云小程序
		async toYXYApplet(deviceSerial) {
			if(!this.accessTokenObj || this.accessTokenObj.expireTime <= Date.now()){
				await this.upToken()
			}
			// #ifdef MP-WEIXIN
			wx.openEmbeddedMiniProgram({
				appId: this.XYYAppId,
				path: '/pages/live/live?accessToken='+ this.accessToken +  '&deviceSerial='+ deviceSerial + '&channelNo=1'
			})
			// #endif
			// #ifndef MP-WEIXIN
			uni.showToast({
				title: "请在微信小程序查看监控",
				icon: "none"
			})
			// #endif
		},
	}	
}
</script>

<style lang="scss" scoped>
.videoSurveillanceList{
	width: 100vw;
	height: 100vh;
	background-color: #f9f9f9;
}
.container{
	width: 100vw;
	padding: 20rpx;
	box-sizing: border-box;
	display: grid;
	grid-template-columns: 1fr 1fr;
	grid-template-rows: 1fr 1fr;
	grid-gap: 30rpx;
	.item{
		height: 392rpx;
		border-radius: 20rpx;
		overflow: hidden;
		background-color: white;
		box-shadow: 0 0 10px #d1d1d1;
		.item-t{
			width: 100%;
			height: 300rpx;
			image{
				width: 100%;
				height: 100%;
			}
		}
		.item-b{
			padding: 6rpx 10rpx;
			display: flex;
			align-items: center;
			justify-content: space-between;
			font-weight: 500;
			.text{
				overflow: hidden;
				white-space: nowrap;
				text-overflow: ellipsis;
			}
			.icon{
				margin-left: 10rpx;
				display: flex;
				align-items: center;
				padding: 10rpx 4rpx;
			}
		}
	}
}

.popup_content{
	padding: 10rpx 0;
	font-size: 28rpx;
	font-weight: 500;
	width: 300rpx;
	height: 200rpx;
	background-color: #f9f9f9;
	border-radius: 20rpx;
	display: flex;
	flex-direction: column;
	justify-content: center;
	align-items: center;
	.title{
		border-bottom: #d1d1d1 1px solid;
		width: 100%;
		font-weight: 600;
		text-align: center;
		margin-bottom: 10rpx;
	}
	.popup_item{
		display: flex;
		justify-content: center;
		align-items: center;
		margin:10rpx 0;
		text{
			padding-left: 10rpx;
		}
	}
	.popup_item:last-child{
		margin-bottom: 0;
	}
}
</style>

注:通过萤石云视频APP、萤石云开放平台、海康摄像机、uniapp,简略实现了uniapp微信小程序查看海康摄像机监控视频和操作摄像机拍摄方向
在这里插入图片描述
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

web学习笔记(五十五)

目录 1. 配置代码片段的步骤 2. 条件判断 2.1 v-if、v-else、v-else-if 2.2 v-show 2.3 v-show和v-if的区别 1. 配置代码片段的步骤 在Visual Studio Code中我们可以将常用的代码配置成代码片段&#xff0c;这样就可以在页面上快速输入大段代码了。 &#xff08;1&#…

JavaScript-基本数据类型和变量

基本数据类型 JavaScript支持数字、字符串和布尔值3种基本数据类型 字符串型 字符串型是JavaScript用来表示文本的数据类型&#xff0c;字符串通常由单引号或双引号括起来&#xff0c;如果字符串存在特殊字符&#xff0c;可以用转义字符代替 数字型 数字型也是JavaScript中的基…

pytest教程-46-钩子函数-pytest_sessionstart

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了pytest_report_testitemFinished钩子函数的使用方法&#xff0c;本小节我们讲解一下pytest_sessionstart钩子函数的使用方法。 pytest_sessionstart 是 Pytest 提供的一个钩子函数&#xff0c…

U盘中毒文件变乱码?揭秘原因与高效恢复方法!

在日常使用U盘的过程中&#xff0c;有时我们会遭遇到一个非常棘手的问题——文件突然出现乱码。当你满怀期待地插入U盘&#xff0c;准备打开某个重要文件时&#xff0c;却发现文件名或内容变成了一堆无法识别的字符&#xff0c;这种心情无异于晴天霹雳。乱码文件不仅影响了我们…

数据结构------二叉树经典习题1

博主主页: 码农派大星. 关注博主带你了解更多数据结构知识 1判断相同的树 OJ链接 这道题相对简单,运用我们常规的递归写法就能轻松写出 所以我们解题思路应该这样想: 1.如果p为空&#xff0c;q为空&#xff0c;那么就是两颗空树肯定相等 2.如果一个树为空另一棵树不为空那么…

Android 应用开发-实现将公共存储空间内的文件复制到应用的私用存储空间中

一、前言 几个月前&#xff0c;我用Android Studio给公司销售部门的同事开发了一款手机app&#xff0c;让同事们用自己的手机就能进行商品的扫码盘点操作&#xff0c;帮他们提高了工作效率&#xff0c;他们用了一段时间&#xff0c;反映还不错。不过前几天&#xff0c;销售部门…

洗衣洗鞋店做小程序有什么优势?

互联网洗衣洗鞋小程序闪亮登场&#xff0c;想知道这款小程序有何魅力吗&#xff1f; 如今&#xff0c;众多商家纷纷推出预约上门洗鞋服务&#xff0c;&#x1f481;‍♀️并倾力打造洗鞋小程序&#xff0c;旨在拓展线上销售渠道。&#x1f31f;那么&#xff0c;这款洗鞋小程序究…

libsndfile读取wav文件基本属性

本文的目的是提供一种方法读取wav文件的基本属性&#xff1a;音频帧数&#xff0c;格式、通道数和采样率信息。 代码如下所示&#xff1a; #include <iostream> #include <QDebug> #include "sndfile.h"using namespace std;int main() {// 初始化 ALS…

Gradio

文章目录 关于 Gradio安装InterfaceChatInterface TextBlocksSentence BuilderDiff Texts MediaSepia FilterVideo IdentityIterative OutputGenerate Tone TabularFilter RecordsVideo IdentityIterative OutputGenerate Tone TabularFilter RecordsTranspose MatrixTax Calcu…

C++ 日志库 log4cpp 编译、压测及其范例代码 [全流程手工实践]

文章目录 一、 log4cpp官网二、下载三、编译1.目录结构如下2.configure 编译3.cmake 编译 四、测试五、压测源码及结果1.运行环境信息2.压测源码3.压测结果 文章内容&#xff1a;包含了对其linux上的完整使用流程&#xff0c;下载、编译、安装、测试用例尝试、以及一份自己写好…

20232906 2023-2024-2 《网络与系统攻防技术》第十次作业

20232906 2023-2024-2 《网络与系统攻防技术》第十次作业 1.实验内容 一、SEED SQL注入攻击与防御实验 我们已经创建了一个Web应用程序&#xff0c;并将其托管在http://www.seedlabsqlinjection.com/&#xff08;仅在SEED Ubuntu中可访问&#xff09;。该Web应用程序是一个简…

Qt多文档程序的一种实现

注&#xff1a;文中所列代码质量不高&#xff0c;但不影响演示我的思路 实现思路说明 实现DemoApplication 相当于MFC中CWinAppEx的派生类&#xff0c;暂时没加什么功能。 DemoApplication.h #pragma once#include <QtWidgets/QApplication>//相当于MFC中CWinAppEx的派生…

【Python报错】Python安装模块时报错Fatal error in launcher

【Python报错】Python安装模块时报错Fatal error in launcher 最近需要用到python下载一个小工具&#xff0c;自信敲下回车键本想看到黑乎乎的终端上会出现快速跳跃的命令代码&#xff0c;没想到&#xff0c;报错了...... Fatal error in launcher: Unable to create process …

外卖系统拦截器实现(Interceptor)

SpringMVC的拦截器主要是用于拦截控制器方法的执行&#xff1b; 概念&#xff1a;是一种动态拦截方法调用的机制&#xff0c;类似于过滤器。在Spring中动态拦截控制器中方法的执行。 作用&#xff1a;在指定的控制器中调用前后执行预先设定的代码&#xff0c;完成功能增强。 应…

day08|字符串题目part01

相关题目&#xff1a; ● 344.反转字符串 ● 541. 反转字符串II ● 卡码网&#xff1a;54.替换数字 ● 151.翻转字符串里的单词 ● 卡码网&#xff1a;55.右旋转字符串 344.反转字符串—双指针的应用 力扣链接 思路&#xff1a;创建两个指针分别指向头部和尾部&#xff0c;首…

【JavaEE进阶】 Bean的作用域与生命周期

文章目录 &#x1f343;Bean的作用域&#x1f6a9;作用域的使用&#x1f6a9;观察Bean的作用域&#x1f388;单例作用域&#x1f388;多例作用域&#x1f388;请求作用域&#x1f388;会话作⽤域&#x1f388;Application作⽤域 &#x1f384;Bean的⽣命周期⭕总结 &#x1f34…

Linux 第三十三章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

rocketmq的存储和检索

messageId是rocketmq自动生成的。

JSP+SQL学生成绩管理系统

Java版本&#xff1a;1.8 数据库&#xff1a;MySQL 框架&#xff1a;Spring Spring MVC MyBatis 服务器&#xff1a;Tomcat 前端解析框架&#xff1a;Thymeleaf 开发工具&#xff1a;Idea 2017 版本管理工具&#xff1a;Maven 版本控制工具&#xff1a;GitHub 经过对系统的需…

国际化日期(inti)

我们可以使用国际化API自动的格式化数字或者日期&#xff0c;并且格式化日期或数字的时候是按照各个国家的习惯来进行格式化的&#xff0c;非常的简单&#xff1b; const now new Date(); labelDate.textContent new Intl.DateTimeFormat(zh-CN).format(now);比如说这是按照…