?這是一套拿到手就能直接用的根據(jù)??堤峁┑臄z像機(jī)節(jié)點(diǎn)實(shí)時(shí)預(yù)覽和回放的全步驟代碼,開箱即用。
先點(diǎn)贊后觀看,養(yǎng)成好習(xí)慣。
前言
?我的是基于vue2寫的,vue3可以看我下一篇文章。
?點(diǎn)擊跳轉(zhuǎn)至vue3關(guān)于海康視頻開發(fā)文章。
很多人在開發(fā)vue項(xiàng)目的時(shí)候,不知道怎么去開發(fā)視頻實(shí)時(shí)預(yù)覽和回放功能,然后一直查文檔,再去看別人寫的項(xiàng)目,就是無從下手。這篇文章是我剛開始接觸到這個(gè)項(xiàng)目的時(shí)候從頭到尾寫下來的,功能已經(jīng)實(shí)現(xiàn)希望有用。
一、插件下載與安裝
首先去海康開放平臺(tái)下載??堤峁┑腄emo,這里面有項(xiàng)目需要用到的播放器插件和js文件。
點(diǎn)擊進(jìn)入??甸_放平臺(tái)
我使用的是V1.6.1版本。
然后下載這一個(gè),首次下載需要登錄,沒有的直接手機(jī)號(hào)注冊(cè)一個(gè)就行了。
然后安裝視頻播放插件,如下圖。?
二、使用步驟
?1.引入js
?在vue項(xiàng)目中的public目錄下新建文件夾,把剛才下載好的js復(fù)制到這個(gè)文件夾里面,然后再在public目錄下的index.html文件里面引入sj文件。
?
2.代碼部分
代碼如下(示例):
這里是template部分,只給一個(gè)盒子,然后給個(gè)寬和高就行了,插件會(huì)自適應(yīng)盒子大小和位置的。
ref對(duì)應(yīng)的名字在初始化插件的時(shí)候會(huì)用到。
<div class="videoMain" ref="playWndBox">
<div
id="playWnd"
class="playWnd"
:style="{
height: playWndHeight + 'px',
width: playWndWidth + 'px',
}"
></div>
</div>
這是data里面的數(shù)據(jù),可根據(jù)自己需求修改。
data() {
return {
// 視頻盒子的高度
playWndHeight: "",
// 視頻盒子的寬度
playWndWidth: "",
oWebControl: null,
initCount: 0,
pubKey: "",
cameraIndexCode: "", // 這里面是監(jiān)控點(diǎn)編號(hào)
objData: {
appkey: "", //??灯脚_(tái)提供的appkey
ip: "", //平臺(tái)地址
secret: "", //??灯脚_(tái)提供的secret
port: 443,
playMode: 0, // 0 預(yù)覽 1回放
layout: "1x1", //頁面展示的模塊數(shù)【16】
},
}
},
?這是monted里面的代碼,組件加載后先獲取視頻盒子的高度和寬度
// 首次加載時(shí)的到父容器的高度
this.playWndHeight = this.$refs.playWndBox.clientHeight;
// 首次加載時(shí)的到父容器的寬度
this.playWndWidth = this.$refs.playWndBox.clientWidth;
// 初始化播放器插件
this.$nextTick(() => {
this.initPlugin();
});
// 監(jiān)聽scroll事件,使插件窗口尺寸跟隨DIV窗口變化
window.addEventListener("scroll", () => {
if (this.oWebControl != null) {
this.oWebControl.JS_Resize(
this.$refs.playWndBox.clientWidth,
this.$refs.playWndBox.clientHeight
);
this.setWndCover();
}
});
// 監(jiān)聽resize事件,使插件窗口尺寸跟隨DIV窗口變化
window.addEventListener("resize", (e) => {
if (this.oWebControl != null) {
this.oWebControl.JS_Resize(
this.$refs.playWndBox.clientWidth,
this.$refs.playWndBox.clientHeight
);
this.setWndCover();
}
});
?組件銷毀的時(shí)候要調(diào)用插件銷毀方法,要不然頁面會(huì)有插件殘留。
destroyed () {
if (this.oWebControl != null) {
// 先讓窗口隱藏,規(guī)避可能的插件窗口滯后于瀏覽器消失問題
this.oWebControl.JS_HideWnd();
// 銷毀當(dāng)前播放的視頻
this.oWebControl.JS_RequestInterface({ funcName: "destroyWnd" });
// 斷開與插件服務(wù)連接
this.oWebControl.JS_Disconnect();
}
},
?下面是methods方法里面的函數(shù),自己定義點(diǎn)擊事件函數(shù),把監(jiān)控點(diǎn)編號(hào)發(fā)送到previewVideo(data)函數(shù)里面。前提是得先安裝播放插件!?。?/span>
// 創(chuàng)建播放實(shí)例
initPlugin() {
let that = this;
this.oWebControl = null;
that.oWebControl = new WebControl({
szPluginContainer: "playWnd", // 指定容器id
iServicePortStart: 15900, // 指定起止端口號(hào),建議使用該值
iServicePortEnd: 15909,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: () => {
// 創(chuàng)建WebControl實(shí)例成功
that.oWebControl
.JS_StartService("window", {
// WebControl實(shí)例創(chuàng)建成功后需要啟動(dòng)服務(wù)
// 值"./VideoPluginConnect.dll"寫死
dllPath: "./VideoPluginConnect.dll",
})
.then(
function () {
// 設(shè)置消息回調(diào)
that.oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: that.cbIntegrationCallBack,
});
//JS_CreateWnd創(chuàng)建視頻播放窗口,寬高可設(shè)定
that.oWebControl
.JS_CreateWnd("playWnd", 2040, 945, { bEmbed: true })
//注:2040,945這是我本人項(xiàng)目視頻盒子的大小,你們要根據(jù)自己視頻盒子的大小進(jìn)行修改,不然初始化插件的時(shí)候會(huì)有空白閃爍。
.then(function () {
// 創(chuàng)建播放實(shí)例成功后初始化
that.init();
});
},
function () {
// 啟動(dòng)插件服務(wù)失敗
}
);
},
// 創(chuàng)建WebControl實(shí)例失敗
cbConnectError: function () {
that.oWebControl = null;
// alert('插件未啟動(dòng),正在嘗試啟動(dòng),請(qǐng)稍候...')
// that.$message.warning("插件未啟動(dòng),正在嘗試啟動(dòng),請(qǐng)稍候...");
// 程序未啟動(dòng)時(shí)執(zhí)行error函數(shù),采用wakeup來啟動(dòng)程序
window.WebControl.JS_WakeUp("VideoWebPlugin://");
that.initCount++;
if (that.initCount < 3) {
setTimeout(function () {
that.initPlugin();
}, 3000);
} else {
// that.messageBox = true
// alert('插件啟動(dòng)失敗,請(qǐng)安裝插件并重新啟動(dòng)!')
// that.downloadHikVideo()
// setTimeout(function () {
// that.messageBox = false
// }, 5000)
// setTimeout(function () {
// alert('插件啟動(dòng)失敗,請(qǐng)檢查插件是否安裝!')
// that.$message({
// message: '插件啟動(dòng)失敗,請(qǐng)檢查插件是否安裝! \n 插件下載地址:https://www.baidu.com',
// type: 'warning'
// });
// }, 5000)
}
},
cbConnectClose: () => {
// 異常斷開:bNormalClose = false
// JS_Disconnect正常斷開:bNormalClose = true
// console.log("cbConnectClose");
that.oWebControl = null;
},
});
},
// 初始化
init(callback) {
let that = this;
that.getPubKey(() => {
let appkey = that.objData.appkey; //綜合安防管理平臺(tái)提供的appkey,必填
let secret = that.setEncrypt(that.objData.secret); //綜合安防管理平臺(tái)提供的secret,必填
let ip = that.objData.ip; //綜合安防管理平臺(tái)IP地址,必填
let playMode = that.objData.playMode; //初始播放模式:0-預(yù)覽,1-回放
let port = that.objData.port; //綜合安防管理平臺(tái)端口,若啟用HTTPS協(xié)議,默認(rèn)443
let snapDir = "D:\\SnapDir"; //抓圖存儲(chǔ)路徑
let videoDir = "D:\\VideoDir"; //緊急錄像或錄像剪輯存儲(chǔ)路徑
let layout = that.objData.layout; //playMode指定模式的布局
let enableHTTPS = 1; //是否啟用HTTPS協(xié)議與綜合安防管理平臺(tái)交互,這里總是填1
let encryptedFields = "secret"; //加密字段,默認(rèn)加密領(lǐng)域?yàn)閟ecret
let showToolbar = 1; //是否顯示工具欄,0-不顯示,非0-顯示
let showSmart = 1; //是否顯示智能信息(如配置移動(dòng)偵測(cè)后畫面上的線框),0-不顯示,非0-顯示
let buttonIDs = "0,16,256,257,258,259,260,512,513,514,515,516,517,768,769"; //自定義工具條按鈕
// var toolBarButtonIDs = "2049,2304" // 工具欄上自定義按鈕
that.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, //自定義工具條按鈕
}),
})
.then(function (oData) {
that.oWebControl.JS_Resize(that.playWndWidth, that.playWndHeight); // 初始化后resize一次,規(guī)避firefox下首次顯示窗口后插件窗口未與DIV窗口重合問題
if (callback) {
callback();
}
// 隱藏
// that.oWebControl.JS_HideWnd()
});
});
},
// 獲取公鑰
getPubKey(callback) {
let that = this;
this.oWebControl
.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024,
}),
})
.then(function (oData) {
if (oData.responseMsg.data) {
that.pubKey = oData.responseMsg.data;
callback();
}
});
},
// RSA 加密
setEncrypt(value) {
let that = this;
let encrypt = new window.JSEncrypt();
encrypt.setPublicKey(that.pubKey);
return encrypt.encrypt(value);
},
// 回調(diào)的消息
cbIntegrationCallBack(oData) {
let { responseMsg: type } = oData;
if (type === "error") {
} else {
}
},
// 視頻預(yù)覽功能
previewVideo(data) {
let that = this;
let cameraIndexCode = data; // 獲取輸入的監(jiān)控點(diǎn)編號(hào)值,必填
let streamMode = 0; // 主子碼流標(biāo)識(shí):0-主碼流,1-子碼流
let transMode = 0; // 傳輸協(xié)議:0-UDP,1-TCP
let gpuMode = 0; // 是否啟用GPU硬解,0-不啟用,1-啟用
let wndId = -1; // 播放窗口序號(hào)(在2x2以上布局下可指定播放窗口)
// console.log(cameraIndexCode, "-------cameraIndexCode-");
that.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ù)覽
stopAllPreview() {
this.oWebControl.JS_RequestInterface({
funcName: "stopAllPreview",
});
},
// 格式化時(shí)間
dateFormat(oDate, fmt) {
let o = {
"M+": oDate.getMonth() + 1, //月份
"d+": oDate.getDate(), //日
"h+": oDate.getHours(), //小時(shí)
"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 (let 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;
},
// 設(shè)置窗口裁剪,當(dāng)因滾動(dòng)條滾動(dòng)導(dǎo)致窗口需要被遮住的情況下需要JS_CuttingPartWindow部分窗口
setWndCover() {
var iWidth = $(window).width();
var iHeight = $(window).height();
var oDivRect = $("#playWnd").get(0).getBoundingClientRect();
var iCoverLeft = (oDivRect.left < 0) ? Math.abs(oDivRect.left) : 0;
var iCoverTop = (oDivRect.top < 0) ? Math.abs(oDivRect.top) : 0;
var iCoverRight = (oDivRect.right - iWidth > 0) ? Math.round(oDivRect.right - iWidth) : 0;
var iCoverBottom = (oDivRect.bottom - iHeight > 0) ? Math.round(oDivRect.bottom - iHeight) : 0;
iCoverLeft = (iCoverLeft > 2041) ? 2041 : iCoverLeft;
iCoverTop = (iCoverTop > 945) ? 945 : iCoverTop;
iCoverRight = (iCoverRight > 2041) ? 2041 : iCoverRight;
iCoverBottom = (iCoverBottom > 945) ? 945 : iCoverBottom;
this.oWebControl.JS_RepairPartWindow(0, 0, 2041, 946); // 多1個(gè)像素點(diǎn)防止還原后邊界缺失一個(gè)像素條
if (iCoverLeft != 0) {
this.oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 946);
}
if (iCoverTop != 0) {
this.oWebControl.JS_CuttingPartWindow(0, 0, 2041, iCoverTop); // 多剪掉一個(gè)像素條,防止出現(xiàn)剪掉一部分窗口后出現(xiàn)一個(gè)像素條
}
if (iCoverRight != 0) {
this.oWebControl.JS_CuttingPartWindow(2041 - iCoverRight, 0, iCoverRight, 946);
}
if (iCoverBottom != 0) {
this.oWebControl.JS_CuttingPartWindow(0, 946 - iCoverBottom, 2041, iCoverBottom);
}
},
后期如果需要對(duì)監(jiān)控點(diǎn)位進(jìn)行多窗口預(yù)覽,多窗口預(yù)覽實(shí)現(xiàn)原理是先定義要預(yù)覽的窗口數(shù)量,然后把要調(diào)用的窗口數(shù)據(jù)按照??档母袷竭M(jìn)行存放到數(shù)組里面,在窗口數(shù)量改變之后再統(tǒng)一調(diào)用,下面是我簡(jiǎn)單調(diào)用的不是很牛的例子。
// 對(duì)多點(diǎn)位監(jiān)控監(jiān)控進(jìn)行查看
lookPresetVideoHandler(presetDataArray) {
//這里對(duì)要查看的監(jiān)控點(diǎn)位按照??档母袷竭M(jìn)行封裝
//presetDataArray是我自己監(jiān)控的cameraIndexCode存放的數(shù)組,可按照自己的需求進(jìn)行命名
presetDataArray.forEach((item, index) => {
let NowObj = {
cameraIndexCode: item,
ezvizDirect: 0,
gpuMode: 0,
streamMode: 1,
transMode: 1,
wndId: index + 1,
};
//在data里面創(chuàng)建一個(gè)videoList的數(shù)組
this.videoList.push(NowObj);
});
let VideoListLength = presetDataArray.length;
//利用switch 進(jìn)行判斷窗口的數(shù)量然后來調(diào)用初始化窗口的函數(shù)
switch (true) {
case VideoListLength == 1:
this.objData.layout = "1x1";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 2:
this.objData.layout = "1x2";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 3:
this.objData.layout = "1+2";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 4:
this.objData.layout = "2x2";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 5:
this.objData.layout = "1+5";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 6:
this.objData.layout = "1+5";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 7:
this.objData.layout = "3+4";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 8:
this.objData.layout = "1+7";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 9:
this.objData.layout = "3x3";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 10:
this.objData.layout = "1+9";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 11:
this.objData.layout = "3x4";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 12:
this.objData.layout = "3x4";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 13:
this.objData.layout = "1+12";
this.initLayout(this.objData.layout);
break;
case VideoListLength == 14:
this.objData.layout = "1+1+12";
this.initLayout(this.objData.layout);
break;
}
//這里直接調(diào)用lookVideoListHandler這個(gè)函數(shù)來進(jìn)行多窗口預(yù)覽
this.lookVideoListHandler(this.videoList);
},
//初始化播放窗口
initLayout(data) {
let that = this;
that.oWebControl.JS_RequestInterface({
funcName: "setLayout",
argument: JSON.stringify({ layout: data }),
});
},
//點(diǎn)擊查看監(jiān)控列表監(jiān)控
lookVideoListHandler(data) {
let that = this;
that.oWebControl.JS_RequestInterface({
funcName: "startMultiPreviewByCameraIndexCode",
argument: JSON.stringify({ list: data }),
});
//回調(diào)函數(shù)
// .then(function () {
// that.oWebControl.JS_SetWindowControlCallback({
// cbIntegrationCallBack: function (oData) {
// // let responseMsg = JSON.stringify(oData)
// that.ooooo.push(oData.responseMsg.msg.cameraIndexCode)
// }
// });
// console.log(that.ooooo);
// });
},
?下面是視頻回放功能
//把視頻預(yù)覽中的playMode修改成1,插件就會(huì)自動(dòng)調(diào)用回放功能
// playMode: 1, // 0 預(yù)覽 1回放
//然后點(diǎn)擊事件調(diào)用 backVideo(VideoIndex)這個(gè)函數(shù),可以實(shí)現(xiàn)預(yù)覽功能
// 視頻回放
backVideo(VideoIndex) {
//我這是查詢?nèi)烨暗臄?shù)據(jù),可以根據(jù)直接需求自行修改。
//邏輯可能寫的比較垃圾,我這是寫死的,對(duì)著開發(fā)文檔根據(jù)自己需求修改
let cameraIndexCode = VideoIndex;
let months = new Date().getMonth() + 1
let end = new Date().getFullYear() + '/' + months + '/' + new Date().getDate() + ' 23:59:59'
let endT = String(parseInt(new Date(end).getTime() / 1000));
let star = String(parseInt(new Date(end).getTime() / 1000 - 3 * 24 * 60 * 60))
this.oWebControl.JS_RequestInterface({
funcName: "startPlayback",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode.trim(), // 監(jiān)控點(diǎn)編號(hào)
startTimeStamp: star, // 錄像查詢開始時(shí)間戳,單位:秒
endTimeStamp: endT, // 錄像查詢結(jié)束時(shí)間戳,單位:秒
recordLocation: 0, // 錄像存儲(chǔ)類型 0-中心存儲(chǔ) 1-設(shè)備存儲(chǔ)
transMode: 0, // 傳輸協(xié)議 ,0-UDP 1-TCP
gpuMode: 0, // 是否開啟 GPU 硬解,0-不開啟 1-開啟
wndId: -1 //可指定播放窗口
})
});
},
下面附加上我Gitee的連接
HikDemo:直接點(diǎn)擊進(jìn)入這個(gè)地址,可以拿下來直接使用,里面為可以直接運(yùn)行的demo。https://gitee.com/yyyyong/hik.git文章來源:http://www.zghlxwxcb.cn/news/detail-414186.html
?既然看到最后了,如果感覺對(duì)你有幫助的話,麻煩給點(diǎn)個(gè)贊。
總結(jié)
??甸_發(fā)平臺(tái)只提供了原生JS的語法,這里是vue2的語法,有不懂的可以私信留言。文章來源地址http://www.zghlxwxcb.cn/news/detail-414186.html
到了這里,關(guān)于vue2實(shí)現(xiàn)??低暩鶕?jù)海康插件進(jìn)行監(jiān)控實(shí)時(shí)預(yù)覽和回放功能,全套代碼,開箱即用。的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!