一、環(huán)境準(zhǔn)備
下載地址:??低暪倬W(wǎng)
下載頁(yè)面
文件解壓后的目錄
運(yùn)行bin文件下的VideoWebPlugin.exe
二、插件demo測(cè)試
demo/demo_window_integration.html 包含了插件所有功能的,可參照此demo來(lái)開發(fā)、驗(yàn)證功能、排查問題
demo/demo_window_simple_playback.html.html? 視頻回放,可在此基礎(chǔ)上二次開發(fā)
demo/demo_window_simple_preview.html 實(shí)時(shí)預(yù)覽,可在基礎(chǔ)上二次開發(fā)
在瀏覽器中打開?demo/demo_window_integration.html?文件如下
?在進(jìn)入官網(wǎng)運(yùn)行管理平臺(tái)獲取到 Appkey、AppSecret、Ip、Port,就能連接到自己的攝像頭進(jìn)行調(diào)試開發(fā)了
三、api相關(guān)介紹
1、JS_StartService(szType,options)?啟動(dòng)插件服務(wù)接口 (返回值Promise)
????????szType:服務(wù)類型?固定填充 “window”(必填)
????????options:可選參數(shù)對(duì)象?固定填充{dllPath: "./VideoPluginConnect.dll"}(對(duì)象選填)
2、JS_Disconnect() 斷開服務(wù)接口 (返回值Promise)
3、JS_CreateWnd(szId, iWidth, iHeight)?創(chuàng)建插件窗口接口?(返回值Promise)
????????szId:父窗口的id?(必填)
????????iWidth:元素 ID 標(biāo)識(shí)窗口的寬度?(必填)
????????iHeight:元素 ID 標(biāo)識(shí)窗口的高度?(必填)
4、JS_SetWindowControlCallback(callback)?設(shè)置消息回調(diào)接口
? ? ? ?callback(對(duì)象 必填) 示例
? ? ? ?{
????????????????cbIntegrationCallBack(必要屬性): function(oData){ // oData 是封裝的視頻 web 插件回調(diào)消息的消息體
????????????????console.log(JSON.stringify(oData)); // 打印消息體至控制臺(tái)
???????? }
5、JS_Resize(iWidth,iHeight)?調(diào)整插件窗口大小、位置接口
????????iWidth:DIV 窗口寬度 (必填)
????????iHeight:DIV 窗口高度(必填)
6、JS_CuttingPartWindow(iLeft, iTop, iWidth, iHeight)?扣除部分插件窗口接口
? ? ? ? 場(chǎng)景:插件窗口創(chuàng)建后,會(huì)始終置頂,因此當(dāng)和其它組件一同使用時(shí),會(huì)遮擋其它組件內(nèi)容,該接口 的作用是,當(dāng)部分插件窗口不需要置頂時(shí),我們會(huì)隱藏部分插件窗口。也就是向上滾動(dòng)的時(shí)候會(huì)隱藏
????????iLeft:距離插件窗口左邊距(必填)
????????iTop:距離插件窗口上邊距(必填)
????????iWidth:需要扣除的寬度(必填)
????????iHeight:需要扣除的高度(必填)
7、JS_RepairPartWindow(iLeft, iTop, iWidth, iHeight) 還原扣除部分窗口后的插件窗口
? ? ? ? 場(chǎng)景:一般聯(lián)合?JS_CuttingPartWindow 一起使用,在還原部分窗口后 在扣除
????????iLeft:扣除窗口的頂點(diǎn)距離插件窗 口左邊距?(必填)
????????iTop:扣除窗口的頂點(diǎn)距離插件窗 口上邊距?(必填)
????????iWidth:扣除窗口的寬度(必填)
????????iHeight:扣除窗口的高度(必填)
8、JS_HideWnd()?插件窗口隱藏接口
9、JS_ShowWnd() 插件窗口顯示接口
10、JS_DestroyWnd()?插件窗口銷毀接口
11、JS_WakeUp(szProtocal)?喚醒 WebControl.exe 接口
? ? ? ? 場(chǎng)景 當(dāng) WebControl.exe 未啟動(dòng)時(shí)喚醒 WebControl.exe。若 WebControl.exe 已啟動(dòng)則忽略
????????szProtocal:?jiǎn)拘褏f(xié)議 內(nèi)容固定為("VideoWebPlugin://")
12、JS_RequestInterface({funcName,argument})通過(guò)請(qǐng)求響應(yīng)接口?(返回值Promise)
????????funcName:功能標(biāo)識(shí)(必填)
? ? ? ??argument:功能參數(shù) (object 格式的字符串)
- 例?申請(qǐng) RSA 公鑰
?{ funcName: "getRSAPubKey", argument: "{ keyLength: 1024 }" }
- 初始化? ??
{
funcName: "init",
argument: "{
appkey: "afsgnhmj34567dgh", // API 網(wǎng)關(guān)提供的 appkey
secret: "vgkk3g0jaoj0igoigj", // API 網(wǎng)關(guān)提供的 secret
ip: "10.33.31.4", // API 網(wǎng)關(guān) IP 地址
port: 9016, // API 網(wǎng)關(guān)端口
playMode: 0, //播放模式(決定顯示預(yù)覽還是回放界面),0-預(yù)覽 1-錄像播放
encryptedFields: "appkey,secret", //secret 和 appkey 已加密,對(duì)多個(gè)字段加密存在初始化耗時(shí)問題
snapDir: "D:\SnapDir", // 抓圖存儲(chǔ)路徑
layout: "2x2" // 初始化 2x2 布局
showToolbar: 1, // 顯示工具欄
showIntelligent: 1, // 顯示智能信息
buttonIDs: "0,16,256,257,258"
}"
}
- 根據(jù)監(jiān)控點(diǎn)編號(hào)視頻預(yù)覽
{
funcName: "startPreview",
argument: "{
cameraIndexCode: "afsgnhmj34567dgh", // 監(jiān)控點(diǎn)編號(hào)
streamMode: 0, // 主子碼流標(biāo)識(shí),0-主碼流 1-子碼流
transMode: 1, // 傳輸協(xié)議,0-UDP 1-TCP
gpuMode: 0 // 是否開啟 GPU 硬解,不建議開啟,0-不開啟 1-開啟
}"
}
- 停止所有視頻預(yù)覽
{
funcName: "stopAllPreview"
}
- 根據(jù)監(jiān)控點(diǎn)編號(hào)錄像回放
{
funcName: "startPlayback",
argument: "{
cameraIndexCode: "afsgnhmj34567dgh", // 監(jiān)控點(diǎn)編號(hào)
startTimeStamp: "10237898985", // 錄像查詢開始時(shí)間戳,單位:秒
endTimeStamp: "10237899985", // 錄像查詢結(jié)束時(shí)間戳,單位:秒
recordLocation: 0, // 錄像存儲(chǔ)類型 0-中心存儲(chǔ) 1-設(shè)備存儲(chǔ)
transMode: 1, // 傳輸協(xié)議 ,0-UDP 1-TCP
gpuMode: 0 // 是否開啟 GPU 硬解,0-不開啟 1-開啟
}"
}
- 停止所有錄像回放
{
funcName: "stopAllPlayback"
}
- 銷毀播放實(shí)例
{
funcName: "destroyWnd"
}
- ?獲取當(dāng)前布局
{
funcName: "getLayout"
}
- 設(shè)置當(dāng)前布局?
{
funcName: " setLayout",
argument: "{
layout: "2x2" // 窗口布局
}"
}
// 布局可選值有“1x1”、
“2x2”、“3x3”、“4x4”、“5x5”、“1x2”、
“1+2”、“1+5”、“1+7”、 “1+8”、“1+9”、
“1+12”、“1+16”、“4+9”、“1+1+12”、
“3+4”、“1x4”、“4x6”
- 畫面字符疊加
{
"funcName": "drawOSD",
"argument": "{
text: "溫度:50\n 濕度:38", // 窗口布局
x: 5, // 相對(duì)播放窗口左上角的橫坐標(biāo)起點(diǎn)
y: 5, // 相對(duì)播放窗口左上角的縱坐標(biāo)起點(diǎn)
color: red // 字體顏色
}"
}
根據(jù)監(jiān)控點(diǎn)編號(hào)批量視頻預(yù)覽
{
"funcName": "startMultiPreviewByCameraIndexCode",
"argument": {
"list": [
{
"cameraIndexCode": "c633ef048fe141e1ac6dbeb36aaf21d3", // 監(jiān)控點(diǎn)編號(hào)
"ezvizDirect": 0, // 是否直連螢石預(yù)覽 未指定或?yàn)?0-非直連 其它值-直連
"gpuMode": 0, // 是否啟用 GPU 硬解 0-不啟用 1-啟用
"streamMode": 0, // 主子碼流標(biāo)識(shí) 0-主碼流 1-子碼流
"transMode": 1, // 傳輸協(xié)議 0-UDP 1-TCP
"wndId": 1 // 播放窗口序號(hào)
},
{
"cameraIndexCode": "c633ef048fe141e1ac6dbeb36aaf21d3",
"ezvizDirect": 0,
"gpuMode": 0,
"streamMode": 0,
"transMode": 1,
"wndId": 2
}
]
}
}
- ?根據(jù)監(jiān)控點(diǎn)編號(hào)批量錄像回放
{
"funcName": "startMultiPlaybackByCameraIndexCode",
"argument":
{
"list":[{
"cameraIndexCode": "58e90452772a4d9da7c7ba4cef26dbf0", // 監(jiān)控點(diǎn)編號(hào)
"startTimeStamp": "10237898985", // 錄像查詢開始時(shí)間戳,單位:秒
"endTimeStamp": "10237899985", // 錄像查詢結(jié)束時(shí)間戳,單位:秒
"recordLocation": 0, // 錄像存儲(chǔ)類型 0-中心存儲(chǔ) 1-設(shè)備存儲(chǔ)
"transMode": 1, // 傳輸協(xié)議 ,0-UDP 1-TCP
"wndId": 1, // 窗口序號(hào)
"gpuMode": 0 // 是否開啟 GPU 硬解,0-不開啟 1-開啟
}]
}
}
- 批量停止播放
{
"funcName": "stopMultiPlay",
"argument":
{
"list":[{
"wndId": 1 // 窗口序號(hào)
},
{
"wndId": 2 // 窗口序號(hào)
}]
}
}
?四、開發(fā)流程示意圖
? ? ? ?圖中灰色部分為可選步驟。其中申請(qǐng) RSA 公鑰可選。申請(qǐng) RSA 公鑰是為了加密初始化中 的一些敏感參數(shù),對(duì)安全性要求高的用戶可以考慮對(duì)敏感參數(shù)加密。但需要注意的是,使用 RSA 公 鑰加密機(jī)制必然會(huì)導(dǎo)致初始化耗時(shí)。一般情況下不需要調(diào) JS_DestroyWnd 來(lái)銷毀插件窗口 (JS_Disconnect 中會(huì)自行銷毀),但一些特殊的場(chǎng)景如瀏覽器頁(yè)面上需隨時(shí)啟用和禁用視頻播放時(shí), 需調(diào) JS_DestroyWnd 來(lái)禁用視頻播放,需要調(diào) JS_CreateWnd 來(lái)啟用視頻播放。JS_DestroyWnd 和 JS_Disconnect 中會(huì)反初始化插件,這里無(wú)需調(diào) JS_RequestInterface/uninit 反初始化。
?五、在vue中使用(實(shí)時(shí)預(yù)覽完整示例)
?1、在public目錄下的index.html中引入文件(資源文件在demo目錄下)
<script src="./jquery-1.9.1.min.js"></script>
<script src="./jsencrypt.min.js"></script> // 用于 RSA 公鑰加密
<script src="./jsWebControl-1.0.0.min.js"></script> // 用于前端與插件交互
?2、線預(yù)覽模塊完整實(shí)例,其他的模塊功能以此內(nèi)推(如有疑惑,可參考doc目錄下的文檔,里面記載很清楚)
html 示例
<div class="right" ref="playWndBox">
<!-- 視頻數(shù)據(jù)站位 -->
<div
id="playWnd"
class="playWnd"
:style="{
height: playWndHeight + 'px',
width: playWndWidth + 'px'
}"
></div>
</div>
?js 示例文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-402397.html
<script>
// 聲明公用變量 攝像頭實(shí)例對(duì)現(xiàn)象,為了方便引用 定義在全局
let oWebControl = null
var initCount = 0
var pubKey = ''
export default {
name: 'videoRuntime',
data() {
return {
playWndHeight: '', // 視頻盒子的高度
playWndWidth: '' // 視頻盒子的寬度
}
},
mounted() {
this.playWndHeight = this.$refs.playWndBox.clientHeight // 首次加載時(shí)的到父容器的高度
this.playWndWidth = this.$refs.playWndBox.clientWidth // 首次加載時(shí)的到父容器的寬度
this.$nextTick(() => {
// 初始化攝像頭
this.initPlugin()
})
// 監(jiān)聽resize事件,使插件窗口尺寸跟隨DIV窗口變化
window.addEventListener('resize', () => {
if (oWebControl != null) {
if (this.$refs.playWndBox)
oWebControl.JS_Resize(this.$refs.playWndBox.clientWidth, this.$refs.playWndBox.clientHeight)
}
})
},
methods: {
// 創(chuàng)建播放實(shí)例
initPlugin() {
let that = this
oWebControl = new window.WebControl({
szPluginContainer: 'playWnd', // 指定容器id
iServicePortStart: 15900, // 指定起止端口號(hào),建議使用該值
iServicePortEnd: 15909,
szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11', // 用于IE10使用ActiveX的clsid
cbConnectSuccess: () => {
// 創(chuàng)建WebControl實(shí)例成功
oWebControl
.JS_StartService('window', {
// WebControl實(shí)例創(chuàng)建成功后需要啟動(dòng)服務(wù)
dllPath: './VideoPluginConnect.dll' // 值"./VideoPluginConnect.dll"寫死
})
.then(
function() {
// 啟動(dòng)插件服務(wù)成功
oWebControl.JS_SetWindowControlCallback({
// 設(shè)置消息回調(diào)
cbIntegrationCallBack: that.cbIntegrationCallBack
})
oWebControl.JS_CreateWnd('playWnd', 0,0).then(function() {
//JS_CreateWnd創(chuàng)建視頻播放窗口,寬高可設(shè)定 默認(rèn)設(shè)置為0 消除初始化閃白問題
that.init() // 創(chuàng)建播放實(shí)例成功后初始化
})
},
function() {
// 啟動(dòng)插件服務(wù)失敗
}
)
},
cbConnectError: function() {
// 創(chuàng)建WebControl實(shí)例失敗
oWebControl = null
that.$message.warning('插件未啟動(dòng),正在嘗試啟動(dòng),請(qǐng)稍候...')
window.WebControl.JS_WakeUp('VideoWebPlugin://') // 程序未啟動(dòng)時(shí)執(zhí)行error函數(shù),采用wakeup來(lái)啟動(dòng)程序
initCount++
if (initCount < 3) {
setTimeout(function() {
that.initPlugin()
}, 3000)
} else {
that.$message.warning('插件啟動(dòng)失敗,請(qǐng)檢查插件是否安裝!')
}
},
cbConnectClose: () => {
// 異常斷開:bNormalClose = false
// JS_Disconnect正常斷開:bNormalClose = true
console.log('cbConnectClose')
oWebControl = null
}
})
},
// 初始化
init() {
let that = this
this.getPubKey(() => {
var appkey = '28730366' //綜合安防管理平臺(tái)提供的appkey,必填
var secret = this.setEncrypt('HSZkCJpSJ7gSUYrO6wVi') //綜合安防管理平臺(tái)提供的secret,必填
var ip = '10.19.132.75' //綜合安防管理平臺(tái)IP地址,必填
var playMode = 0 //初始播放模式:0-預(yù)覽,1-回放
var port = 443 //綜合安防管理平臺(tái)端口,若啟用HTTPS協(xié)議,默認(rèn)443
var snapDir = 'D:\\SnapDir' //抓圖存儲(chǔ)路徑
var videoDir = 'D:\\VideoDir' //緊急錄像或錄像剪輯存儲(chǔ)路徑
var layout = '1x1' //playMode指定模式的布局
var enableHTTPS = 1 //是否啟用HTTPS協(xié)議與綜合安防管理平臺(tái)交互,這里總是填1
var encryptedFields = 'secret' //加密字段,默認(rèn)加密領(lǐng)域?yàn)閟ecret
var showToolbar = 1 //是否顯示工具欄,0-不顯示,非0-顯示
var showSmart = 1 //是否顯示智能信息(如配置移動(dòng)偵測(cè)后畫面上的線框),0-不顯示,非0-顯示
var buttonIDs = '0,16,256,257,258,259,260,512,513,514,515,516,517,768,769' //自定義工具條按鈕
// var toolBarButtonIDs = "2049,2304" // 工具欄上自定義按鈕
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) {
console.log(oData)
oWebControl.JS_Resize(that.playWndWidth, that.playWndHeight) // 初始化后resize一次,規(guī)避firefox下首次顯示窗口后插件窗口未與DIV窗口重合問題
// 一進(jìn)來(lái)就隱藏
oWebControl.JS_HideWnd() // 先讓窗口隱藏,規(guī)避可能的插件窗口滯后于瀏覽器消失問題
})
})
},
// 獲取公鑰
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) {
var encrypt = new window.JSEncrypt()
encrypt.setPublicKey(pubKey)
return encrypt.encrypt(value)
},
// 回調(diào)的消息
cbIntegrationCallBack(oData) {
let { responseMsg: type, responseMsg: msg } = oData
if (type === 'error') {
console.log(type, msg, this.dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss'))
} else {
console.log(type, msg, this.dateFormat(new Date(), 'yyyy-MM-dd hh:mm:ss'))
}
},
// 預(yù)覽
startPreview(cameraCode) {
// 點(diǎn)擊查詢后顯示
oWebControl.JS_ShowWnd()
var cameraIndexCode = cameraCode //獲取輸入的監(jiān)控點(diǎn)編號(hào)值,必填
console.log(cameraCode)
var streamMode = 0 //主子碼流標(biāo)識(shí):0-主碼流,1-子碼流
var transMode = 1 //傳輸協(xié)議:0-UDP,1-TCP
var gpuMode = 0 //是否啟用GPU硬解,0-不啟用,1-啟用
var wndId = -1 //播放窗口序號(hào)(在2x2以上布局下可指定播放窗口)
cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, '')
cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, '')
oWebControl.JS_RequestInterface({
funcName: 'startPreview',
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, //監(jiān)控點(diǎn)編號(hào)
streamMode: streamMode, //主子碼流標(biāo)識(shí)
transMode: transMode, //傳輸協(xié)議
gpuMode: gpuMode, //是否開啟GPU硬解
wndId: wndId //可指定播放窗口
})
})
},
// 停止全部預(yù)覽
stopAllPreview() {
oWebControl.JS_RequestInterface({
funcName: 'stopAllPreview'
})
},
// 格式化時(shí)間
dateFormat(oDate, fmt) {
var 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 (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;
}
},
destroyed() { // 組件銷毀后
if (oWebControl != null) {
oWebControl.JS_HideWnd() // 先讓窗口隱藏,規(guī)避可能的插件窗口滯后于瀏覽器消失問題
oWebControl.JS_RequestInterface({funcName: "destroyWnd"}) // 銷毀當(dāng)前播放的視頻
oWebControl.JS_Disconnect() // 斷開與插件服務(wù)連接
}
}
}
</script>
注:由于本頁(yè)面沒有滾動(dòng)條,不會(huì)出現(xiàn)因滾動(dòng)條滾動(dòng)導(dǎo)致窗口需要被遮住的情況,所以就沒有添加scroll,如有滾動(dòng)條,請(qǐng)參考demo文件下?demo_window_simple_preview.html 中的setWndCover事件文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-402397.html
到了這里,關(guān)于vue+海康威視視頻web插件開發(fā)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!