前端接入海康威视摄像头3.3sdk多摄像头预览
下载sdk
链接: 海康开发平台websdk
选择3.3开发包,不用下载开发指南,压缩包里已经包含了.
打开下载解压缩的安装,其他目录不用管直接打开webs目录下index.html
直接双击打开就行不用管是file协议还是http协议,这是官方的demo.
这个账号密码就是你摄像头局域网ip复制到浏览器以后登录时用的账号和密码,端口没改过的话默认80,账号admin.
安装插件
要显示画面就得先安装codebase下面的这个exe文件.
随便整个vue文件用iframe将官方demo index.html内联进来.
<template>
<div class="container">
<iframe
class="iframe"
src="/hc/hc.html"
style="width: 100%; height: 100%"
></iframe>
</div>
</template>
<script>
/* eslint-disable no-undef */
import { getCommonList } from '@/api/device'
export default {
data() {
return {
loginDevices: [],
}
},
mounted() {
this.init()
},
methods: {
init() {
const iframe = document.querySelector('.iframe')
iframe.addEventListener('load', () => {
getCommonList({ type: 2 }).then((res) => {
const loginDevices = res.results.map((item) => {
return {
szUsername: item.account,
szPassword: item.password,
szIP: item.host,
szPort: item.port,
}
})
iframe.contentWindow.postMessage(loginDevices, '*')
})
})
},
},
}
</script>
<style lang="scss" scoped>
.container {
display: flex;
width: 100%;
height: 100%;
.seetings {
position: relative;
z-index: 1000;
padding: 10px;
}
.btns {
display: flex;
justify-content: space-evenly;
}
iframe {
border: none;
}
}
</style>
因为我的需求只是多窗口预览,不需要别的功能.直接将demo.css里将其他元素给隐藏掉.除plugin是显示摄像头画面用的其他的都可以隐藏掉.
.left *:not(.plugin) {
display: none;
}
//初始化插件检测安装
WebVideoCtrl.I_InitPlugin({
bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
iWndowType: 1,
//aIframe: ["test"],
cbSelWnd: function (xmlDoc) {
g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10);
var szInfo = "当前选择的窗口编号:" + g_iWndIndex;
showCBInfo(szInfo);
},
cbDoubleClickWnd: function (iWndIndex, bFullScreen) {
var szInfo = "当前放大的窗口编号:" + iWndIndex;
if (!bFullScreen) {
szInfo = "当前还原的窗口编号:" + iWndIndex;
}
showCBInfo(szInfo);
},
cbEvent: function (iEventType, iParam1, iParam2) {
if (2 == iEventType) {// 回放正常结束
showCBInfo("窗口" + iParam1 + "回放结束!");
} else if (-1 == iEventType) {
showCBInfo("设备" + iParam1 + "网络错误!");
} else if (3001 == iEventType) {
clickStopRecord(g_szRecordType, iParam1);
}
},
cbInitPluginComplete: function () {
WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin").then(() => {
// 检查插件是否最新
WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => {
if (bFlag) {
alert("检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!");
}
});
}, () => {
alert("插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!");
});
}
});
//魔改一下和让vue组件和iframe通信这里接收传过来的ip,端口,账号密码数组
//批量登录,加个定时器异步一下,别问为什么,因为同步调用api大概率会失败.
window.onload = function () {
window.addEventListener('message', (event) => {
//这里根据数组长度进行分屏处理一下
const num = Math.ceil(Math.sqrt(event.data.length)) >= 4 ? 4 : Math.ceil(Math.sqrt(event.data.length))
setTimeout(() => { changeWndNum(num) }, 200)
event.data.forEach((item, index) => {
setTimeout(() => {
clickLogin(item, event.data.length - 1 - index)
}, 1000 + index * 100);
})
})
};
// 登录
function clickLogin(device, index) {
const { szIP, szPort, szUsername, szPassword } = device
if ("" == szIP || "" == szPort) {
return;
}
var szDeviceIdentify = szIP + "_" + szPort;
console.log(szIP, 1, szPort, szUsername, szPassword)
WebVideoCtrl.I_Login(szIP, 1, szPort, szUsername, szPassword, {
timeout: 3000,
success: function (xmlDoc) {
console.log(szDeviceIdentify + " 登录成功!");
setTimeout(function () {
$("#ip").val(szDeviceIdentify);
setTimeout(function () {
getChannelInfo(szDeviceIdentify);
}, 1000);
getDevicePort(szDeviceIdentify);
}, 10);
//这里加个定时器进行预览的api调用,异步一下,时间比前面1000ms长就行,不然批量预览不会全部成功
setTimeout(() => {
clickStartRealPlay(1, szDeviceIdentify, index)
}, 2000);
},
error: function (oError) {
if (ERROR_CODE_LOGIN_REPEATLOGIN === status) {
showOPInfo(szDeviceIdentify + " 已登录过!");
} else {
showOPInfo(szDeviceIdentify + " 登录失败!", oError.errorCode, oError.errorMsg);
}
}
});
}
// 窗口分割数
function changeWndNum(iType) {
if ("1*2" === iType || "2*1" === iType) {
WebVideoCtrl.I_ArrangeWindow(iType).then(() => {
showOPInfo("窗口分割成功!");
}, (oError) => {
var szInfo = "窗口分割失败!";
showOPInfo(szInfo, oError.errorCode, oError.errorMsg);
});
} else {
iType = parseInt(iType, 10);
WebVideoCtrl.I_ChangeWndNum(iType).then(() => {
console.log("窗口分割成功!");
}, (oError) => {
var szInfo = "窗口分割失败!";
console.log(szInfo, oError.errorCode, oError.errorMsg);
});
}
}
参数全部写死处理那个窗口,直接通过数组下标来指定每个摄像头播放的窗口.iWndIndex动态传就行.
//魔改一下预览函数
function clickStartRealPlay(iStreamType, szDeviceIdentify, index) {
console.log(iStreamType, szDeviceIdentify, index, '预览参数');
var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex)
if (null == szDeviceIdentify) {
return;
}
var startRealPlay = function () {
WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
iWndIndex: index,
iStreamType: iStreamType,
iChannelID: 1,
bZeroChannel: false,
success: function () {
szInfo = "开始预览成功!";
console.log(szDeviceIdentify + " " + szInfo);
},
error: function (oError) {
console.log(szDeviceIdentify + " 开始预览失败!", oError.errorCode, oError.errorMsg);
}
});
};
if (oWndInfo != null) {// 已经在播放了,先停止
WebVideoCtrl.I_Stop({
success: function () {
startRealPlay();
}
});
} else {
startRealPlay();
}
}