首言:
通过海康威视的最新web开发包工具进行js调用引入至vue项目中,实现监控设备的对接,监控功能的实现。3.2无插件js库同时支持插件安装的模式。
目录
1、无插件开发包必须使用nginx代理(无论是测试还是生产环境)
一、海康威视开发平台:
网址:https://open.hikvision.com/
可以下载开发包文档,在线咨询客户,需要注册账号使用。
1、下载开发工具包文档
选择对应的开发类型需要的开发包:
进行下载。
2、专家支持在线咨询问题
进行咨询问题
二、3.2无插件开发
1、需要引用的js包
这些是必须引入的。
其中
这三个js需要直接script引入至项目中
其他的只要按照对应的路径复制到项目中,会被其他代码自动加载。
2、开发api
//参数
bNoPlugin: true,//是否启用无插件
//初始化
// 全局保存当前选中窗口
var g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
function initWebKIK() {
//检查浏览器是否支持无插件
if (!WebVideoCtrl.I_SupportNoPlugin()) {
Notification.warning({
title: '提示',
message: "当前浏览器不支持无插件预览监控视频,已自动切换成插件模式,如果还未安装插件请安装",
});
// 检查插件是否已经安装过
const iRet = window.WebVideoCtrl.I_CheckPluginInstall();
if (-1 == iRet) {
Notification.warning({
title: '提示',
message: "您还未安装过插件,请先下载WebComponentsKit.exe双击安装!",
});
return;
}
}
// 初始化插件参数及插入插件
WebVideoCtrl.I_InitPlugin("100%", "100%", {
bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
iPackageType: 2,
//szColorProperty:"plugin-background:0000ff; sub-background:00B2BF; sub-border:e7eaec; sub-border-select:0000ff", //2:PS 11:MP4
iWndowType: 3,
bNoPlugin: true,//是否启用无插件
cbSelWnd: function (xmlDoc) {
g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10);
const szInfo = "当前选择的窗口编号:" + g_iWndIndex;
console.log(szInfo);
},
cbDoubleClickWnd: function (iWndIndex, bFullScreen) {
let szInfo = "当前放大的窗口编号:" + iWndIndex;
if (!bFullScreen) {
szInfo = "当前还原的窗口编号:" + iWndIndex;
}
console.log(szInfo);
},
cbEvent: function (iEventType, iParam1, iParam2) {
if (2 == iEventType) {// 回放正常结束
showCBInfo("窗口" + iParam1 + "回放结束!");
} else if (-1 == iEventType) {
showCBInfo("设备" + iParam1 + "网络错误!");
} else if (3001 == iEventType) {
clickStopRecord(g_szRecordType, iParam1);
}
},
cbRemoteConfig: function () {
console.log("关闭远程配置库!");
},
cbInitPluginComplete: function () {
WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin");
//WebVideoCtrl.I_InsertOBJECTPlugin("divPluginTwo");
// 检查插件是否最新
if (-1 == WebVideoCtrl.I_CheckPluginVersion()) {
Notification.warning({
title: '提示',
message: "检测到新的插件版本,双击WebComponentsKit.exe升级!",
});
return;
}
}
});
}
// 登录
function clickLogin(szIP, szPort, szUsername, szPassword) {
/*
* szIP 设备的 IP 地址或者普通域名(比如花生壳域名)
iPrototocol http 协议,1 表示 http 协议 2 表示 https 协议
iPort 登录设备的 http/https 端口号,根据 iPrototocol 选择传入不同的端口
szUserName 登录用户名称
szPassword 用户密码
options 可选参数对象:
async http 交互方式,true 表示异步,false 表示同步
cgi CGI 协议选择,1 表示 ISAPI,2 表示 PSIA,如果不传这个参数,会
自动选择一种设备支持的协议.
success 成功回调函数,有一个参数,表示返回的 XML 内容。
error 失败回调函数,有两个参数,第一个是 http 状态码,第二个是设
备返回的 XML(可能为空)
* */
var iRet = WebVideoCtrl.I_Login(
szIP,
1,
szPort,
szUsername,
szPassword,
{
success: function (xmlDoc) {
console.log('登录成功')
}, error: function () {
console.log('登录失败!');
}
});
}
//获取数字通道
// 开始预览
function clickStartRealPlay(szIP, iStreamType, iWndIndex, iChannelID) {
console.log("窗口"+iWndIndex+"开始预览");
var iRet = WebVideoCtrl.I_StartRealPlay(szIP, {
//码流类型 1-主码流,2-子码流,默认使用主码流预览
iStreamType: iStreamType,
//播放窗口,如果不传,则默认使用当前选择窗口播放(默认选中窗口 0)
iWndIndex: iWndIndex,
//播放通道号,默认通道 1
iChannelID: iChannelID,
bZeroChannel: false,
success: function () {
console.log("预览成功");
},error: function (status, xmlDoc) {
console.log("预览error");
let szInfo;
if (403 === status) {
szInfo = "设备不支持Websocket取流!";
} else {
szInfo = "开始预览失败!";
}
console.log(szIP + " " + szInfo+xmlDoc);
}
});
}
其他功能详情请见开发文档。
3、注意事项
a、插件初始化的div必须指定宽高度
<div id="divPlugin" class="plugin"></div>
<style scoped>
.plugin{
width:100%;
height:48.7%;
}
</style>
b、同时初始化插件宽高需要指定为100%
函数: I_InitPlugin(szWidth, szHight, options)
功能: 初始化插件的各种属性
参数: szWidth 插件的宽度(单位为”px”, 100%表示撑满插件容器)
szHight 插件的高度(单位为”px”, 100%表示撑满插件容器)
否则则会在高版本浏览器初始化直接显示16个窗口
三、在VUE项目中多个页面引用插件进行监控视频实时显示
1、把初始化过程抽象为一个组件
<template>
<div id="divPlugin" class="plugin"></div>
</template>
<script>
import {Notification} from "element-ui";
export default {
name: "HIKVideo",
data() {
return {
g_iWndIndex: '0',
}
},
props: {
videoIPS: {
type: Object,
default: () => {
}
}
},
methods: {
//初始化
clickInitPlugin(iWndowType) {
this.initWebKIK(iWndowType);
},
// 登录
clickLogin(IPS) {
/*
szIP 设备的 IP 地址或者普通域名(比如花生壳域名)
iPrototocol http 协议,1 表示 http 协议 2 表示 https 协议
iPort 登录设备的 http/https 端口号,根据 iPrototocol 选择传入不同的端口
szUserName 登录用户名称
szPassword 用户密码
options 可选参数对象:
async http 交互方式,true 表示异步,false 表示同步
cgi CGI 协议选择,1 表示 ISAPI,2 表示 PSIA,如果不传这个参数,会
自动选择一种设备支持的协议.
success 成功回调函数,有一个参数,表示返回的 XML 内容。
error 失败回调函数,有两个参数,第一个是 http 状态码,第二个是设
备返回的 XML(可能为空)
*/
let that = this
console.log("设备" + IPS.szIP + ":" + IPS.szPort + "开始登录");
let oWndInfo = that.getWindowStatus(IPS.iWndIndex);
console.log("窗口" + IPS.iWndIndex + "的状态信息:" + JSON.stringify(oWndInfo));
if (oWndInfo !== null) {
//console.log("窗口" + IPS.iWndIndex + "先停止在登录预览!");
that.clickStopRealPlay(IPS);
}
let iRet = WebVideoCtrl.I_Login(
IPS.szIP,
1,
IPS.szPort,
IPS.szUsername,
IPS.szPassword,
{
success: function (xmlDoc) {
console.log('登录成功')
that.clickStartRealPlay(IPS);
}, error: function () {
console.log('登录失败!');
}
});
},
//退出
clickLogout(IPS) {
let iRet = WebVideoCtrl.I_Logout(IPS.szIP);
let szInfo;
if (0 === iRet) {
szInfo = "退出成功!";
} else {
szInfo = "退出失败!";
}
console.log(IPS.szIP + " " + szInfo);
},
// 开始预览
clickStartRealPlay(IPS) {
let that = this;
console.log("设备" + IPS.szIP + ":" + IPS.szPort + "开始预览");
//let oWndInfo = that.getWindowStatus(IPS.iWndIndex);
//console.log("窗口" + IPS.iWndIndex + "的状态信息:" + JSON.stringify(oWndInfo));
//if (oWndInfo == null) {
let iRet = WebVideoCtrl.I_StartRealPlay(IPS.szIP, {
//码流类型 1-主码流,2-子码流,默认使用主码流预览
iStreamType: IPS.iStreamType,
//播放窗口,如果不传,则默认使用当前选择窗口播放(默认选中窗口 0)
iWndIndex: IPS.iWndIndex,
//播放通道号,默认通道 1
iChannelID: IPS.iChannelID,
bZeroChannel: false,
success: function () {
that.$emit('previewSuccess',IPS);
console.log("预览成功");
}, error: function (status, xmlDoc) {
console.log("预览error");
let szInfo;
if (403 === status) {
szInfo = "设备不支持Websocket取流!";
} else {
szInfo = "开始预览失败!";
}
console.log(IPS.szIP + " " + szInfo + xmlDoc);
}
});
//}
},
// 停止预览
clickStopRealPlay(IPS) {
let that = this;
let oWndInfo = that.getWindowStatus(IPS.iWndIndex),
szInfo = "";
console.log("窗口" + IPS.iWndIndex + "的状态信息:" + JSON.stringify(oWndInfo));
if (oWndInfo != null) {
WebVideoCtrl.I_Stop({
iWndIndex: IPS.iWndIndex,
success: function () {
szInfo = "停止预览成功!";
console.log(oWndInfo.szDeviceIdentify + " " + szInfo);
},
error: function () {
szInfo = "停止预览失败!";
console.log(oWndInfo.szDeviceIdentify + " " + szInfo);
}
});
that.clickLogout(IPS);
} else {
console.log("窗口" + IPS.iWndIndex + "已经停止预览");
that.clickLogout(IPS);
}
},
//获取当前窗口的播放信息
getWindowStatus(iWndIndex) {
return WebVideoCtrl.I_GetWindowStatus(iWndIndex);
},
//选中窗口全屏
clickFullScreen() {
WebVideoCtrl.I_FullScreen(true);
},
//初始化
// 全局保存当前选中窗口
//let g_iWndIndex = 0; //可以不用设置这个变量,有窗口参数的接口中,不用传值,开发包会默认使用当前选择窗口
initWebKIK(iWndowType) {
//检查浏览器是否支持无插件
if (!WebVideoCtrl.I_SupportNoPlugin()) {
Notification.warning({
title: '提示',
message: "当前浏览器不支持无插件预览监控视频,已自动切换成插件模式,如果还未安装插件请安装",
});
// 检查插件是否已经安装过
const iRet = window.WebVideoCtrl.I_CheckPluginInstall();
if (-1 == iRet) {
Notification.warning({
title: '提示',
message: "您还未安装过插件,请先下载WebComponentsKit.exe双击安装!",
});
return;
}
}
let that = this;
// 初始化插件参数及插入插件
WebVideoCtrl.I_InitPlugin("100%", "100%", {
//szColorProperty:"plugin-background:0000ff; sub-background:00B2BF; sub-border:e7eaec; sub-border-select:0000ff", //2:PS 11:MP4
iWndowType: iWndowType,
bNoPlugin: true,//是否启用无插件
cbSelWnd: function (xmlDoc) {
that.g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10);
const szInfo = "当前选择的窗口编号:" + that.g_iWndIndex;
console.log(szInfo);
},
cbDoubleClickWnd: function (iWndIndex, bFullScreen) {
let szInfo = "当前放大的窗口编号:" + iWndIndex;
if (!bFullScreen) {
szInfo = "当前还原的窗口编号:" + iWndIndex;
}
console.log(szInfo);
},
cbRemoteConfig: function () {
console.log("关闭远程配置库!");
},
cbInitPluginComplete: function () {
WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin");
// 检查插件是否最新
if (-1 == WebVideoCtrl.I_CheckPluginVersion()) {
Notification.warning({
title: '提示',
message: "检测到新的插件版本,双击WebComponentsKit.exe升级!",
});
return;
}
}
})
},
}
}
export class HIKVideo {
}
</script>
<style scoped>
.plugin {
width: 960px;
height: 540px;
}
</style>
2、在不同页面中进行调用
在VUE中切换页面时需要把上一个页面已登录的设备全部退出,否则下一个页面将无法正常工作,如果有好的解决方法,可以在评论中说明,或者私信我讨论。
<template>
<el-container>
<el-aside>
<div>
<div class="jkxzTit">出口监控显示选择
<el-checkbox :indeterminate="isIndeterminate" v-model="checkAll" @change="handleCheckAllChange" style="margin-left: 10px">全选
</el-checkbox>
</div>
<div>
<el-checkbox-group v-model="checkboxGroup" class="chooseBtn" :max="16">
<el-checkbox-button v-for="(item,index) in cameras" :label="item" :key="index" style="margin: 2px 0">
{{
item.name + (index + 1)
}}#
</el-checkbox-button>
</el-checkbox-group>
</div>
<div style="line-height: 30px;margin-top: 8px;">
<div align="center">
<el-pagination
background
:page-size="16"
@current-change="handleCurrentChange"
layout="prev, pager, next"
:total="this.total"
>
</el-pagination>
</div>
<div align="justify">
<el-button type="primary" :disabled="realPlaySingle" @click="rPA()" style="margin: 10px 0px 10px 10px">单个预览
</el-button>
<el-button type="primary" @click="rPA()">多个预览</el-button>
<el-button type="primary" @click="rPS()">全部停止预览</el-button>
<el-button type="primary" @click="rPF()">放大</el-button>
</div>
</div>
</div>
</el-aside>
<el-main>
<div class="plugin">
<HIKVideo :object="this.objectHIK" ref="hVP" @previewSuccess="pvS"></HIKVideo>
</div>
</el-main>
</el-container>
</template>
<script>
import HIKVideo from "@/components/HIKVideo";
import {listCamera} from "@/api/business/camera";
import {Notification} from "element-ui";
export default {
name: "sc",
components: {HIKVideo},
data() {
return {
realPlaySingle: true,
objectHIK: {
szIP: '192.168.110.164',
szPort: '80',
szUsername: 'admin',
szPassword: 'jz12345678',
iStreamType: 1,
iWndIndex: 0,
iChannelID: 1,
},
isIndeterminate: true,
checkAll: true,
queryCameraParams: {
pageNum: 1,
pageSize: 16,
deviceType: "1"
},
cameras: [],
// 总条数
total: 0,
checkboxGroup: [],
realPlayGroup: [],//预览成功的摄像头
}
},
watch: {
//监听单个预览当选中只有一个时,按钮可以使用
checkboxGroup: function () {
(this.checkboxGroup.length === 1) ? this.realPlaySingle = false : this.realPlaySingle = true;
},
},
mounted() {
this.$refs.hVP.clickInitPlugin(4);
this.dataInit();
},
methods: {
dataInit() {
let that = this
//摄像头的数据
listCamera(this.queryCameraParams).then(response => {
that.cameras = response.rows;
that.total = response.total;
that.checkboxGroup = that.cameras;
that.test();
});
},
//预览
test() {
let a = 0;
for (let camera of this.checkboxGroup) {
setTimeout(() => {
let ips = camera.ip.split(':');
this.objectHIK.szIP = ips[0];
this.objectHIK.szPort = ips[1];
this.objectHIK.szUsername = camera.loginName;
this.objectHIK.szPassword = camera.loginPwd;
this.checkboxGroup.length !== 1 ? this.objectHIK.iWndIndex = a : this.objectHIK.iWndIndex = this.$refs.hVP.g_iWndIndex;
let objectAbc = Object.assign({}, this.objectHIK)
console.log("objectAbc.iWndIndex:" + objectAbc.iWndIndex);
this.$refs.hVP.clickLogin(objectAbc);
a++;
}, 100);
}
},
//f5刷新
f5() {
// location.reload();
this.$router.replace('#/show/sc')
},
//分页当前页码变化时
handleCurrentChange(val) {
this.rPS();
//this.sleep(1000);
this.checkboxGroup =[];
this.queryCameraParams.pageNum = val;
listCamera(this.queryCameraParams).then(response => {
this.cameras = response.rows;
this.checkboxGroup = this.cameras;
this.test();
});
},
//全选
handleCheckAllChange(val) {
this.checkboxGroup = val ? this.cameras : [];
this.isIndeterminate = false;
},
//单个预览/或多个预览
rPA() {
if (this.checkboxGroup.length < 1) Notification.warning({
title: '提示',
message: "至少选中一个才可以预览",
});
this.test();
},
//单个窗口放大
rPF() {
this.$refs.hVP.clickFullScreen(true);
},
//全部停止预览
rPS() {
for (let camera of this.realPlayGroup) {
this.$refs.hVP.clickStopRealPlay(camera);
}
},
//从子组件接收预览成功的摄像头信息
pvS(IPS){
this.realPlayGroup[this.realPlayGroup.length] = IPS;
console.log("realPlayGroup:"+JSON.stringify(this.realPlayGroup));
},
//模拟睡眠
sleep(ms) {
for (let t = Date.now(); Date.now() - t <= ms;) ;
},
//初始化页面时摄像头全部选中
},
}
</script>
<style scoped>
.jkxzTit {
margin: 1vh 0 0 0.625vw;
font-size: 1.7vh;
color: rgb(111, 112, 113);
}
.chooseBtn {
display: flex;
flex-wrap: wrap;
padding-left: 0.52vw;
padding-top: 0.8vh;
}
.plugin {
width: 100%;
height: 806px;
}
</style>
3、效果图
四、其他说明
1、无插件开发包必须使用nginx代理(无论是测试还是生产环境)
2、设备必须要支持webSocket取流
WEB3.2
确认设备是否支持websocket取流方法如下:
可以在高版本谷歌浏览器下输入设备IP地址,登录设备自带的WEB页面,看下能否预览。
如果能够预览的话,检查下任务管理器,是否有启用了localservicecontrol.exe这个进程,把这个进程关闭之后看下能否继续预览。
如果仍旧能够预览,说明设备支持websocket取流;如果不能预览的话,说明设备不支持websocket取流。
在nginx配置文件中server中添加如下配置
location ~ /ISAPI|SDK/ {
if ($http_cookie ~ "webVideoCtrlProxy=(.+)") {
proxy_pass http://$cookie_webVideoCtrlProxy;
break;
}
}
详细其他功能请参照api文档进行开发