一唤殴、在index.html文件中引入以下3個(gè)js文件
<!-- 引入阂鹛康插件內(nèi)容 -->
<script type="text/javascript" src="./haikang/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="./haikang/jsencrypt.min.js"></script>
<script type="text/javascript" src="./haikang/jsWebControl-1.0.0.min.js"></script>
image.png
這3個(gè)js文件在官網(wǎng)案例Web插件中有他也提供了案例來進(jìn)行測(cè)試:https://open.hikvision.com/download/5c67f1e2f05948198c909700?type=10
image.png
image.png
二、上代碼探越,將以下代碼封裝成組件在 components下新建/video/monitorVideo.vue(隨意命名)
<template>
<div
id="hikvision-grid"
class="wrapper"
ref="wrapper"
style="width: 100%; height: 100%; clear: both"
>
<div
v-show="oWebControl"
:id="setting.id"
:class="[oWebControl === null ? 'videoNull' : '']"
></div>
<br />
<div v-show="!oWebControl">
<div v-html="playText"></div>
<br />
<div v-show="playText.includes('插件啟動(dòng)失敗')">
下載完成?
<el-button type="primary" @click="destroyedAndCreate">
點(diǎn)擊此處
</el-button>
啟動(dòng)插件
</div>
</div>
</div>
</template>
<script>
export default {
// 從父組件傳遞過來的
props: {
setting: {
// 設(shè)置項(xiàng)窑业,帶id
type: Object,
default: () => ({
id: 1,
}),
},
sysParams: {
// 系統(tǒng)參數(shù)
type: Object,
default: () => ({
appkey: "", // API 網(wǎng)關(guān)提供的 appkey
secret: "", // API 網(wǎng)關(guān)提供的 secret
ip: "", // API 網(wǎng)關(guān) IP 地址
port: ,// API 網(wǎng)關(guān)端口
}),
},
list: {
// cameraCode列表
type: Array,
default: () => [],
},
layout: {
// 布局
type: String,
default: "2x2",
},
},
data() {
return {
videoWidth: 0,
videoHeight: 0,
left: "",
top: "",
initCount: 0, // 啟動(dòng)次數(shù)
playMode: 0, // 0 預(yù)覽 1回放
playText: "加載中...",
cameraIndexCode: "", // 監(jiān)控點(diǎn)編號(hào)
oWebControl: null,
href: "http://124.71.178.44:9000/image/VideoWebPlugin.exe",
selfEle: null, // 自身原始
//設(shè)置窗口遮擋 根據(jù)瀏覽器大小變化視頻插件的大小
iLastCoverLeft: 0,
iLastCoverTop: 0,
iLastCoverRight: 0,
iLastCoverBottom: 0,
};
},
mounted() {
// 當(dāng)前組件
this.selfEle = this.$refs.wrapper;
this.observeWrapper();
// 首次加載時(shí)的到父容器的高度
this.playWndHeight = this.$refs.wrapper.clientHeight;
// 首次加載時(shí)的到父容器的寬度
this.playWndWidth = this.$refs.wrapper.clientWidth;
// 初始化攝像頭
// this.$nextTick(() => {
// this.initPlugin();
// });
// 監(jiān)聽resize事件钦幔,使插件窗口尺寸跟隨DIV窗口變化
window.addEventListener("resize", () => {
if (this.oWebControl != null) {
this.oWebControl.JS_Resize(
this.$refs.wrapper.clientWidth,
this.$refs.wrapper.clientHeight
);
}
});
// 監(jiān)聽滾動(dòng)條scroll事件,使插件窗口跟隨瀏覽器滾動(dòng)而移動(dòng)
window.addEventListener("scroll", () => {
if (this.oWebControl != null) {
this.oWebControl.JS_Resize(
this.$refs.wrapper.clientWidth,
this.$refs.wrapper.clientHeight
);
}
});
},
methods: {
// 監(jiān)聽自身容器大小變化
observeWrapper() {
// 監(jiān)聽 自身容器 元素寬度的變化
const ro = new ResizeObserver((entries) => {
for (const entry of entries) {
const cr = entry.contentRect;
this.videoWidth = cr.width;
this.videoHeight = cr.height;
this.oWebControl &&
this.oWebControl.JS_Resize(this.videoWidth, this.videoHeight);
this.oWebControl && this.setWndCover();
}
});
ro.observe(document.querySelector("#hikvision-grid"));
},
// 初始化+預(yù)覽
createdVideo() {
this.playText = "啟動(dòng)中...";
this.initPlugin(this.setting.id, () => {
this.multiPreviewVideo();
});
},
// 銷毀插件
destroyWnd(cb) {
if (this.oWebControl) {
this.oWebControl.JS_HideWnd();
this.oWebControl
.JS_DestroyWnd({
funcName: "destroyeWnd",
})
.then(function (oData) {});
} else {
console.log("沒有實(shí)例");
}
cb && cb();
},
// 銷毀并重啟
destroyedAndCreate() {
console.log(this.list);
this.destroyWnd(() => {
this.createdVideo();
});
},
// 初始化
init(callback) {
this.getPubKey(() => {
////////////////////////////////// 請(qǐng)自行修改以下變量值 ////////////////////////////////////
let appkey = this.sysParams.appkey; //綜合安防管理平臺(tái)提供的appkey常柄,必填
let secret = this.setEncrypt(this.sysParams.secret); //綜合安防管理平臺(tái)提供的secret鲤氢,必填
let ip = this.sysParams.ip; //綜合安防管理平臺(tái)IP地址,必填
let playMode = this.playMode; //初始播放模式:0-預(yù)覽西潘,1-回放
let port = this.sysParams.port; //綜合安防管理平臺(tái)端口卷玉,若啟用HTTPS協(xié)議,默認(rèn)443
let snapDir = "D:\\SnapDir"; //抓圖存儲(chǔ)路徑
let videoDir = "D:\\VideoDir"; //緊急錄像或錄像剪輯存儲(chǔ)路徑
let layout = this.layout; //playMode指定模式的布局
let enableHTTPS = 1; //是否啟用HTTPS協(xié)議與綜合安防管理平臺(tái)交互喷市,是為1相种,否為0
let encryptedFields = "secret"; //加密字段,默認(rèn)加密領(lǐng)域?yàn)閟ecret
let showToolbar = 0; //是否顯示工具欄品姓,0-不顯示寝并,非0-顯示
let showSmart = 0; //是否顯示智能信息(如配置移動(dòng)偵測(cè)后畫面上的線框),0-不顯示腹备,非0-顯示
let buttonIDs =
"0,16,256,257,258,259,260,512,513,514,515,516,517,768,769"; //自定義工具條按鈕
////////////////////////////////// 請(qǐng)自行修改以上變量值 ////////////////////////////////////
this.oWebControl
.JS_RequestInterface({
funcName: "init",
argument: JSON.stringify({
appkey: appkey, //API網(wǎng)關(guān)提供的appkey
secret: secret, //API網(wǎng)關(guān)提供的secret
ip: ip, //API網(wǎng)關(guān)IP地址
playMode: playMode, //播放模式(決定顯示預(yù)覽還是回放界面)
port: port, //端口
snapDir: snapDir, //抓圖存儲(chǔ)路徑
videoDir: videoDir, //緊急錄像或錄像剪輯存儲(chǔ)路徑
layout: layout, //布局
enableHTTPS: enableHTTPS, //是否啟用HTTPS協(xié)議
encryptedFields: encryptedFields, //加密字段
showToolbar: showToolbar, //是否顯示工具欄
showSmart: showSmart, //是否顯示智能信息
buttonIDs: buttonIDs, //自定義工具條按鈕
}),
})
.then((oData) => {
// 初始化后resize一次食茎,規(guī)避firefox下首次顯示窗口后插件窗口未與DIV窗口重合問題
this.oWebControl.JS_Resize(this.videoWidth, this.videoHeight);
callback && callback();
});
});
},
// 創(chuàng)建播放實(shí)例
initPlugin(id, callback) {
let that = this;
that.oWebControl = new WebControl({
szPluginContainer: id, // 指定容器id
iServicePortStart: 15900, // 指定起止端口號(hào),建議使用該值
iServicePortEnd: 15900,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: function () {
// 創(chuàng)建WebControl實(shí)例成功
that.oWebControl
.JS_StartService("window", {
// WebControl實(shí)例創(chuàng)建成功后需要啟動(dòng)服務(wù)
dllPath: "./VideoPluginConnect.dll", // 值"./VideoPluginConnect.dll"寫死
})
.then(
function () {
// 啟動(dòng)插件服務(wù)成功
that.oWebControl.JS_SetWindowControlCallback({
// 設(shè)置消息回調(diào)
cbIntegrationCallBack: that.cbIntegrationCallBack,
});
that.oWebControl
.JS_CreateWnd(id, that.videoWidth, that.videoHeight)
.then(() => {
//JS_CreateWnd創(chuàng)建視頻播放窗口馏谨,寬高可設(shè)定
that.init(callback); // 創(chuàng)建播放實(shí)例成功后初始化
});
},
function () {
// 啟動(dòng)插件服務(wù)失敗
}
);
},
cbConnectError: () => {
// 創(chuàng)建WebControl實(shí)例失敗
that.oWebControl = null;
that.playText = "插件未啟動(dòng),正在嘗試啟動(dòng)附迷,請(qǐng)稍候...";
WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未啟動(dòng)時(shí)執(zhí)行error函數(shù)惧互,采用wakeup來啟動(dòng)程序
that.initCount++;
if (that.initCount < 3) {
setTimeout(() => {
that.initPlugin();
}, 3000);
} else {
that.playText = `插件啟動(dòng)失敗哎媚,請(qǐng)檢查插件是否安裝!<a href=${this.href} type="primary" download="VideoWebPlugin.exe" style='color:#4194fc'>下載地址</a>`;
}
},
cbConnectClose: (bNormalClose) => {
// 異常斷開:bNormalClose = false
// JS_Disconnect正常斷開:bNormalClose = true
that.oWebControl = null;
},
});
},
// 關(guān)閉
handleClose() {
if (this.oWebControl) {
this.oWebControl.JS_RequestInterface({
funcName: "stopAllPreview",
});
this.oWebControl.JS_HideWnd(); // 先讓窗口隱藏喊儡,規(guī)避可能的插件窗口滯后于瀏覽器消失問題
this.oWebControl.JS_Disconnect().then(
() => {
// 斷開與插件服務(wù)連接成功
},
() => {
// 斷開與插件服務(wù)連接失敗
}
);
this.oWebControl = null;
}
},
// 消息回調(diào)
cbIntegrationCallBack(oData) {
// console.log(oData);
},
// 預(yù)覽
previewVideo() {
let cameraIndexCode = this.cameraIndexCode; // 獲取輸入的監(jiān)控點(diǎn)編號(hào)值拨与,必填
let streamMode = 1; // 主子碼流標(biāo)識(shí):0-主碼流,1-子碼流
let transMode = 1; // 傳輸協(xié)議:0-UDP艾猜,1-TCP
let gpuMode = 0; // 是否啟用GPU硬解买喧,0-不啟用,1-啟用
let wndId = -1; // 播放窗口序號(hào)(在2x2以上布局下可指定播放窗口)
this.oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode.trim(), // 監(jiān)控點(diǎn)編號(hào)
streamMode: streamMode, // 主子碼流標(biāo)識(shí)
transMode: transMode, // 傳輸協(xié)議
gpuMode: gpuMode, // 是否開啟GPU硬解
wndId: wndId, // 可指定播放窗口
}),
});
},
// 批量預(yù)覽
multiPreviewVideo() {
let streamMode = 1; // 主子碼流標(biāo)識(shí):0-主碼流匆赃,1-子碼流
let transMode = 1; // 傳輸協(xié)議:0-UDP淤毛,1-TCP
let gpuMode = 0; // 是否啟用GPU硬解,0-不啟用算柳,1-啟用
this.oWebControl
.JS_RequestInterface({
funcName: "startMultiPreviewByCameraIndexCode",
argument: JSON.stringify({
list: this.list.map((camera, idx) => {
return {
cameraIndexCode: camera, //監(jiān)控點(diǎn)編號(hào)
streamMode, //主子碼流標(biāo)識(shí)
transMode, //傳輸協(xié)議
gpuMode, //是否開啟GPU硬解
wndId: idx + 1, // 播放窗口序號(hào)(在2x2以上布局下可指定播放窗口)
};
}), // 監(jiān)控點(diǎn)編號(hào)集合
}),
})
.then((res) => {
if (res.errorCode === 0) {
console.log("預(yù)覽成功");
}
});
},
//獲取公鑰
getPubKey(callback) {
this.oWebControl
.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024,
}),
})
.then((oData) => {
if (oData.responseMsg.data) {
this.pubKey = oData.responseMsg.data;
callback();
}
});
},
//RSA加密
setEncrypt(value) {
let encrypt = new JSEncrypt();
encrypt.setPublicKey(this.pubKey);
return encrypt.encrypt(value);
},
//設(shè)置窗口遮擋
// setWndCover() {
// let iWidth = document.body.clientWidth;
// let iHeight = document.body.clientHeight;
// let oDivRect = document.getElementById("divPlugin").getBoundingClientRect();
// let iCoverLeft = (oDivRect.left < 0) ? Math.abs(oDivRect.left): 0;
// let iCoverTop = (oDivRect.top < 0) ? Math.abs(oDivRect.top): 0;
// let iCoverRight = (oDivRect.right - iWidth > 0) ? Math.round(oDivRect.right - iWidth) : 0;
// let iCoverBottom = (oDivRect.bottom - iHeight > 0) ? Math.round(oDivRect.bottom - iHeight) : 0;
// iCoverLeft = (iCoverLeft > 700) ? 700 : iCoverLeft;
// iCoverTop = (iCoverTop > 400) ? 400 : iCoverTop;
// iCoverRight = (iCoverRight > 700) ? 700 : iCoverRight;
// iCoverBottom = (iCoverBottom > 400) ? 400 : iCoverBottom;
// if (this.iLastCoverLeft != iCoverLeft) {
// console.log("iCoverLeft: " + iCoverLeft);
// this.iLastCoverLeft = iCoverLeft;
// this.oWebControl.JS_SetWndCover("left", iCoverLeft);
// }
// if (this.iLastCoverTop != iCoverTop) {
// console.log("iCoverTop: " + iCoverTop);
// this.iLastCoverTop = iCoverTop;
// this.oWebControl.JS_SetWndCover("top", iCoverTop);
// }
// if (this.iLastCoverRight != iCoverRight) {
// console.log("iCoverRight: " + iCoverRight);
// this.iLastCoverRight = iCoverRight;
// this.oWebControl.JS_SetWndCover("right", iCoverRight);
// }
// if (this.iLastCoverBottom != iCoverBottom) {
// console.log("iCoverBottom: " + iCoverBottom);
// this.iLastCoverBottom = iCoverBottom;
// this.oWebControl.JS_SetWndCover("bottom", iCoverBottom);
// }
// },
// 設(shè)置窗口裁剪低淡,當(dāng)因滾動(dòng)條滾動(dòng)導(dǎo)致窗口需要被遮住的情況下需要JS_CuttingPartWindow部分窗口
setWndCover() {
let iWidth = $(window).width(); // 獲取瀏覽器寬度 不含滾動(dòng)條
let iHeight = $(window).height();
let oDivRect = $("#" + this.setting.id)
.get(0)
.getBoundingClientRect();
let iCoverLeft = oDivRect.left < 0 ? Math.abs(oDivRect.left) : 0;
let iCoverTop = oDivRect.top < 0 ? Math.abs(oDivRect.top) : 0;
let iCoverRight =
oDivRect.right - iWidth > 0 ? Math.round(oDivRect.right - iWidth) : 0;
let iCoverBottom =
oDivRect.bottom - iHeight > 0
? Math.round(oDivRect.bottom - iHeight)
: 0;
iCoverLeft = iCoverLeft > this.videoWidth ? this.videoWidth : iCoverLeft;
iCoverTop = iCoverTop > this.videoHeight ? this.videoHeight : iCoverTop;
iCoverRight =
iCoverRight > this.videoWidth ? this.videoWidth : iCoverRight;
iCoverBottom =
iCoverBottom > this.videoHeight ? this.videoHeight : iCoverBottom;
// 多1個(gè)像素點(diǎn)防止還原后邊界缺失一個(gè)像素條
this.oWebControl.JS_RepairPartWindow(
0,
0,
this.videoWidth + 1,
this.videoHeight
);
if (iCoverLeft != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
0,
iCoverLeft,
this.videoHeight
);
}
if (iCoverTop != 0) {
// 多剪掉一個(gè)像素條,防止出現(xiàn)剪掉一部分窗口后出現(xiàn)一個(gè)像素條
this.oWebControl.JS_CuttingPartWindow(
0,
0,
this.videoWidth + 1,
iCoverTop
);
}
if (iCoverRight != 0) {
this.oWebControl.JS_CuttingPartWindow(
this.videoWidth - iCoverRight,
0,
iCoverRight,
this.videoHeight
);
}
if (iCoverBottom != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
this.videoHeight - iCoverBottom,
this.videoWidth,
iCoverBottom
);
}
},
},
destroyed() {
this.destroyWnd();
},
watch: {
list: {
immediate: true,
deep: true,
handler(value) {
if (value.length > 0) {
console.log("watch核蚕睿康威視組件的列表list:", value);
this.destroyedAndCreate();
} else {
this.destroyWnd(() => {
this.oWebControl = null;
});
if (value.length === 0) {
this.playText =
"<span style='color:#fff;font-size:27px;'>暫無現(xiàn)場(chǎng)監(jiān)控視頻U崽!!</span>";
} else {
this.playText =
"<span style='color:#fff;font-size:27px;'>現(xiàn)場(chǎng)監(jiān)控暫不可用囱淋,請(qǐng)刷新后再試V砗肌!</span>";
}
}
},
},
"$store.state.videohide"(n, o) {
if (n) {
this.oWebControl.JS_HideWnd();
} else if (!n) {
this.oWebControl.JS_ShowWnd();
}
},
},
};
</script>
<style lang="less" scoped>
.playWnd {
// margin: 30px 0 0 400px;
width: 1000px; /*播放容器的寬和高設(shè)定*/
height: 600px;
border: 1px solid red;
}
.operate {
margin-top: 24px;
}
.operate::after {
content: "";
display: block;
clear: both;
}
.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 input[type="text"] {
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: 100px;
margin-left: 80px;
}
</style>
將這里補(bǔ)充完整即可
image.png
三妥衣、在項(xiàng)目的地方引入組件使用
<div style="width: 1000px; height: 500px">
<monitorVideoVue :list="curShowList"></monitorVideoVue>
</div>
<script>
import monitorVideoVue from "../components/video/monitorVideo.vue";
components: {
monitorVideoVue
},
data(){
videoListAll: [],
curShowList: [], // 當(dāng)前能顯示的攝像頭
},
methods: {
getxxxxxxVideo().then((res) => {
this.videoListAll = res.data;
})
for (let i = 0; i <= 3; i++) { //這里我只拿了4個(gè)索引碼傳過去皂吮,要多少看你們自己
this.curShowList.push(videoListAll[i].cameraIndexCode)
}
}
</script>
如代碼有錯(cuò)誤請(qǐng)糾正
3c420ac57a28589900f57b432ed3dd0.jpg