完成的效果是:点击按钮然后弹出所播放的视频
使用的海康web插件:由海康官网下载的视频WEB插件V1.5.2版本,解压完毕后目录如下:
第一步:安装插件
安装在bin文件下面的VideoWebPlugin.exe
第二步:引入必要的文件
在public下面创建文件夹,文件名称可以自己起名字,我这里的是lib下面的js,然后把demo文件下的jquery-1.12.4.min.js、jsencrypt.min.js、web-control_1.2.5.min.js三个文件复制到所创建的文件夹下,最后在public/index.html引入所需要的文件
引入:
<!-- 视频插件 -->
<script src="<%= BASE_URL %>lib/js/jquery-1.12.4.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>lib/js/jsencrypt.min.js" charset="utf-8"></script>
<script src="<%= BASE_URL %>lib/js/web-control_1.2.5.min.js" charset="utf-8"></script>
然后在views下面创建一个vue文件:
父组件:
<template>
<div>
<el-button @click="talkTo()">播放</el-button>
<div v-if="dialogVisible && cameraId"
style="width: 100%;height: 100%;position: absolute;background: transparent;z-index: 1111;"
>
<div style="
width: 2200px;
position: absolute;
top: 23%;
left: 31%;
background-color: #122559;
z-index: 1111;
padding: 0 30px;
">
<div style="color: #fff;font-size: 30px;text-align: right;cursor: pointer;" @click="close()">x</div>
<stationVideo ref="stationVideo" v-show="dialogVisible" :cameraId="cameraId">
</stationVideo>
</div>
</div>
</div>
</template>
<script>
import stationVideo from "./stationVideo"
export default {
components: {
stationVideo
},
data() {
return {
dialogVisible: false,
cameraId: "",//通过接口拿到的每个视频的id
}
},
methods: {
//关闭窗口
close() {
this.dialogVisible = false
this.$refs.stationVideo.hideWindow()
},
talkTo() {
this.dialogVisible = true
}
}
}
</script>
子组件:
<template>
<div style="width: 2200px; height: 1000px">
<div id="playWnd" class="playWnd" style="left: 109px; top: 133px"></div>
</div>
</template>
<script>
export default {
props: ["cameraId"],
data() {
return {
// 插件对象实例,初始化为null,需要创建多个插件窗口时,需要定义多个插件对象实例变量,各个变量唯一标志对应的插件实例
oWebControl: null,
bIE: !!window.ActiveXObject || "ActiveXObject" in window, // 是否为IE浏览器
pubKey: "", // demo中未使用加密,可根据需求参照开发指南自行使用加密功能
initCount: 0,
playMode: 0, // 播放类型,0-预览,1-回放
timer: null,
objData: {
argument: {
authUuid: "",
cameraIndexCode: "",
ezvizDirect: 0,
gpuMode: 0,
streamMode: 0,
transMode: 1,
wndId: -1,
cascade: 1
},
funcName: "startPreview"
}
};
},
mounted() {
this.initPlugin();
setTimeout(()=>{
this.initBtn();
this.UpdatePlayParamValue()
},1000)
},
methods: {
// 创建插件实例,并启动本地服务建立websocket连接,创建插件窗口
initPlugin() {
this.oWebControl = new WebControl({
szPluginContainer: "playWnd",
iServicePortStart: 15900,
iServicePortEnd: 15900,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: () => {
this.initCount = 0;
this.setCallbacks();
this.oWebControl
.JS_StartService("window", {
dllPath: "./VideoPluginConnect.dll",
})
.then(
() => {
this.oWebControl.JS_CreateWnd("playWnd", 2100, 900).then(() => {
console.log("JS_CreateWnd success");
this.oWebControl
.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024,
}),
})
.then((oData) => {
console.log(oData);
if (oData.responseMsg.data) {
this.pubKey = oData.responseMsg.data;
}
});
});
},
() => {}
);
},
cbConnectError: () => {
console.log("cbConnectError");
this.oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
this.initCount++;
if (this.initCount < 3) {
setTimeout(() => {
this.initPlugin();
}, 3000);
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
cbConnectClose: (bNormalClose) => {
// 异常断开:bNormalClose = false
// JS_Disconnect正常断开:bNormalClose = true
console.log("cbConnectClose");
this.oWebControl = null;
$("#playWnd").html("插件未启动,正在尝试启动,请稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://");
this.initCount++;
if (this.initCount < 3) {
setTimeout(() => {
this.initPlugin();
}, 3000);
} else {
$("#playWnd").html("插件启动失败,请检查插件是否安装!");
}
},
});
},
initBtn() {
let param = JSON.stringify({
"argument": {
"appkey": "",
"ip": "",
"port": 443,
"secret": "",
"enableHTTPS": 1,
"language": "zh_CN",
"layout": "1x1",
"playMode": 0,
"reconnectDuration": 5,
"reconnectTimes": 5,
"showSmart": 0,
"showToolbar": 1,
"toolBarButtonIDs": "2048,2049,2050,2304,2306,2305,2307,2308,2309,4096,4608,4097,4099,4098,4609,4100",
"snapDir": "D:/snap",
"videoDir": "D:/video"
},
"funcName": "init"
}, null, 2);
this.isJSON(param);
var JsonParam = JSON.parse(param);
if (!JsonParam.hasOwnProperty("argument")) {
// this.showCBInfo("init failed, param miss argument field");
} else {
if (JsonParam.argument.hasOwnProperty("playMode")) {
this.playMode = JsonParam.argument.playMode;
}
//如果包含加密处理,处理加密字段
if (JsonParam.argument.hasOwnProperty("encryptedFields")) {
var enFields = JsonParam.argument.encryptedFields;
var strArray = new Array();
strArray = enFields.split(",");
for (var i = 0, len = strArray.length; i < len; i++) {
if ("appkey" == strArray[i]) {
if (JsonParam.argument.hasOwnProperty("appkey")) {
var appkey = JsonParam.argument.appkey;
appkey = this.setEncrypt(appkey);
JsonParam.argument.appkey = appkey;
}
}
if ("secret" == strArray[i]) {
if (JsonParam.argument.hasOwnProperty("secret")) {
var secret = JsonParam.argument.secret;
secret = this.setEncrypt(secret);
JsonParam.argument.secret = secret;
}
}
if ("ip" == strArray[i]) {
if (JsonParam.argument.hasOwnProperty("ip")) {
var ip = JsonParam.argument.ip;
ip = this.setEncrypt(ip);
JsonParam.argument.ip = ip;
}
}
if ("snapDir" == strArray[i]) {
if (JsonParam.argument.hasOwnProperty("snapDir")) {
var snapDir = JsonParam.argument.snapDir;
snapDir = this.setEncrypt(snapDir);
JsonParam.argument.snapDir = snapDir;
}
}
if ("layout" == strArray[i]) {
if (JsonParam.argument.hasOwnProperty("layout")) {
var layout = JsonParam.argument.layout;
layout = this.setEncrypt(layout);
JsonParam.argument.layout = layout;
}
}
if ("videoDir" == strArray[i]) {
if (JsonParam.argument.hasOwnProperty("videoDir")) {
var videoDir = JsonParam.argument.videoDir;
videoDir = this.setEncrypt(videoDir);
JsonParam.argument.videoDir = videoDir;
}
}
}
}
//1.4.1及以上版本支持argument字段为json,以下版本argument必须为string
var JsonArgument = JsonParam.argument;
JsonParam.argument = JSON.stringify(JsonArgument);
}
this.oWebControl.JS_RequestInterface(JsonParam).then((oData) => {
console.log(oData);
// this.showCBInfo(JSON.stringify(oData ? oData.responseMsg : ""));
// this.UpdatePlayParamValue();
this.oWebControl.JS_Resize(2100, 900); //
});
},
// 判断字符串是否为json
isJSON(str) {
if (typeof str == "string") {
try {
var obj = JSON.parse(str);
if (typeof obj == "object" && obj) {
return true;
} else {
// this.showCBInfo("param is not the correct JSON message");
return false;
}
} catch (e) {
// this.showCBInfo("param is not the correct JSON message");
return false;
}
}
console.log("It is not a string!");
},
// RSA加密
setEncrypt(value) {
var encrypt = new JSEncrypt();
encrypt.setPublicKey(this.pubKey);
return encrypt.encrypt(value);
},
// 格式化时间
dateFormat(oDate, fmt) {
var o = {
"M+": oDate.getMonth() + 1, //月份
"d+": oDate.getDate(), //日
"h+": oDate.getHours(), //小时
"m+": oDate.getMinutes(), //分
"s+": oDate.getSeconds(), //秒
"q+": Math.floor((oDate.getMonth() + 3) / 3), //季度
S: oDate.getMilliseconds(), //毫秒
};
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
(oDate.getFullYear() + "").substr(4 - RegExp.$1.length)
);
}
for (var k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(
RegExp.$1,
RegExp.$1.length == 1
? o[k]
: ("00" + o[k]).substr(("" + o[k]).length)
);
}
}
return fmt;
},
// 设置窗口控制回调
setCallbacks() {
this.oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: this.cbIntegrationCallBack,
});
},
UpdatePlayParamValue() {
this.objData = {
argument: {
authUuid: "",
cameraIndexCode: this.cameraId,
ezvizDirect: 0,
gpuMode: 0,
streamMode: 0,
transMode: 1,
wndId: -1,
cascade: 1
},
funcName: "startPreview"
}
let param = JSON.stringify(this.objData, null, 2);
this.playBtn(param);
},
playBtn(param) {
this.requestInterface(param);
},
// value为字符串,JS_RequestInterface仅接收json格式的变量,且需要先解析出argument,并且将argument字段的内容转为字符串
requestInterface(value) {
this.isJSON(value);
let JsonParam = JSON.parse(value);
console.log(JsonParam);
let JsonArgument = JsonParam.argument;
JsonParam.argument = JSON.stringify(JsonArgument);
this.oWebControl.JS_RequestInterface(JsonParam).then((oData) => {
console.log(oData);
// this.showCBInfo(JSON.stringify(oData ? oData.responseMsg : ""));
});
},
//隐藏窗口
hideWindow() {
this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
//更新为停止所有播放请求的参数,根据初始化时的playmode字段,设置为预览或回放
this.objData = {
argument: {
authUuid: "",
cameraIndexCode: "",
ezvizDirect: 0,
gpuMode: 0,
streamMode: 0,
transMode: 1,
wndId: -1,
cascade: 1
},
funcName: "stopAllPreview"
}
let param = JSON.stringify(this.objData, null, 2);
this.playBtn(param);
console.log("stopAllPreview success");
}
},
};
</script>
<style scoped>
.playWnd {
width: 2100px;
height: 100%;
/* border: 1px solid red; */
}
.cbInfoDiv {
float: left;
width: 360px;
margin-left: 16px;
border: 1px solid #7f9db9;
}
.cbInfo {
height: 200px;
padding: 5px;
border: 1px solid #7f9db9;
overflow: auto;
word-break: break-all;
}
.operate {
margin-top: 24px;
}
.operate::after {
content: "";
display: block;
clear: both;
}
.operate .btns {
height: 32px;
}
.module {
float: left;
width: 340px;
min-height: 320px;
margin-left: 16px;
padding: 16px 8px;
box-sizing: border-box;
border: 1px solid #e5e5e5;
}
.module .item {
margin-bottom: 4px;
}
.module .label {
width: 150px;
display: inline-block;
vertical-align: middle;
margin-right: 8px;
text-align: right;
}
.module input[type="text"],
.module select {
box-sizing: border-box;
display: inline-block;
vertical-align: middle;
margin-left: 0;
width: 150px;
min-height: 20px;
}
.module .btn {
min-width: 80px;
min-height: 24px;
margin-top: 16px;
margin-left: 158px;
}
/* 弹框风格
.white_content {
display: none;
position: absolute;
top: 25%;
left: 25%;
width: 30%;
height: 30%;
padding: 20px;
border: 3px solid orange;
background-color: white;
z-index:1002;
overflow: auto;
}
*/
.white_content {
display: none;
position: absolute;
top: 80px;
left: 450px;
width: 600px;
height: 300px;
border: 3px solid orange;
background-color: white;
z-index: 1002;
}
</style>
里面的appkey,secret,ip等必要参数需要联系海康的对接人员,摄像头的编号值(cameraIndexCode)这个需要从接口获取
效果图:鼠标hover的时候出现操作栏