萤石云九宫格监控实现流程

  • 说在最前面
    • 将海康录像机添加到萤石云控制台
    • 开始进行开发
      • 代码中所用接口
        • 获取accessToken
        • 获取设备列表
        • 获取摄像头(录像机的通道)列表
        • 获取当前摄像头的监控地址
    • 实现完整代码
    • 展示效果(出于隐私不显示视频)
    • 额外总结
      • 1、上、下、左、右、放大、缩小是用来操作球机或者可以进行操作的摄像机,截图和全屏显示功能均可使用;
      • 2、获取录像机下的通道列表,每一条信息中的`status`为`1`时,代表此通道有摄像机,为`-1`时,代表此通道未连接摄像机;
      • 3、`ipcSerial`字段的说明
      • 4、上面代码说明

说在最前面

本笔记使用的摄像头为海康摄像头,摄像头连接的是海康录像机。小于等于9个摄像机可以直接使用。

将海康录像机添加到萤石云控制台

  • 在萤石云开放平台创建萤石云账号(注册并登录)
    萤石云开放平台链接
  • 进入控制台并进行将设备进行绑定
    1. 进入控制台

    2. 进行认证,不然什么都做不了,企业的比个人的认证要方便一些

    3. 创建应用,创建应用之后就可以看到调用接口所需要的参数,我这里创建的是web应用

    4. 其中后续调用接口所需要的参数appKeyappSecret分别为应用秘钥模块中的AppKeySecret,经常还需要一个accessToken,需要调用接口获取,最好不要用这里的AccessToken,毕竟有一定的有效期

    5. 进行设备绑定
      (1)要在海康平台进行配置,接入的平台为萤石云
      (2)在萤石云的设备列表添加自己的设备,没有添加过是没有设备的。我这里的设备是录像机,添加设备需要的九位设备序列号和设备验证码在设备后面的标签上(添加设备可以根据需求选择使用接口添加)

开始进行开发

  • 安装并引入
    安装:npm install ezuikit-js
    main.js中引入:

    import  EZUIKit from 'ezuikit-js';
    Vue.use(EZUIKit );
    
  • 萤石云接口基址:https://open.ys7.com/
  • 萤石云的请求参数都是formData型数据

代码中所用接口

获取accessToken
 url: '/api/lapp/token/get'type: 'post'data: {appKey: 应用信息页面的appKey,appSecret: 应用信息页面的appSecret}
获取设备列表
 url: '/api/lapp/device/list'type: 'post'data: {accessToken: 获取到的accessToken,pageSize: 每页多少条数据,pageStart: 开始页数}
获取摄像头(录像机的通道)列表
 url: '/api/lapp/device/camera/list'type: 'post'data: {accessToken: 获取到的accessToken,deviceSerial: 设备的序列号}
获取当前摄像头的监控地址
 url: '/api/lapp/v2/live/address/get'type: 'post'data: {accessToken: 获取到的accessToken,deviceSerial: 设备的序列号,channelNo: 当前摄像头在录像机中的通道号}

实现完整代码

<template><div class="main"><div class="app-container"><!-- 左边视频窗口 --><div class="left" id="divPlugin"><div class="hello-ezuikit-js" ref="videoBox"><!-- 最多9格 --><divv-for="item in 9"v-show="(select == 1 && selectVideoFirst == item) ||(select == 2 &&item >= selectVideoFirst &&item < selectVideoFirst + 4) ||select == 3":key="item":class="select == 1 ? 'width' : select == 2 ? 'width2' : 'width3'"style="position:relative;"><!-- 最多16格 --><!-- <divv-for="item in 16"v-show="(select == 1 && selectVideoFirst == item) ||(select == 2 &&item >= selectVideoFirst &&item < selectVideoFirst + 4) ||(select == 3 &&item >= selectVideoFirst &&item < selectVideoFirst + 9) ||select == 4":key="item":class="select == 1? 'width': select == 2? 'width2': select == 3? 'width3': 'width4'"style="position:relative;"> --><div:id="'video-cover' + item"class="video-cover":class="{'video-active': selectVideo == item}"></div><div :id="'video-container' + item"></div></div></div></div><!-- 右边操作区 --><div class="right"><el-inputstyle="width:15.625rem;position: relative;left:1.875rem"placeholder="请输入设备名称"prefix-icon="el-icon-search"v-model="search"clearable></el-input><divv-if="searchList.length"style="width:91%;position: relative;left:1.25rem;height:50%;overflow:auto;top:.3125rem"><divv-for="(camera, index) in searchList"@click="selectCamera2(camera)":key="index":style="cameraList[selectVideo - 1].ipcSerial == camera.ipcSerial? 'color:#0079e0': ''"style="width: 100%;height: 2rem;cursor: pointer"><spanv-if="camera.status"style="width:.5rem;height:.5rem;borderRadius:50%;background:#0cdc8c;display:inline-block;margin-right:.9375rem"></span><spanv-elsestyle="width:.5rem;height:.5rem;borderRadius:50%;background:#aaa;display:inline-block;margin-right:.9375rem"></span>{{ camera.channelName }}</div></div><divv-elsestyle="width:91%;position: relative;left:1.25rem;height:50%;overflow:auto;top:.3125rem"><divv-for="(camera, index) in cameraList"@click="selectCamera(camera, index)":key="index":style="cameraList[selectVideo - 1].ipcSerial == camera.ipcSerial? 'color:#0079e0': ''"style="width: 100%;height: 2rem;cursor: pointer"><spanv-if="camera.status"style="width:.5rem;height:.5rem;borderRadius:50%;background:#0cdc8c;display:inline-block;margin-right:.9375rem"></span><spanv-elsestyle="width:.5rem;height:.5rem;borderRadius:50%;background:#aaa;display:inline-block;margin-right:.9375rem"></span>{{ camera.channelName }}</div></div><div class="btns"><div class="wheel"><div @click="deviceCapture" class="camera"><i class="el-icon-camera"></i></div><div class="top"><div@click="startPTZCtrl('0')"class="triangle triangle-top"></div></div><div class="center"><div class="center-left"><div@click="startPTZCtrl('2')"class="triangle triangle-left"></div></div><div class="center-right"><div@click="startPTZCtrl('3')"class="triangle triangle-right"></div></div></div><div class="bottom"><div@click="startPTZCtrl('1')"class="triangle triangle-bottom"></div></div></div><div class="two-btn"><el-button @click="startPTZCtrl('9')" size="mini" type="primary">-</el-button><el-button @click="startPTZCtrl('8')" size="mini" type="primary">+</el-button></div><el-buttonclass="right-btn"@click="showAllScreen"size="small"type="primary">全屏显示</el-button></div></div></div><!-- 底部切屏按钮 --><div@click="select = 1"style="position: absolute;left:1.875rem;top:94.5vh;cursor: pointer;"><imgclass="rect"v-if="select == 1"src="../../assets/images1/one_1.png"alt/><img class="rect" v-else src="../../assets/images1/one.png" alt /></div><div@click="select = 2"style="position: absolute;left:4rem;top:94.5vh;cursor: pointer;"><imgclass="rect"v-if="select == 2"src="../../assets/images1/four_1.png"alt/><img class="rect" v-else src="../../assets/images1/four.png" alt /></div><div@click="select = 3"style="position: absolute;left:6.125rem;top:94.5vh;cursor: pointer;"><imgclass="rect"v-if="select == 3"src="../../assets/images1/nine_1.png"alt/><img class="rect" v-else src="../../assets/images1/nine.png" alt /></div><!-- <div@click="select = 4"style="position: absolute;left:8.25rem;top:94.5vh;cursor: pointer;"><imgclass="rect"v-if="select == 4"src="../../assets/images1/nine_1.png"alt/><img class="rect" v-else src="../../assets/images1/nine.png" alt /></div> --></div>
</template>
<script>
import EZUIKit from "ezuikit-js";
import axios from "axios";
axios.defaults.baseURL = "/yingshiyun";
export default {name: "Project",data() {return {count: 0,selectPlayer: "", // 选中的监控deviceList: [], // 录像机个数cameraList: [], // 摄像头个数selectChannelNo: 1, // 选中的通道号select: 1, // 选中的网格数accessToken: "", // 用appKey和APPSecret请求回来的tokenselectVideo: 1, // 当前选中的video序号selectVideoFirst: 1,search: "", // 搜索框searchList: []};},created() {},async mounted() {// 获得萤石云的tokenthis.getDeviceToken();},watch: {// 选择显示video数量select(value) {this.select = value;this.cameraList.forEach((item, index) => {if (value == 1) {if (item.code == 200)item.player.reSize(this.$refs.videoBox.offsetWidth,this.$refs.videoBox.offsetHeight);} else if (value == 2) {if (item.code == 200)item.player.reSize(this.$refs.videoBox.offsetWidth / 2 - 2,this.$refs.videoBox.offsetHeight / 2 - 2);} else if (value == 3) {if (item.code == 200)item.player.reSize(this.$refs.videoBox.offsetWidth / 3,this.$refs.videoBox.offsetHeight / 3);}// else {//   if (item.code == 200)//     item.player.reSize(//       this.$refs.videoBox.offsetWidth / 4,//       this.$refs.videoBox.offsetHeight / 4//     );// }});},search(value) {if (value) {this.searchList = this.cameraList.filter(item => item.channelName.indexOf(value) > -1);} else {this.searchList = [];}}},beforeDestroy() {this.players.forEach(item => {item.stop();});},methods: {// 获取tokenasync getDeviceToken() {const data = new FormData();data.append("appKey", "萤石云账户的appKey");data.append("appSecret", "萤石云账户的appSecret");var res = await axios({headers: {"Content-Type": "application/x-www-form-urlencoded"},method: "post",url: "/api/lapp/token/get",data: data});if (res.data.code == 200) {this.accessToken = res.data.data.accessToken;// TODO:deviceList(设备列表)需要利用获取设备列表接口获取if (this.deviceList.length) {this.deviceList.forEach(item => {this.getChannelList(item);});}}},// 获取摄像头(通道)列表async getChannelList(device) {const data = new FormData();data.append("accessToken", this.accessToken);data.append("deviceSerial", device.deviceSerial);var res = await axios({headers: {"Content-Type": "application/x-www-form-urlencoded"},method: "post",url: "/api/lapp/device/camera/list",data: data});this.count++;if (res.data.code == 200) {var canUseList = [];canUseList = res.data.data.filter(item => item.deviceSerial != item.ipcSerial);this.cameraList = [...this.cameraList, ...canUseList];if (this.count >= this.deviceList.length) {this.cameraList.forEach((item, index) => {this.getEzuikitUrl(item, index);});this.selectPlayer = this.cameraList[0];}}},// 获取监控地址async getEzuikitUrl(item, index, select) {const data = new FormData();data.append("accessToken", this.accessToken);data.append("deviceSerial", item.deviceSerial);data.append("channelNo", item.channelNo);var res = await axios({headers: {"Content-Type": "application/x-www-form-urlencoded"},url: "/api/lapp/v2/live/address/get",method: "post",data: data});if (res.data.code == 200) {var url = res.data.data.url;item.url = url;item.code = 200;item.msg = res.data.msg;// 渲染视频播放this.StructureEZUIKitPlayer(url, item, index, select);} else {var ref = document.querySelector("#video-cover" + (index + 1));ref.innerText = res.data.msg;}this.$set(this.cameraList, index, item);},// 渲染视频播放StructureEZUIKitPlayer(url, item, index, select) {if (select) {var player = new EZUIKit.EZUIKitPlayer({autoplay: false,audio: "0",id: "video-container", // 视频容器IDaccessToken: this.accessToken,url: url, // 初始化写死一个离线或者找不到的设备,避免初始化无法创建播放器;template: "simple",width: this.$refs.videoBox.offsetWidth / 3,height: this.$refs.videoBox.offsetHeight / 3});this.selectPlayer.player = player;} else {var player = new EZUIKit.EZUIKitPlayer({autoplay: false,audio: "0",id: `video-container${index + 1}`, // 视频容器IDaccessToken: this.accessToken,url: url, // 初始化写死一个离线或者找不到的设备,避免初始化无法创建播放器;template: "simple",width: this.$refs.videoBox.offsetWidth / 3,height: this.$refs.videoBox.offsetHeight / 3});item.player = player;}this.select = 3;},// 开始云台控制async startPTZCtrl(direction) {// 放大缩小:8 放大 9 缩小// 方向:0-上,1-下,2-左,3-右,4-左上,5-左下,6-右上,7-右下const data = new FormData();data.append("accessToken", this.accessToken);data.append("deviceSerial", this.selectPlayer.deviceSerial);data.append("channelNo", this.selectPlayer.channelNo);data.append("direction", direction);data.append("speed", "1");var res = await axios({headers: {"Content-Type": "application/x-www-form-urlencoded"},method: "post",url: "/api/lapp/device/ptz/start",data: data});if (res.data.code != 200) {this.$message(res.data.msg);} else {this.stopPTZCtrl(direction);}},// 停止云台控制async stopPTZCtrl() {const data = new FormData();data.append("accessToken", this.accessToken);data.append("deviceSerial", this.selectPlayer.deviceSerial);data.append("channelNo", this.selectPlayer.channelNo);data.append("direction", "0");var res = await axios({headers: {"Content-Type": "application/x-www-form-urlencoded"},method: "post",url: "/api/lapp/device/ptz/stop",data: data});this.$message(res.data.msg);},// 设备抓拍图片async deviceCapture() {this.cameraList[this.selectVideo - 1].player.capturePicture();},// 全屏显示showAllScreen() {this.cameraList[this.selectVideo - 1].player.cancelFullScreen();this.cameraList[this.selectVideo - 1].player.fullScreen();},selectCamera(item, index) {this.selectPlayer = item;this.selectVideo = index + 1;this.selectVideoFirst = index + 1;},selectCamera2(camera) {var index = this.cameraList.findIndex(item => item.ipcSerial == camera.ipcSerial);this.selectPlayer = item;this.selectVideo = index + 1;this.selectVideoFirst = index + 1;}}
};
</script>
<style lang="scss" scoped>
.main {position: fixed;.app-container {width: 94.375rem;height: 71vh;// border: .125rem solid rgb(116, 228, 24);left: 1.875rem;background-color: rgb(255, 255, 255);margin: 0rem auto;position: relative;top: 13.125rem;// border-radius:.625rem;overflow: hidden;.left {overflow: hidden;width: 80%;border: 0.125rem solid rgb(226, 181, 33);height: 100%;position: absolute;left: 0;top: 0rem;.title {position: absolute;top: 1rem;left: 0.75rem;font-size: 1rem;font-weight: 600;color: #000;}.time {position: absolute;top: 1rem;right: 1.25rem;font-size: 1rem;font-weight: 600;color: #000;}}.left1 {width: 80%;border: 0.125rem solid rgb(37, 43, 102);height: 100%;top: 0rem;position: absolute;left: 0;overflow: hidden;}.left2 {top: 0rem;width: 80%;border: 0.125rem solid rgb(37, 43, 102);height: 100%;position: absolute;overflow: hidden;left: 0;}.right {display: flex;flex-direction: column;justify-content: space-between;background: rgb(255, 255, 255);width: 20%;height: 100%;top: 0;// border: .0625rem solid rgb(22, 21, 27);position: absolute;right: 0;.right1 {width: 100%;text-align: start;line-height: 2.5rem;color: #6e727a;margin: 0.3125rem auto;height: 2.5rem;padding: 0 1.25rem;cursor: pointer;}.right1:hover {background: #1393fc;color: rgb(255, 255, 255);border: none;}.right2 {width: 100%;padding: 0 1.25rem;height: 2.5rem;margin: 0.3125rem auto;line-height: 2.5rem;background: #1393fc;color: rgb(255, 255, 255);cursor: pointer;}}}
}.hello-ezuikit-js {width: 100%;height: 100%;display: flex;flex-wrap: wrap;overflow: hidden;background: #ccc;
}.width {width: 100%;height: 100%;
}.width2 {width: 50%;height: 50%;
}.width3 {width: 33.3%;height: 33.3%;
}.width4 {width: 25%;height: 25%;
}.video-active {border: 0.125rem solid rgb(255, 133, 62) !important;
}.rect {width: 1.625rem;height: 1.625rem;
}.video-cover {display: flex;justify-content: center;align-items: center;font-size: 12px;color: rgb(153, 0, 0);position: absolute;top: 0;left: 0;width: 100%;height: 100%;z-index: 5;border-top: 0.0313rem solid #fff;border-right: 0.0313rem solid #fff;
}::v-deep .el-dialog__wrapper {display: flex;justify-content: center;align-items: center;
}::v-deep .el-dialog__header {background: #efefef;
}::v-deep .el-dialog {width: 36rem;
}::v-deep .el-dialog__body {padding-top: 3.75rem;display: flex;justify-content: center;
}::v-deep .el-form {width: 28.125rem;
}::v-deep .el-form-item__label {width: 6.875rem !important;
}::v-deep .el-input {width: 20rem;
}.tabs {width: 100%;height: 2.4375rem;display: flex;position: absolute;top: 3.375rem;left: 0;border-top: 1px solid #ccc;.tab-item {width: 50%;height: 100%;display: flex;justify-content: center;align-items: center;}.tab-active {background: #ccc;color: #fff;}
}.wheel {position: relative;width: 9.375rem;height: 9.375rem;border-radius: 50%;background: rgb(77, 77, 77);.camera {position: absolute;left: 3.75rem;top: 3.75rem;z-index: 5;width: 1.875rem;height: 1.875rem;text-align: center;line-height: 1.875rem;font-size: 1.25rem;color: #fff;cursor: pointer;}.top {height: 33.3%;display: flex;justify-content: center;align-items: center;}.center {height: 33.3%;display: flex;justify-content: space-between;align-items: center;.center-left,.center-right {width: 33.3%;display: flex;justify-content: center;}}.bottom {height: 33.3%;display: flex;justify-content: center;align-items: center;}.triangle {width: 0;height: 0;border: 0.625rem solid transparent;cursor: pointer;}.triangle-top {border-bottom: 0.9375rem solid #fff;}.triangle-bottom {border-top: 0.9375rem solid #fff;}.triangle-left {border-right: 0.9375rem solid #fff;}.triangle-right {border-left: 0.9375rem solid #fff;}
}.bg-black {display: flex;justify-content: center;align-items: center;background: #000;color: rgb(151, 0, 0);font-size: 12px;
}.btns {display: flex;flex-direction: column;align-items: center;.two-btn {width: 11.25rem;margin: 0.9375rem auto;.el-button {width: 50%;margin: 0;}}
}::v-deep .el-button {background: rgb(77, 77, 77);border-color: rgb(77, 77, 77);
}::v-deep .el-button.right-btn {width: 11.25rem;margin: 0 auto 0.625rem;
}
</style>

展示效果(出于隐私不显示视频)



额外总结

1、上、下、左、右、放大、缩小是用来操作球机或者可以进行操作的摄像机,截图和全屏显示功能均可使用;
2、获取录像机下的通道列表,每一条信息中的status1时,代表此通道有摄像机,为-1时,代表此通道未连接摄像机;
3、ipcSerial字段的说明

利用设备序列号获取通道列表时:
(1)status字段为1时,且ipcSerialdeviceSerial相同时,代表当前设备是直连的摄像头,摄像头的;
(2)status字段为-1时,且ipcSerialdeviceSerial相同时,代表此通道未连接摄像机,连接萤石云的设备为硬盘录像机;

4、上面代码说明

(1)因为我的设备使用接口添加的,设备列表数据库存了一份,所以应用中没有使用接口获取设备列表;
(2)代码中判断当前通道是否接入摄像头是判断ipcSerialdeviceSerial是否相等;如果萤石云直接连的摄像头,需要改变判断方式;
(3)代码中注掉的部分是16格视频,使用16格视频时需要解除注释,渲染视频播放方法中的this.select=4,宽高比也应为/4

基于萤石云实现的九宫格监控相关推荐

  1. EasyCVR平台基于萤石云SDK接入的设备播放流程及接口调用

    EasyCVR视频融合云服务支持海量视频汇聚与管理.处理与分发.智能分析等视频能力,在功能上,可支持视频监控直播.云端录像.云存储.录像检索与回看.智能告警.平台级联.服务器集群等.EasyCVR平台 ...

  2. 萤石云好友分享的监控怎么看_助力开学季丨萤石云APP新增群组分享功能、扩容优惠套餐!...

    开学季 萤石云新功能上线 又是一年忙碌充实的开学季,小小少年们又回到了学校,萤石幼儿园校长却多了份幸福的烦恼:宝爸宝妈们都想看自家孩子的上课录像,可每次只能跨过班主任直接向校长申请:小班的同学座位升到 ...

  3. 萤石云好友分享的监控怎么看_萤石S1:英超赛场上雄起的中国品牌

    北京时间4月26日20:30,英超2014/15赛季第34轮,曼联客场0比3不敌埃弗顿,麦卡锡.斯通斯和米拉拉斯先后进球.曼联在连败的情况下积分榜跌至第四.后弗格森时代的曼联最近刚刚有点起色,似乎这场 ...

  4. 萤石云平台接入_前端接入监控视频

    简介 在可视化平台的展示中,监控视频可能是不可或缺的一部分.由于屏幕的尺寸限制,监控视频在可视化平台中占比不大,但是对于设计到实物的企业来说,监控视频在可视化平台中的展现是必不可少的一部分. 海康威视 ...

  5. 怎么查看表用了那个序列_知识分享008:怎样在手机上用萤石云查看海康威视监控录像...

    问题描述: 现在监控系统越来越普及了,很多公司和个人都会安装.在公司内部,可以通过直接到监控主机那里,或者通过网页来查看.到了外面,也可以通过手机软件来查看监控录像. 对于监控系统,我们推荐海康威视的 ...

  6. 京东如何建设基于云原生架构的监控 - 日志系统?

    在这个人人都谈"云原生"的时代,企业在建设内部相关系统时常常会优先考虑云原生架构.那么,云原生架构的系统与传统架构系统有什么不同?又该如何建设呢?本文我们邀请京东架构师韩超老师分享 ...

  7. 基于阿里云生态构建网聚宝业务监控系统

    伊始 -- 网聚宝业务监控系统 今年网聚宝开始推进服务化进程,我有幸分在架构组,在公司产品服务化的过程中负责业务监控模块.在以前,我们发展工程还未服务化的时候,我们可能只单单关注单个请求的耗时等基本指 ...

  8. vue 接入萤石云,实现监控、多窗口监控、转向、放大缩小等

    准备资料:文档概述 · 萤石开放平台API文档 vue 萤石云视频监控对接_谭CV的博客-CSDN博客_萤石云vue 1.接入萤石云 npm i ezuikit npm i ezuikit-js@0. ...

  9. html实现ezuikit.js萤石云直播监控,ezuikit.js实时监控实现,萤石云实时监控简单实现

    效果图 实现 下面方式一的播放url获取:登录萤石云->控制台->我的资源->设备列表->列表中:查看通道->监控地址 下面方式二的播放url获取:登录萤石云->控 ...

最新文章

  1. 使用Teams接收Azure服务运行状况通知
  2. hashmap 扩容是元素还是数组_HashMap的扩容机制---resize()
  3. oracle的结构是什么,Oracle的软件结构是什么呢?
  4. 【Python】向函数传递列表
  5. 【重温基础】7.时间对象
  6. Python黑魔法,一行实现并行化
  7. 定时任务的实现原理,看完就能手撸一个!
  8. KBMMW 4.81.00 发布
  9. C语言课后习题(37)
  10. 很特别的一个动态规划入门教程
  11. mysql 同义词_数据库中的同义词synonym
  12. element技巧之element的dialog弹出框可拖拽、可拉伸、可全屏并处理边界问题
  13. 野火PID上位机通信移植
  14. perl统计日志文件ip及数量
  15. 学会OpenStack之核心Nova服务一篇就够了!!!
  16. Teigha4.0加载显示Dwg文件
  17. jsp作业--计算矩形、圆形面积
  18. qrcode生成固定大小的二维码
  19. 枚举的练习、声明一个枚举类型Status, Status(员工状态),可以限定为4个:空闲(Free),忙(Busy),休假(Vocation),离职(Left)
  20. 启动马达接线实物图_软启动器怎么接线?一张电路图一张实物图供大家参考

热门文章

  1. 类office2007工具栏
  2. linux下网络收音机,基于嵌入式Linux的流媒体网络收音机系统的设计与研究
  3. 【坎坷求职路】:选择大于努力!一名六次反复经历失败的应届生,最后一刻跻身阿里如愿以偿
  4. 关于2023年软件测试的5大趋势探讨
  5. 融云Java服务端(好友、群组)
  6. WordPress主题添加鼠标点击特效
  7. 终于,还是用Python向喜马拉雅动手了
  8. spring(转账为例)四种实现方式一
  9. 求职OMG——大学生就业指导与技能开发 第二章测试
  10. 计算机语言学专业排名,语言学专业排名