1. 下載並安裝海康 web 插件
https://open.hikvision.com/download/5c67f1e2f05948198c909700?type=10
2. 把上一步解壓的三個 js, 複製到你的項目中, 根據路徑, 自己引入到 index.html 中
3. 建議運行它的 demo, 大概看看代碼, 瞭解一下它的大致結構, 它的註解很詳細, 3 分鐘就能看完
4. 貼上我的代碼(我的是每次只顯示一個畫面, 點擊攝像頭切換畫面)
<template>
<!--視頻窗口展示-->
<div id="playWnd" class="playWnd" style="left: 109px; top: 133px;"></div>
</template>
<script>
import publicUtils from "../../utils/publicUtils"; // 我自己的工具類, 可以不要
let divWidth = 500; // 容器寬
let divHeight = 300; // 容器高
//聲明公用變量
let initCount = 0; // 初始化重試次數,3次失敗則報錯
let oWebControl; // 頁面控制對象
let pubKey = '';
export default {
name: 'hkVideo',
data() {
return { // 視頻播放
cameraIndexCode: this.cameraIndexCodeProp, // 攝像頭的code, 我是父頁面傳過來的
}
},
props: ['cameraIndexCodeProp'], // 接收父頁面傳來的攝像頭 code
methods: {
// 創建播放實例, 這裏不用改
initPlugin() { // 初始化播放插件, 相當於準備播放環境(不是重點, 但要記着這是每次加載的第一步, 不然切換畫面會有坑)
const _this = this;
oWebControl = new WebControl({
szPluginContainer: "playWnd", // 指定容器id
iServicePortStart: 15900, // 指定起止端口號,建議使用該值
iServicePortEnd: 15909,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用於IE10使用ActiveX的clsid
cbConnectSuccess: function () { // 創建WebControl實例成功
oWebControl.JS_StartService("window", { // WebControl實例創建成功後需要啓動服務
dllPath: "./VideoPluginConnect.dll" // 值"./VideoPluginConnect.dll"寫死
}).then(function () { // 啓動插件服務成功
oWebControl.JS_SetWindowControlCallback({ // 設置消息回調
cbIntegrationCallBack: _this.cbIntegrationCallBack
});
oWebControl.JS_CreateWnd("playWnd", divWidth, divHeight).then(function () { //JS_CreateWnd創建視頻播放窗口,寬高可設定
_this.init(); // 創建播放實例成功後初始化
});
}, function () { // 啓動插件服務失敗
});
},
cbConnectError: function () { // 創建WebControl實例失敗
oWebControl = null;
publicUtils.notify('warn', "插件未啓動,正在嘗試啓動,請稍候...");
WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未啓動時執行error函數,採用wakeup來啓動程序
initCount++;
if (initCount < 3) {
setTimeout(function () {
this.initPlugin();
}, 3000)
} else {
publicUtils.notify('error', "插件啓動失敗,請檢查插件是否安裝!");
}
},
cbConnectClose: function (bNormalClose) {
// 異常斷開:bNormalClose = false
// JS_Disconnect正常斷開:bNormalClose = true
if (!bNormalClose) {
publicUtils.notify('error', "視屏鏈接異常中斷!");
}
oWebControl = null;
}
});
},
//初始化, 主要改這裏
init() {
const _this = this;
this.getPubKey(function () {
////////////////////////////////// 請自行修改以下變量值 ////////////////////////////////////
let appkey = "你的appkey"; //綜合安防管理平臺提供的appkey,必填
let secret = _this.setEncrypt("你的secret"); //綜合安防管理平臺提供的secret,必填
let ip = "192.168.2.110"; //綜合安防管理平臺IP地址,必填
let playMode = 0; //初始播放模式:0-預覽,1-回放
let port = 443; //綜合安防管理平臺端口,若啓用HTTPS協議,默認443
let snapDir = "D:\\SnapDir"; //抓圖存儲路徑
let videoDir = "D:\\VideoDir"; //緊急錄像或錄像剪輯存儲路徑
let layout = "1x1"; //playMode指定模式的佈局
let enableHTTPS = 1; //是否啓用HTTPS協議與綜合安防管理平臺交互,這裏總是填1
let encryptedFields = 'secret'; //加密字段,默認加密領域爲secret
let showToolbar = 0; //是否顯示工具欄,0-不顯示,非0-顯示
let showSmart = 1; //是否顯示智能信息(如配置移動偵測後畫面上的線框),0-不顯示,非0-顯示
let buttonIDs = ""; //自定義工具條按鈕
////////////////////////////////// 請自行修改以上變量值 ////////////////////////////////////
oWebControl.JS_RequestInterface({
funcName: "init",
argument: JSON.stringify({
appkey: appkey, //API網關提供的appkey
secret: secret, //API網關提供的secret
ip: ip, //API網關IP地址
playMode: playMode, //播放模式(決定顯示預覽還是回放界面)
port: port, //端口
snapDir: snapDir, //抓圖存儲路徑
videoDir: videoDir, //緊急錄像或錄像剪輯存儲路徑
layout: layout, //佈局
enableHTTPS: enableHTTPS, //是否啓用HTTPS協議
encryptedFields: encryptedFields, //加密字段
showToolbar: showToolbar, //是否顯示工具欄
showSmart: showSmart, //是否顯示智能信息
buttonIDs: buttonIDs //自定義工具條按鈕
})
}).then(function (oData) {
oWebControl.JS_Resize(divWidth, divHeight); // 初始化後resize一次,規避firefox下首次顯示窗口後插件窗口未與DIV窗口重合問題
});
});
},
//獲取公鑰, 不用改
getPubKey(callback) {
oWebControl.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
}).then(function (oData) {
console.log(oData);
if (oData.responseMsg.data) {
pubKey = oData.responseMsg.data;
callback()
}
})
},
//RSA加密, 不用改
setEncrypt(value) {
let encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
},
// 設置窗口裁剪,當因滾動條滾動導致窗口需要被遮住的情況下需要JS_CuttingPartWindow部分窗口
setWndCover() {
let iWidth = $(window).width();
let iHeight = $(window).height();
let oDivRect = $("#playWnd").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 > 1000) ? 1000 : iCoverLeft;
iCoverTop = (iCoverTop > 600) ? 600 : iCoverTop;
iCoverRight = (iCoverRight > 1000) ? 1000 : iCoverRight;
iCoverBottom = (iCoverBottom > 600) ? 600 : iCoverBottom;
oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1個像素點防止還原後邊界缺失一個像素條
if (iCoverLeft != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);
}
if (iCoverTop != 0) {
oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一個像素條,防止出現剪掉一部分窗口後出現一個像素條
}
if (iCoverRight != 0) {
oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);
}
if (iCoverBottom != 0) {
oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);
}
},
//視頻預覽功能, 就設置 cameraIndexCode 就行了
startPreview() {
let _this = this;
let cameraIndexCode = _this.cameraIndexCode; //獲取輸入的監控點編號值,必填
let streamMode = 0; //主子碼流標識:0-主碼流,1-子碼流
let transMode = 1; //傳輸協議:0-UDP,1-TCP
let gpuMode = 0; //是否啓用GPU硬解,0-不啓用,1-啓用
let wndId = -1; //播放窗口序號(在2x2以上佈局下可指定播放窗口)
cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");
oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, //監控點編號
streamMode: streamMode, //主子碼流標識
transMode: transMode, //傳輸協議
gpuMode: gpuMode, //是否開啓GPU硬解
wndId: wndId //可指定播放窗口
})
})
},
// 這裏根據你的需要去改, 只加載一次的話, 就放到 mounted 中就行了
initView(){
// 先準備環境, 環境準備好才能加載, 所以給了個延遲, 用 Promise 同步執行, 加載不出來.只能用此下策, 有空再優化
if(this.cameraIndexCode){
this.initPlugin();
setTimeout(this.startPreview, 1000);
}
},
//停止全部預覽
stopAllPreview() {
oWebControl.JS_RequestInterface({
funcName: "stopAllPreview"
})
},
destroyedView(){
if (oWebControl != null) {
this.stopAllPreview();
oWebControl.JS_HideWnd(); // 先讓窗口隱藏,規避可能的插件窗口滯後於瀏覽器消失問題
oWebControl.JS_Disconnect().then(function () { // 斷開與插件服務連接成功
},
function () { // 斷開與插件服務連接失敗
});
}
}
},
mounted() {
// 有攝像頭 code, 才加載, 另外因爲我每次只顯示一個, 所以顯示之前要把之前顯示的攝像頭銷燬, 所以加了 oWebControl == null 的判斷.
if(this.cameraIndexCode && oWebControl == null){
this.initView();
}else{
// 如果 code 不爲空, 則先銷燬現有攝像頭, 再去加載新的攝像頭
this.destroyedView();
setTimeout(this.initView, 1000);
}
},
destroyed() {
this.destroyedView();
}
}
</script>
<style scoped>
html, body {
padding: 0;
margin: 0;
}
.playWnd {
width: 500px; /*播放容器的寬和高設定*/
height: 300px;
}
.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>
5. 父頁面代碼
// key設置的當前時間, 爲了每次點擊都加載新的組件, 避免畫面重疊, 不刷新
<div v-if="hkVideoble" class="visual-background-hkVideo-div">
<hkVideoView :key="timer" v-bind:cameraIndexCodeProp="cameraIndexCode"/>
</div>
// js 方法, 這是在另一個組件裏調的, 就不貼出來了. 就是點擊攝像頭圖片, 觸發這個方法而已
openCamera(e) {
//如果點擊同一個, 則關閉畫面
if(this.cameraIndexCode == e.cameraIndexCode){
this.hkVideoble = false;
this.cameraIndexCode = null;
}else{
this.hkVideoble = true;
this.cameraIndexCode = e.cameraIndexCode;
this.timer = new Date().getTime();
}
}
6. index.html 引用也貼出來吧, 這個應該都會吧
7. 沒了, 希望能幫到你們