一、环境准备
下载地址:海康威视官网
下载页面
文件解压后的目录
运行bin文件下的VideoWebPlugin.exe
二、插件demo测试
demo/demo_window_integration.html 包含了插件所有功能的,可参照此demo来开发、验证功能、排查问题
demo/demo_window_simple_playback.html.html 视频回放,可在此基础上二次开发
demo/demo_window_simple_preview.html 实时预览,可在基础上二次开发
在浏览器中打开 demo/demo_window_integration.html 文件如下
在进入官网运行管理平台获取到 Appkey、AppSecret、Ip、Port,就能连接到自己的摄像头进行调试开发了
三、api相关介绍
1、JS_StartService(szType,options) 启动插件服务接口 (返回值Promise)
szType:服务类型 固定填充 “window”(必填)
options:可选参数对象 固定填充{dllPath: "./VideoPluginConnect.dll"}(对象选填)
2、JS_Disconnect() 断开服务接口 (返回值Promise)
3、JS_CreateWnd(szId, iWidth, iHeight) 创建插件窗口接口 (返回值Promise)
szId:父窗口的id (必填)
iWidth:元素 ID 标识窗口的宽度 (必填)
iHeight:元素 ID 标识窗口的高度 (必填)
4、JS_SetWindowControlCallback(callback) 设置消息回调接口
callback(对象 必填) 示例
{
cbIntegrationCallBack(必要属性): function(oData){ // oData 是封装的视频 web 插件回调消息的消息体
console.log(JSON.stringify(oData)); // 打印消息体至控制台
}
5、JS_Resize(iWidth,iHeight) 调整插件窗口大小、位置接口
iWidth:DIV 窗口宽度 (必填)
iHeight:DIV 窗口高度(必填)
6、JS_CuttingPartWindow(iLeft, iTop, iWidth, iHeight) 扣除部分插件窗口接口
场景:插件窗口创建后,会始终置顶,因此当和其它组件一同使用时,会遮挡其它组件内容,该接口 的作用是,当部分插件窗口不需要置顶时,我们会隐藏部分插件窗口。也就是向上滚动的时候会隐藏
iLeft:距离插件窗口左边距(必填)
iTop:距离插件窗口上边距(必填)
iWidth:需要扣除的宽度(必填)
iHeight:需要扣除的高度(必填)
7、JS_RepairPartWindow(iLeft, iTop, iWidth, iHeight) 还原扣除部分窗口后的插件窗口
场景:一般联合 JS_CuttingPartWindow 一起使用,在还原部分窗口后 在扣除
iLeft:扣除窗口的顶点距离插件窗 口左边距 (必填)
iTop:扣除窗口的顶点距离插件窗 口上边距 (必填)
iWidth:扣除窗口的宽度(必填)
iHeight:扣除窗口的高度(必填)
8、JS_HideWnd() 插件窗口隐藏接口
9、JS_ShowWnd() 插件窗口显示接口
10、JS_DestroyWnd() 插件窗口销毁接口
11、JS_WakeUp(szProtocal) 唤醒 WebControl.exe 接口
场景 当 WebControl.exe 未启动时唤醒 WebControl.exe。若 WebControl.exe 已启动则忽略
szProtocal:唤醒协议 内容固定为("VideoWebPlugin://")
12、JS_RequestInterface({funcName,argument})通过请求响应接口 (返回值Promise)
funcName:功能标识(必填)
argument:功能参数 (object 格式的字符串)
- 例 申请 RSA 公钥
{ funcName: "getRSAPubKey", argument: "{ keyLength: 1024 }" }
- 初始化
{
funcName: "init",
argument: "{
appkey: "afsgnhmj34567dgh", // API 网关提供的 appkey
secret: "vgkk3g0jaoj0igoigj", // API 网关提供的 secret
ip: "10.33.31.4", // API 网关 IP 地址
port: 9016, // API 网关端口
playMode: 0, //播放模式(决定显示预览还是回放界面),0-预览 1-录像播放
encryptedFields: "appkey,secret", //secret 和 appkey 已加密,对多个字段加密存在初始化耗时问题
snapDir: "D:\SnapDir", // 抓图存储路径
layout: "2x2" // 初始化 2x2 布局
showToolbar: 1, // 显示工具栏
showIntelligent: 1, // 显示智能信息
buttonIDs: "0,16,256,257,258"
}"
}
- 根据监控点编号视频预览
{
funcName: "startPreview",
argument: "{
cameraIndexCode: "afsgnhmj34567dgh", // 监控点编号
streamMode: 0, // 主子码流标识,0-主码流 1-子码流
transMode: 1, // 传输协议,0-UDP 1-TCP
gpuMode: 0 // 是否开启 GPU 硬解,不建议开启,0-不开启 1-开启
}"
}
- 停止所有视频预览
{
funcName: "stopAllPreview"
}
- 根据监控点编号录像回放
{
funcName: "startPlayback",
argument: "{
cameraIndexCode: "afsgnhmj34567dgh", // 监控点编号
startTimeStamp: "10237898985", // 录像查询开始时间戳,单位:秒
endTimeStamp: "10237899985", // 录像查询结束时间戳,单位:秒
recordLocation: 0, // 录像存储类型 0-中心存储 1-设备存储
transMode: 1, // 传输协议 ,0-UDP 1-TCP
gpuMode: 0 // 是否开启 GPU 硬解,0-不开启 1-开启
}"
}
- 停止所有录像回放
{
funcName: "stopAllPlayback"
}
- 销毁播放实例
{
funcName: "destroyWnd"
}
- 获取当前布局
{
funcName: "getLayout"
}
- 设置当前布局
{
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, // 相对播放窗口左上角的横坐标起点
y: 5, // 相对播放窗口左上角的纵坐标起点
color: red // 字体颜色
}"
}
根据监控点编号批量视频预览
{
"funcName": "startMultiPreviewByCameraIndexCode",
"argument": {
"list": [
{
"cameraIndexCode": "c633ef048fe141e1ac6dbeb36aaf21d3", // 监控点编号
"ezvizDirect": 0, // 是否直连萤石预览 未指定或为 0-非直连 其它值-直连
"gpuMode": 0, // 是否启用 GPU 硬解 0-不启用 1-启用
"streamMode": 0, // 主子码流标识 0-主码流 1-子码流
"transMode": 1, // 传输协议 0-UDP 1-TCP
"wndId": 1 // 播放窗口序号
},
{
"cameraIndexCode": "c633ef048fe141e1ac6dbeb36aaf21d3",
"ezvizDirect": 0,
"gpuMode": 0,
"streamMode": 0,
"transMode": 1,
"wndId": 2
}
]
}
}
- 根据监控点编号批量录像回放
{
"funcName": "startMultiPlaybackByCameraIndexCode",
"argument":
{
"list":[{
"cameraIndexCode": "58e90452772a4d9da7c7ba4cef26dbf0", // 监控点编号
"startTimeStamp": "10237898985", // 录像查询开始时间戳,单位:秒
"endTimeStamp": "10237899985", // 录像查询结束时间戳,单位:秒
"recordLocation": 0, // 录像存储类型 0-中心存储 1-设备存储
"transMode": 1, // 传输协议 ,0-UDP 1-TCP
"wndId": 1, // 窗口序号
"gpuMode": 0 // 是否开启 GPU 硬解,0-不开启 1-开启
}]
}
}
- 批量停止播放
{
"funcName": "stopMultiPlay",
"argument":
{
"list":[{
"wndId": 1 // 窗口序号
},
{
"wndId": 2 // 窗口序号
}]
}
}
四、开发流程示意图
图中灰色部分为可选步骤。其中申请 RSA 公钥可选。申请 RSA 公钥是为了加密初始化中 的一些敏感参数,对安全性要求高的用户可以考虑对敏感参数加密。但需要注意的是,使用 RSA 公 钥加密机制必然会导致初始化耗时。一般情况下不需要调 JS_DestroyWnd 来销毁插件窗口 (JS_Disconnect 中会自行销毁),但一些特殊的场景如浏览器页面上需随时启用和禁用视频播放时, 需调 JS_DestroyWnd 来禁用视频播放,需要调 JS_CreateWnd 来启用视频播放。JS_DestroyWnd 和 JS_Disconnect 中会反初始化插件,这里无需调 JS_RequestInterface/uninit 反初始化。
五、在vue中使用(实时预览完整示例)
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、线预览模块完整实例,其他的模块功能以此内推(如有疑惑,可参考doc目录下的文档,里面记载很清楚)
html 示例
<div class="right" ref="playWndBox">
<!-- 视频数据站位 -->
<div
id="playWnd"
class="playWnd"
:style="{
height: playWndHeight + 'px',
width: playWndWidth + 'px'
}"
></div>
</div>
js 示例文章来源:https://www.toymoban.com/news/detail-402397.html
<script>
// 声明公用变量 摄像头实例对现象,为了方便引用 定义在全局
let oWebControl = null
var initCount = 0
var pubKey = ''
export default {
name: 'videoRuntime',
data() {
return {
playWndHeight: '', // 视频盒子的高度
playWndWidth: '' // 视频盒子的宽度
}
},
mounted() {
this.playWndHeight = this.$refs.playWndBox.clientHeight // 首次加载时的到父容器的高度
this.playWndWidth = this.$refs.playWndBox.clientWidth // 首次加载时的到父容器的宽度
this.$nextTick(() => {
// 初始化摄像头
this.initPlugin()
})
// 监听resize事件,使插件窗口尺寸跟随DIV窗口变化
window.addEventListener('resize', () => {
if (oWebControl != null) {
if (this.$refs.playWndBox)
oWebControl.JS_Resize(this.$refs.playWndBox.clientWidth, this.$refs.playWndBox.clientHeight)
}
})
},
methods: {
// 创建播放实例
initPlugin() {
let that = this
oWebControl = new window.WebControl({
szPluginContainer: 'playWnd', // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15909,
szClassId: '23BF3B0A-2C56-4D97-9C03-0CB103AA8F11', // 用于IE10使用ActiveX的clsid
cbConnectSuccess: () => {
// 创建WebControl实例成功
oWebControl
.JS_StartService('window', {
// WebControl实例创建成功后需要启动服务
dllPath: './VideoPluginConnect.dll' // 值"./VideoPluginConnect.dll"写死
})
.then(
function() {
// 启动插件服务成功
oWebControl.JS_SetWindowControlCallback({
// 设置消息回调
cbIntegrationCallBack: that.cbIntegrationCallBack
})
oWebControl.JS_CreateWnd('playWnd', 0,0).then(function() {
//JS_CreateWnd创建视频播放窗口,宽高可设定 默认设置为0 消除初始化闪白问题
that.init() // 创建播放实例成功后初始化
})
},
function() {
// 启动插件服务失败
}
)
},
cbConnectError: function() {
// 创建WebControl实例失败
oWebControl = null
that.$message.warning('插件未启动,正在尝试启动,请稍候...')
window.WebControl.JS_WakeUp('VideoWebPlugin://') // 程序未启动时执行error函数,采用wakeup来启动程序
initCount++
if (initCount < 3) {
setTimeout(function() {
that.initPlugin()
}, 3000)
} else {
that.$message.warning('插件启动失败,请检查插件是否安装!')
}
},
cbConnectClose: () => {
// 异常断开:bNormalClose = false
// JS_Disconnect正常断开:bNormalClose = true
console.log('cbConnectClose')
oWebControl = null
}
})
},
// 初始化
init() {
let that = this
this.getPubKey(() => {
var appkey = '28730366' //综合安防管理平台提供的appkey,必填
var secret = this.setEncrypt('HSZkCJpSJ7gSUYrO6wVi') //综合安防管理平台提供的secret,必填
var ip = '10.19.132.75' //综合安防管理平台IP地址,必填
var playMode = 0 //初始播放模式:0-预览,1-回放
var port = 443 //综合安防管理平台端口,若启用HTTPS协议,默认443
var snapDir = 'D:\\SnapDir' //抓图存储路径
var videoDir = 'D:\\VideoDir' //紧急录像或录像剪辑存储路径
var layout = '1x1' //playMode指定模式的布局
var enableHTTPS = 1 //是否启用HTTPS协议与综合安防管理平台交互,这里总是填1
var encryptedFields = 'secret' //加密字段,默认加密领域为secret
var showToolbar = 1 //是否显示工具栏,0-不显示,非0-显示
var showSmart = 1 //是否显示智能信息(如配置移动侦测后画面上的线框),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网关提供的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 //自定义工具条按钮
})
})
.then(function(oData) {
console.log(oData)
oWebControl.JS_Resize(that.playWndWidth, that.playWndHeight) // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
// 一进来就隐藏
oWebControl.JS_HideWnd() // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
})
})
},
// 获取公钥
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)
},
// 回调的消息
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'))
}
},
// 预览
startPreview(cameraCode) {
// 点击查询后显示
oWebControl.JS_ShowWnd()
var cameraIndexCode = cameraCode //获取输入的监控点编号值,必填
console.log(cameraCode)
var streamMode = 0 //主子码流标识:0-主码流,1-子码流
var transMode = 1 //传输协议:0-UDP,1-TCP
var gpuMode = 0 //是否启用GPU硬解,0-不启用,1-启用
var 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 //可指定播放窗口
})
})
},
// 停止全部预览
stopAllPreview() {
oWebControl.JS_RequestInterface({
funcName: 'stopAllPreview'
})
},
// 格式化时间
dateFormat(oDate, fmt) {
var o = {
"M+": oDate.getMonth() + 1, //月份
"d+": oDate.getDate(), //日
"h+": oDate.getHours(), //小时
"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() // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
oWebControl.JS_RequestInterface({funcName: "destroyWnd"}) // 销毁当前播放的视频
oWebControl.JS_Disconnect() // 断开与插件服务连接
}
}
}
</script>
注:由于本页面没有滚动条,不会出现因滚动条滚动导致窗口需要被遮住的情况,所以就没有添加scroll,如有滚动条,请参考demo文件下 demo_window_simple_preview.html 中的setWndCover事件文章来源地址https://www.toymoban.com/news/detail-402397.html
到了这里,关于vue+海康威视视频web插件开发的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!