以前没有接触过但是公司有这个需求刚好指派给我了只能硬着头皮上了,过程中遇到一些问题也在不断尝试新的方法,因此记录分享一下。(我使用的是3.2版本,3.0版本的用法一致。)
- 去海康开放平台下载开发包
- 解压开发包
- 初始化一个新的vue项目,并在public目录下新建haikang(名字自己取一个就行)目录,将开发包中的文件(图一)复制一份到刚刚新建的haikang目录下(图二)
(图一)
(图二)
- 打开开发包中的demo.html文件(文件位置见图一),拉到最下面可以看到引入的一些js资源(见图二)
(图一)
(图二)
- 打开vue项目中public目录下的index.html页面,对应第4步中的图二将相应的js文件引入到项目中。(注意:jquery文件要在第一行引入,否则会报错)
- 下面就可以开始封装组件了在components目录下新建haikang.vue文件。
- 这里我希望在调用组件的时候进行初始化而不是项目启动的时候,所以我将刚刚引入的demo.js中的一些初始化相关的代码剪切到了组件的mounted函数中。demo中的是需要用户自己输入ip、端口号等登录后才能预览,而我的需求是,不需要用户手动登录打开页面自动登录然后预览,所以在初始化完成后直接调用登录接口,登录成功后再调用预览接口。
- haikang.vue完整代码
<template>
<div class="hello">
<div class="left">
<div :id="'divPlugin_' + index" class="plugin"></div>
</div>
</div>
</template>
<script>
// var g_iWndIndex = 0;
// var version = "websdk3.220191023"
export default {
name: 'HelloWorld',
props: {
szIP: {
type: String, // 摄像头对应ip
},
szPort: {
type: String, // 对应端口
},
szUsername: {
type: String, // 用户名
},
szPassword: {
type: String, // 密码
},
index: {
type: Number, // 调用顺序(后面单独说这个参数的用处)
},
},
data() {
return {};
},
mounted() {
let that = this;
this.$nextTick(() => {
window.WebVideoCtrl.I_InitPlugin(300, 300, {
bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
iPackageType: 2,
//szColorProperty:"plugin-background:0000ff; sub-background:0000ff; sub-border:00ffff; sub-border-select:0000ff", //2:PS 11:MP4
iWndowType: 1,
bNoPlugin: true,
cbInitPluginComplete: function () {
window.WebVideoCtrl.I_InsertOBJECTPlugin('divPlugin_' + that.index);
// 检查插件是否最新
if (-1 == window.WebVideoCtrl.I_CheckPluginVersion()) {
alert(
'检测到新的插件版本,双击开发包目录里的WebComponentsKit.exe升级!'
);
return;
}
},
});
that.login();
});
},
methods: {
login() {
if ('' == this.szIP || '' == this.szPort) {
return;
}
let that = this;
var iRet = window.WebVideoCtrl.I_Login(
this.szIP,
1,
this.szPort,
this.szUsername,
this.szPassword,
{
success: function () {
console.log('登录成功!', that.index);
// that.preView();
setTimeout(() => {
that.preView();
}, that.index * 500);
},
error: function () {
console.log('登录失败!');
},
}
);
if (-1 == iRet) {
console.log('已登录过!');
that.preView();
// setTimeout(() => {
// that.preView();
// }, that.index * 500);
}
},
preView() {
var szDeviceIdentify = this.szIP + '_' + this.szPort;
if (null == szDeviceIdentify) {
return;
}
window.WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
iStreamType: 2,
success: function () {
console.log('开始预览成功!');
},
error: function (status) {
if (403 === status) {
console.log('设备不支持Websocket取流!');
} else {
console.log(window.WebVideoCtrl.I_GetLastError());
console.log(window.WebVideoCtrl.NET_DVR_GetLastError);
console.log('开始预览失败!', status);
}
},
});
},
},
};
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.plugin {
width: 300px;
height: 300px;
}
</style>
- 父组件调用
<haikang
szIP="192.168.3.111" //输入你自己的
szPort="80" //输入你自己的
szUsername="admin" //输入你自己的
szPassword="*****" //输入你自己的
:index="0"
/>
- 到这一步,就完成了组件封装及调用。但是当你直接在终端npm run在浏览器打开后你会发现接口报404,那是因为这个开发包必须使用nginx进行代理下面我们来做这一步。首先打开开发包中的nginx配置文件(如下图)
- 修改配置文件中的ip地址及端口号(图一),保存重启nginx(图二)。
(图一)
(图二)
- 打包vue项目,将生成的dist文件夹放到开发包webs目录下
- 打开浏览器访问
- 最终效果
- 还记得前面封装组件时有一个index参数吗?下面我们来说一下为什么要设置这个参数。
- 上面我们已经实现了单个画面的预览,当我们有多个监控探头都需要预览的时候我们最先想到的肯定是使用v-for循环多次调用haikang组件,事实我也这么做了但是预览失败了(下图)
当我们同时预览两个探头的时候只有第二个预览成功第一个却预览失败了!
-
经过多次调试我发现是因为官方的预览接口它不支持并发,当我们并发去请求接口的时候前面的请求都会被中断只有最后一次请求成功(后来也咨询了他们技术客服得到的答案也是如此)。所以当我们需要预览多个时只能通过定时器去一个一个预览。因此我设置了一个index参数,将父组件for循环中的index传给子组件,这样就可以按照组件调用的顺序去调用接口(目前我测试的结果是每隔0.5秒调用一次是ok的),也就是每隔0.5秒出来一个画面。(具体写法可以看代码)
-
这样虽然可以预览多个画面,但如果有20个监控画面要预览的话就需要10秒才能全部加载出来用户体验非常不好。(我目前也还没有其他解决方案,希望有想法的同学可以分享一下)
- 说明:由于我的需求比较简单只需要打开页面直接预览即可,所以我只用了三个接口:初始化、登录、预览。如果有其他需求用法类似可以参考官方文档。