前段时间项目中需要对接海康视频,需要实现视频的实时预览、回放、录像、抓图及云台操作等功能,因此选择海康视频web插件v1.5.4插件来完成,但也确实在使用插件的过程中踩了很多坑,记录下来希望对其他小伙伴儿有些许帮助。
一、海康视频web插件使用
1、视频web插件安装与下载
注册并登录海康开放平台,如:
海康开放平台https://open.hikvision.com/download/5c67f1e2f05948198c909700?type=20下载视频web插件 V1.5.4,其中包含demo、插件及使用说明,按照使用说明安装插件即可。
2、视频web插件使用
2.1 引用js文件
在public文件夹下新建haikang文件夹,并将上面demo下的三个文件复制到haikang文件夹下,即:
并且在public文件夹下的index.html中引入js文件
<script type="text/javascript" src="./haikang/jquery-1.12.4.min.js"></script>
<script type="text/javascript" src="./haikang/web-control_1.2.5.min.js"></script>
<script type="text/javascript" src="./h5player/h5player.min.js"></script>
2.2 vue文件中使用
定义显示视频的div盒子:
<div id="carousel-hkvideoid" class="playWnd"></div>
初始化并应用插件,即先销毁组件然后再重启插件,可监听窗口并随这浏览器的大小变化。
// 销毁插件
destroyWnd(cb) {
if (this.oWebControl) {
this.oWebControl.JS_HideWnd();
this.oWebControl
.JS_DestroyWnd({
funcName: "destroyeWnd",
})
.then(function (oData) {
});
} else {
console.log("没有实例");
}
cb && cb();
},
// 销毁并重启
destroyedAndCreate() {
this.destroyWnd(() => {
this.createdVideo();
});
},
// 初始化+预览
createdVideo() {
this.initPlugin('carousel-hkvideoid', () => {
if (this.playMode == 0) {
previewVideo(this.oWebControl, this.cameraIndexCode);//预览
} else {
startPlayback(this.oWebControl, this.daterangeMonitorTime, this.cameraIndexCode);
}
});
},
// 初始化
init(callback) {
this.getPubKey(() => {
// 请自行修改以下变量值
let appkey = this.config.appkey; //综合安防管理平台提供的appkey,必填
let secret = this.setEncrypt(this.config.secret); //综合安防管理平台提供的secret,必填
let ip = this.config.ip; //综合安防管理平台IP地址,必填
let playMode = this.playMode; //初始播放模式:0-预览,1-回放
let port = this.config.port; //综合安防管理平台端口,若启用HTTPS协议,默认443
let snapDir = "H:\\SnapDir"; //抓图存储路径
let videoDir = "H:\\VideoDir"; //紧急录像或录像剪辑存储路径
let layout = this.layout; //playMode指定模式的布局
let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互,是为1,否为0
let encryptedFields = "secret"; //加密字段,默认加密领域为secret
let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
let showSmart = 0; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
let buttonIDs = "0,16,256,257,258,259,260,512,513,514,515,516,768,769"; //自定义工具条按钮
// 请自行修改以上变量值
this.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, //自定义工具条按钮
toolBarButtonIDs: '4098',//自定义工具栏按钮
}),
})
.then((oData) => {
// 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
this.getDomInfo();
callback && callback();
});
});
},
// 创建播放实例
initPlugin(id, callback) {
let that = this;
this.videoLoad = false;
that.oWebControl = new WebControl({
szPluginContainer: id, // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15900,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: function () {
// 创建WebControl实例成功
that.oWebControl
.JS_StartService("window", {
// WebControl实例创建成功后需要启动服务
dllPath: "./VideoPluginConnect.dll", // 值"./VideoPluginConnect.dll"写死
})
.then(
function () {
// 启动插件服务成功
that.oWebControl.JS_SetWindowControlCallback({
// 设置消息回调
cbIntegrationCallBack: that.cbIntegrationCallBack,
});
that.oWebControl
.JS_CreateWnd(id, that.videoWidth, that.videoHeight)
.then(() => {
//JS_CreateWnd创建视频播放窗口,宽高可设定
that.init(callback); // 创建播放实例成功后初始化
});
},
function () {
that.oWebControl = null;
that.$message.warning(
`监控插件未启动,正在尝试第${that.initCount + 1}次启动,请稍候...`
);
WebControl.JS_WakeUp("VideoWebPlugin://");
that.initCount++;
if (that.initCount < 3) {
setTimeout(() => that.initPlugin(), 3000);
} else {
that.videoLoad = true; //打开下载提示,请先安装视频插件
}
// 启动插件服务失败
}
);
},
cbConnectError: () => {
// 创建WebControl实例失败
that.oWebControl = null;
that.$message.warning(
`监控插件未启动,正在尝试第${that.initCount + 1}次启动,请稍候...`
);
WebControl.JS_WakeUp("VideoWebPlugin://");
that.initCount++;
if (that.initCount < 3) {
setTimeout(() => that.initPlugin(), 3000);
} else {
that.videoLoad = true; //打开下载提示,请先安装视频插件
}
},
cbConnectClose: (bNormalClose) => {
// 异常断开:bNormalClose = false
// JS_Disconnect正常断开:bNormalClose = true
that.oWebControl = null;
that.$message.warning(
`监控插件未启动,正在尝试第${that.initCount + 1}次启动,请稍候...`
);
WebControl.JS_WakeUp("VideoWebPlugin://");
that.initCount++;
if (that.initCount < 2) {
setTimeout(() => that.initPlugin(), 3000);
} else {
that.videoLoad = true; //打开下载提示,请先安装视频插件
}
},
});
},
//获取公钥
getPubKey(callback) {
this.oWebControl
.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024,
}),
})
.then((oData) => {
if (oData.responseMsg.data) {
this.pubKey = oData.responseMsg.data;
callback();
}
});
},
//RSA加密
setEncrypt(value) {
let encrypt = new JSEncrypt();
encrypt.setPublicKey(this.pubKey);
return encrypt.encrypt(value);
},
getDomInfo() {
const oWebControl = this.oWebControl;
const { width, height, top, left } = document
.getElementById('carousel-hkvideoid')
.getBoundingClientRect();
if (oWebControl) {
oWebControl.JS_Resize(width, height);
// oWebControl.JS_CuttingPartWindow(left, top, 0, 0);
this.videoWidth = width;
this.videoHeight = height;
this.setWndCover();
}
},
// 设置窗口裁剪,当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
setWndCover() {
let iWidth = $(window).width(); // 获取浏览器宽度 不含滚动条
let iHeight = $(window).height();
let oDivRect = $("#" + 'carousel-hkvideoid')
.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 > this.videoWidth ? this.videoWidth : iCoverLeft;
iCoverTop = iCoverTop > this.videoHeight ? this.videoHeight : iCoverTop;
iCoverRight =
iCoverRight > this.videoWidth ? this.videoWidth : iCoverRight;
iCoverBottom =
iCoverBottom > this.videoHeight ? this.videoHeight : iCoverBottom;
// 多1个像素点防止还原后边界缺失一个像素条
this.oWebControl.JS_RepairPartWindow(
0,
0,
this.videoWidth + 1,
this.videoHeight
);
if (iCoverLeft != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
0,
iCoverLeft,
this.videoHeight
);
}
if (iCoverTop != 0) {
// 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
this.oWebControl.JS_CuttingPartWindow(
0,
0,
this.videoWidth + 1,
iCoverTop
);
}
if (iCoverRight != 0) {
this.oWebControl.JS_CuttingPartWindow(
this.videoWidth - iCoverRight,
0,
iCoverRight,
this.videoHeight
);
}
if (iCoverBottom != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
this.videoHeight - iCoverBottom,
this.videoWidth,
iCoverBottom
);
}
},
// value为字符串,JS_RequestInterface仅接收json格式的变量,且需要先解析出argument,并且将argument字段的内容转为字符串
requestInterface() {
var JsonParam = this.drawOSDParam;
var JsonArgument = JsonParam.argument;
JsonParam.argument = JSON.stringify(JsonArgument);
this.oWebControl.JS_RequestInterface(JsonParam).then(function (oData) {
console.log(oData)
});
},
// 消息回调
cbIntegrationCallBack(oData) {
// console.log(oData);
},
实现视频预览播放
//单个监控点实时预览播放
previewVideo(oWebControl,cameraIndexCode) {
let streamMode = 1; // 主子码流标识:0-主码流,1-子码流
let transMode = 1; // 传输协议:0-UDP,1-TCP
let gpuMode = 0; // 是否启用GPU硬解,0-不启用,1-启用
let wndId = -1; // 播放窗口序号(在2x2以上布局下可指定播放窗口)
oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode.trim(), // 监控点编号
streamMode: streamMode, // 主子码流标识
transMode: transMode, // 传输协议
gpuMode: gpuMode, // 是否开启GPU硬解
wndId: wndId, // 可指定播放窗口
}),
});
},
//多个监控点批量实时预览播放
multiPreviewVideo(oWebControl,cameraIndexCodeList,) {
let streamMode = 1; // 主子码流标识:0-主码流,1-子码流
let transMode = 1; // 传输协议:0-UDP,1-TCP
let gpuMode = 0; // 是否启用GPU硬解,0-不启用,1-启用
oWebControl
.JS_RequestInterface({
funcName: "startMultiPreviewByCameraIndexCode",
argument: JSON.stringify({
list: cameraIndexCodeList.map((camera, idx) => {
return {
cameraIndexCode: camera, //监控点编号
streamMode, //主子码流标识
transMode, //传输协议
gpuMode, //是否开启GPU硬解
wndId: idx + 1, // 播放窗口序号(在2x2以上布局下可指定播放窗口)
};
}), // 监控点编号集合
}),
})
.then((res) => {
if (res.errorCode === 0) {
console.log("预览成功");
}
});
},
实现视频回放
//单个监控点视频回放
startPlayback(oWebControl,daterangeMonitorTime,cameraIndexCode) {
var startTimeStamp = new Date(daterangeMonitorTime[0]).getTime(); //回放开始时间戳,必填
var endTimeStamp = new Date(daterangeMonitorTime[1]).getTime(); //回放结束时间戳,必填
startTimeStamp = Math.floor(startTimeStamp / 1000).toString();
endTimeStamp = Math.floor(endTimeStamp / 1000).toString();
var recordLocation = 1; //录像存储位置:0-中心存储,1-设备存储
var transMode = 0; //传输协议:0-UDP,1-TCP
var gpuMode = 0; //是否启用GPU硬解,0-不启用,1-启用
var wndId = 1; //播放窗口序号(在2x2以上布局下可指定播放窗口)
oWebControl.JS_RequestInterface({
funcName: "startPlayback",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, //监控点编号
startTimeStamp, //录像查询开始时间戳,单位:秒
endTimeStamp, //录像结束开始时间戳,单位:秒
recordLocation: recordLocation, //录像存储类型:0-中心存储,1-设备存储
transMode: transMode, //传输协议:0-UDP,1-TCP
gpuMode: gpuMode, //是否启用GPU硬解,0-不启用,1-启用
wndId: wndId //可指定播放窗口
})
})
},
// 多个监控点批量回放
multiPlaybackVideo(oWebControl,daterangeMonitorTime,cameraIndexCodeList) {
if (null == daterangeMonitorTime || '' == daterangeMonitorTime) {
this.$modal.msgError("请选择时间");
return;
}
var startTimeStamp = new Date(daterangeMonitorTime[0]).getTime(); //回放开始时间戳,必填
var endTimeStamp = new Date(daterangeMonitorTime[1]).getTime(); //回放结束时间戳,必填
startTimeStamp = Math.floor(startTimeStamp / 1000).toString();
endTimeStamp = Math.floor(endTimeStamp / 1000).toString();
var recordLocation = 1; //录像存储位置:0-中心存储,1-设备存储
var transMode = 0; //传输协议:0-UDP,1-TCP
var gpuMode = 0; //是否启用GPU硬解,0-不启用,1-启用
let dataList = cameraIndexCodeList;
oWebControl
.JS_RequestInterface({
funcName: "startMultiPlaybackByCameraIndexCode",
argument: JSON.stringify({
list: dataList.map((camera, idx) => {
return {
cameraIndexCode: camera, //监控点编号
startTimeStamp, //录像查询开始时间戳,单位:秒
endTimeStamp, //录像结束开始时间戳,单位:秒
recordLocation: recordLocation, //录像存储类型:0-中心存储,1-设备存储
transMode: transMode, //传输协议:0-UDP,1-TCP
gpuMode: gpuMode, //是否启用GPU硬解,0-不启用,1-启用
wndId: idx + 1, // 播放窗口序号(在2x2以上布局下可指定播放窗口)
};
}), // 监控点编号集合
}),
})
.then((res) => {
if (res.errorCode === 0) {
console.log("回放成功");
}
});
},
//停止回放
stopPlayback(oWebControl) {
oWebControl.JS_RequestInterface({
funcName: "stopAllPlayback"
})
}
该视频web插件自带抓图、录像、云台操作等功能,不需要再进行编写代码,只需在初始化时配置buttonIDs,来添加自己需要的功能。
二、问题及解决方案
1、海康视频不会随着盒子宽高变化而变化的问题
mounted() {
window.addEventListener("resize", () => {
if (this.oWebControl != null) {
this.getDomInfo();
}
});
},
2、在回放时需要选择时间,此时海康视频会出现遮挡弹窗等问题,解决方案是通过扣除部分插件窗口来实现:
//当 input 获得焦点时触发
startTimeFocus() {
if (this.oWebControl) {
this.oWebControl.JS_CuttingPartWindow(this.videoWidth-660, 5, 660, this.videoHeight / 2 -10);
}
},
//当 input 失去焦点时触发
startTimeBlur() {
if (this.oWebControl) {
this.oWebControl.JS_RepairPartWindow(this.videoWidth-660, 5, 660, this.videoHeight / 2 - 10);
}
},
3、web视频插件界面增加html内容,目前是却视频插件遮挡了,解决方案:
如果只是加载text字符串的话,可以通过画面字符叠加来实现:
{
funcName: "drawOSD",
argument: "{
text: "温度:50\n 湿度:38", // 窗口布局
x: 5,
y: 5
}"
}
但是如果要增加图片等html内容的话,还是通过扣除部分插件窗口来实现,即由于项目需要在视频界面增加自己的云台操作功能方便用户操作,因此在初始化的时候就裁剪好窗口,如:
initControl(){
if (this.oWebControl) {
this.controlLeft= this.videoWidth-this.controlWidth-5;
this.controlTop = this.videoHeight*0.5;
this.oWebControl.JS_CuttingPartWindow(this.controlLeft, this.controlTop, this.controlWidth, this.controlHeight);
}
},
三、总结
海康视频web插件的使用可具体参考下载的文件中doc的视频WEB插件V1.5.4开发指南.pdf文档。
整体代码如下:
<!-- monitorVideoDialog.vue -->
<template>
<!-- 海康视频监控 -->
<el-dialog :visible.sync="hkVideoDialog" width="100%" custom-class="dialogClass" :modal="false" :append-to-body="true"
:modal-append-to-body="true">
<div class="videoContent">
<div style="font-size: 30px;position: relative;z-index: 27;cursor: pointer;height: 4%;text-align: right;">
<el-date-picker v-model="daterangeMonitorTime" size="mini" style="width: 360px;margin-right: 10px;"
value-format="yyyy-MM-dd HH:mm:ss" type="datetimerange" range-separator="-" start-placeholder="开始日期"
end-placeholder="结束日期" @focus="startTimeFocus" @blur="startTimeBlur"></el-date-picker>
<el-button round size="mini" @click="playBack"><svg-icon icon-class="playback" style="margin-right:3px"/>回放</el-button>
<el-button round icon="el-icon-switch-button" size="mini" @click="closeVideo"
style="margin-right: 10px;">退出</el-button>
</div>
<div id="carousel-hkvideoid" class="playWnd"></div>
<div class="video-tips" v-if="videoLoad">
<p style="height: 50px;font-size: 30px;font-weight: 600;letter-spacing: 4px;">控件未安装或加载失败</p>
<ul type="none" class="ulStyle">
<li style="line-height: 20px;">1. 若未安装控件,请 <a :href="hrefLink"
style="color:#51c9fa; text-decoration: none;">下载安装浏览器控件</a> ;</li>
<li style="line-height: 20px;">2. 若已安装控件,请先尝试重试当前操作,若问题仍然存在,建议重启电脑或重新安装控件;</li>
<li style="line-height: 20px;">3. 若控件仍不可用,还可前往下载中心下载安装完整桌面客户端进行使用。</li>
</ul>
</div>
</div>
</el-dialog>
</template>
<script>
import { getplugin } from "@/api/api.js";
import { previewVideo, startPlayback } from '@/utils/hkvideo'
export default {
props: {
hkVideoDialog: {
type: Boolean,
},
code: {
//摄像头编号
type: String,
required: true,
},
time: {
//回放的时间段
type: Array,
default: () => [new Date(new Date() - 3600 * 1000 * 24 * 1), new Date()],
},
},
data() {
return {
oWebControl: null, //插件实例
videoLoad: false, //插件是否安装
initCount: 0, //尝试启动插件次数
config: {
//海康后台提供的网关信息,需要叫后端配置好提供给你,或者接口请求回来(!!!必填!!!)
appkey: "",
secret: "",
ip: "",
port: 1443, //只能是number类型否则白屏
},
hrefLink: '',
videoWidth: 0,
videoHeight: 0,
left: "",
top: "",
initCount: 0, // 启动次数
playMode: 0, // 0 预览 1回放
cameraIndexCode: "", // 监控点编号
oWebControl: null,
selfEle: null, // 自身原始
//设置窗口遮挡 根据浏览器大小变化视频插件的大小
iLastCoverLeft: 0,
iLastCoverTop: 0,
iLastCoverRight: 0,
iLastCoverBottom: 0,
type: 'live',//live实时rec回放
daterangeMonitorTime: [this.parseTime(new Date(new Date().setHours(0, 0, 0, 0))), this.parseTime(new Date())],
initCount: 0,
//字符叠加
drawOSDParam: {
"argument": {
"alignType": 1,
"bold": 0,
"color": 255,
"fontSize": 32,
"text": "噪声值:30.5",
"wndId": 0,
"x": 10,
"y": 20
},
"funcName": "drawOSD"
},
layout: '1x1'
};
},
watch: {
hkVideoDialog: {
handler(newVal) {
if (newVal) {
debugger
this.playMode = 0
this.cameraIndexCode = this.code;
this.destroyedAndCreate();
// this.getDomInfo();
}
},
// immediate: true,
deep: true
},
},
mounted() {
//需要先判断用户是否安装插件,没有的话可以先下载插件,
this.getplugin();
window.addEventListener("resize", () => {
if (this.oWebControl != null) {
this.getDomInfo();
}
});
},
methods: {
//下载插件
getplugin() {
getplugin().then((res) => {
if (200 == res.code) {
this.hrefLink = res.data;
}
})
},
//动态调整视频窗口
getDomInfo() {
const oWebControl = this.oWebControl;
const { width, height, top, left } = document
.getElementById('carousel-hkvideoid')
.getBoundingClientRect();
if (oWebControl) {
oWebControl.JS_Resize(width, height);
// oWebControl.JS_CuttingPartWindow(left, top, 0, 0);
this.videoWidth = width;
this.videoHeight = height;
this.setWndCover();
}
},
// 初始化+预览
createdVideo() {
this.initPlugin('carousel-hkvideoid', () => {
if (this.playMode == 0) {
previewVideo(this.oWebControl, this.cameraIndexCode);//预览
} else {
startPlayback(this.oWebControl, this.daterangeMonitorTime, this.cameraIndexCode);
}
});
},
// 销毁插件
destroyWnd(cb) {
if (this.oWebControl) {
this.oWebControl.JS_HideWnd();
this.oWebControl
.JS_DestroyWnd({
funcName: "destroyeWnd",
})
.then(function (oData) {
});
} else {
console.log("没有实例");
}
cb && cb();
},
// 销毁并重启
destroyedAndCreate() {
this.destroyWnd(() => {
this.createdVideo();
});
},
// 初始化
init(callback) {
this.getPubKey(() => {
// 请自行修改以下变量值
let appkey = this.config.appkey; //综合安防管理平台提供的appkey,必填
let secret = this.setEncrypt(this.config.secret); //综合安防管理平台提供的secret,必填
let ip = this.config.ip; //综合安防管理平台IP地址,必填
let playMode = this.playMode; //初始播放模式:0-预览,1-回放
let port = this.config.port; //综合安防管理平台端口,若启用HTTPS协议,默认443
let snapDir = "H:\\SnapDir"; //抓图存储路径
let videoDir = "H:\\VideoDir"; //紧急录像或录像剪辑存储路径
let layout = this.layout; //playMode指定模式的布局
let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互,是为1,否为0
let encryptedFields = "secret"; //加密字段,默认加密领域为secret
let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
let showSmart = 0; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
let buttonIDs = "0,16,256,257,258,259,260,512,513,514,515,516,768,769"; //自定义工具条按钮
// 请自行修改以上变量值
this.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, //自定义工具条按钮
toolBarButtonIDs: '4098',//自定义工具栏按钮
}),
})
.then((oData) => {
// 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
this.getDomInfo();
callback && callback();
});
});
},
// 创建播放实例
initPlugin(id, callback) {
let that = this;
this.videoLoad = false;
that.oWebControl = new WebControl({
szPluginContainer: id, // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15900,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
cbConnectSuccess: function () {
// 创建WebControl实例成功
that.oWebControl
.JS_StartService("window", {
// WebControl实例创建成功后需要启动服务
dllPath: "./VideoPluginConnect.dll", // 值"./VideoPluginConnect.dll"写死
})
.then(
function () {
// 启动插件服务成功
that.oWebControl.JS_SetWindowControlCallback({
// 设置消息回调
cbIntegrationCallBack: that.cbIntegrationCallBack,
});
that.oWebControl
.JS_CreateWnd(id, that.videoWidth, that.videoHeight)
.then(() => {
//JS_CreateWnd创建视频播放窗口,宽高可设定
that.init(callback); // 创建播放实例成功后初始化
});
},
function () {
that.oWebControl = null;
that.$message.warning(
`监控插件未启动,正在尝试第${that.initCount + 1}次启动,请稍候...`
);
WebControl.JS_WakeUp("VideoWebPlugin://");
that.initCount++;
if (that.initCount < 3) {
setTimeout(() => that.initPlugin(), 3000);
} else {
that.videoLoad = true; //打开下载提示,请先安装视频插件
}
// 启动插件服务失败
}
);
},
cbConnectError: () => {
// 创建WebControl实例失败
that.oWebControl = null;
that.$message.warning(
`监控插件未启动,正在尝试第${that.initCount + 1}次启动,请稍候...`
);
WebControl.JS_WakeUp("VideoWebPlugin://");
that.initCount++;
if (that.initCount < 3) {
setTimeout(() => that.initPlugin(), 3000);
} else {
that.videoLoad = true; //打开下载提示,请先安装视频插件
}
},
cbConnectClose: (bNormalClose) => {
// 异常断开:bNormalClose = false
// JS_Disconnect正常断开:bNormalClose = true
that.oWebControl = null;
that.$message.warning(
`监控插件未启动,正在尝试第${that.initCount + 1}次启动,请稍候...`
);
WebControl.JS_WakeUp("VideoWebPlugin://");
that.initCount++;
if (that.initCount < 2) {
setTimeout(() => that.initPlugin(), 3000);
} else {
that.videoLoad = true; //打开下载提示,请先安装视频插件
}
},
});
},
// 关闭
handleClose() {
if (this.oWebControl) {
this.oWebControl.JS_RequestInterface({
funcName: "stopAllPreview",
});
this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
this.oWebControl.JS_Disconnect().then(
() => {
// 断开与插件服务连接成功
},
() => {
// 断开与插件服务连接失败
}
);
this.oWebControl = null;
}
},
// 消息回调
cbIntegrationCallBack(oData) {
// console.log(oData);
},
//获取公钥
getPubKey(callback) {
this.oWebControl
.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024,
}),
})
.then((oData) => {
if (oData.responseMsg.data) {
this.pubKey = oData.responseMsg.data;
callback();
}
});
},
//RSA加密
setEncrypt(value) {
let encrypt = new JSEncrypt();
encrypt.setPublicKey(this.pubKey);
return encrypt.encrypt(value);
},
// 设置窗口裁剪,当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
setWndCover() {
let iWidth = $(window).width(); // 获取浏览器宽度 不含滚动条
let iHeight = $(window).height();
let oDivRect = $("#" + 'carousel-hkvideoid')
.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 > this.videoWidth ? this.videoWidth : iCoverLeft;
iCoverTop = iCoverTop > this.videoHeight ? this.videoHeight : iCoverTop;
iCoverRight =
iCoverRight > this.videoWidth ? this.videoWidth : iCoverRight;
iCoverBottom =
iCoverBottom > this.videoHeight ? this.videoHeight : iCoverBottom;
// 多1个像素点防止还原后边界缺失一个像素条
this.oWebControl.JS_RepairPartWindow(
0,
0,
this.videoWidth + 1,
this.videoHeight
);
if (iCoverLeft != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
0,
iCoverLeft,
this.videoHeight
);
}
if (iCoverTop != 0) {
// 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
this.oWebControl.JS_CuttingPartWindow(
0,
0,
this.videoWidth + 1,
iCoverTop
);
}
if (iCoverRight != 0) {
this.oWebControl.JS_CuttingPartWindow(
this.videoWidth - iCoverRight,
0,
iCoverRight,
this.videoHeight
);
}
if (iCoverBottom != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
this.videoHeight - iCoverBottom,
this.videoWidth,
iCoverBottom
);
}
},
// value为字符串,JS_RequestInterface仅接收json格式的变量,且需要先解析出argument,并且将argument字段的内容转为字符串
requestInterface() {
var JsonParam = this.drawOSDParam;
var JsonArgument = JsonParam.argument;
JsonParam.argument = JSON.stringify(JsonArgument);
this.oWebControl.JS_RequestInterface(JsonParam).then(function (oData) {
console.log(oData)
});
},
//关闭弹框,先销毁插件,再关闭弹框
closeVideo() {
this.destroyWnd();
this.$emit("closeHkVideo");
},
getTime(times, status = true, str) {
const time = new Date(times);
const year = time.getFullYear();
const month = (time.getMonth() + 1).toString().padStart(2, "0");
const week = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"][
time.getDay()
];
const day = time.getDate().toString().padStart(2, "0");
const hours = time.getHours().toString().padStart(2, "0");
const minute = time.getMinutes().toString().padStart(2, "0");
const second = time.getSeconds().toString().padStart(2, "0");
if (status) return `${year}-${month}-${day} ${hours}:${minute}:${second}`;
switch (str) {
case "年":
return year;
case "月":
return month;
case "周":
return week;
case "日":
return day;
case "时":
return hours;
case "分":
return minute;
case "秒":
return second;
default:
return `${year}-${month}-${day}`;
}
},
//回放
playBack() {
this.playMode = 1;
if (null == this.daterangeMonitorTime || '' == this.daterangeMonitorTime) {
this.$message({
message: '请选择时间',
type: 'error',
});
return;
}
this.destroyedAndCreate();
},
//选择回放日期时,需要裁剪视频窗口
startTimeFocus() {
if (this.oWebControl) {
this.oWebControl.JS_CuttingPartWindow(this.videoWidth-660, 5, 660, this.videoHeight / 2 -10);
}
},
//完成选择回放日期后,需要恢复视频窗口
startTimeBlur() {
if (this.oWebControl) {
this.oWebControl.JS_RepairPartWindow(this.videoWidth-660, 5, 660, this.videoHeight / 2 - 10);
}
},
},
/* 销毁 */
beforeDestroy() {
this.destroyWnd();
},
};
</script>
<style lang="scss" scoped>
.dialogClass {
width: 100%;
height: 100%;
margin-top: 0px !important;
.el-dialog {
margin-top: 0px !important
}
.el-dialog__body {
width: 100%;
height: 100%;
padding: 0px !important;
}
.el-dialog__header {
display: none;
}
}
.videoContent {
// position: absolute;
// top: 20%;
// left: 20%;
// width: 81.5vw;
// height: 60vh;
z-index: 25;
background-color: #303133 !important;
// border: 2px dashed aquamarine;
position: absolute;
left: 0px;
right: 0px;
bottom: 0px;
top: 0px;
width: 100%;
height: 100%;
.playWnd {
width: 100%;
height: 96%;
// top:4%;
position: relative;
}
.video-tips {
color: #fff;
font-weight: bold;
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
cursor: pointer;
z-index: 30;
}
}
.ulStyle {
text-align: left;
font-size: 20px;
li {
height: 50px;
line-height: 50px;
}
}
</style>
<style>
/*alert 成功弹出框样式*/
.el-message {
padding: 5px 15px;
}
.el-message--error {
top: 5px !important;
}
.el-message .el-icon-error {
font-size: 14px;
}
</style>
hkvideo.js文件:
/**
* 海康视频加载
hkvideo.js
*/
// 预览
export function previewVideo(oWebControl,cameraIndexCode) {
let streamMode = 1; // 主子码流标识:0-主码流,1-子码流
let transMode = 1; // 传输协议:0-UDP,1-TCP
let gpuMode = 0; // 是否启用GPU硬解,0-不启用,1-启用
let wndId = -1; // 播放窗口序号(在2x2以上布局下可指定播放窗口)
oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode.trim(), // 监控点编号
streamMode: streamMode, // 主子码流标识
transMode: transMode, // 传输协议
gpuMode: gpuMode, // 是否开启GPU硬解
wndId: wndId, // 可指定播放窗口
}),
});
};
// 批量预览
export function multiPreviewVideo(oWebControl,cameraIndexCodeList,) {
let streamMode = 1; // 主子码流标识:0-主码流,1-子码流
let transMode = 1; // 传输协议:0-UDP,1-TCP
let gpuMode = 0; // 是否启用GPU硬解,0-不启用,1-启用
oWebControl
.JS_RequestInterface({
funcName: "startMultiPreviewByCameraIndexCode",
argument: JSON.stringify({
list: cameraIndexCodeList.map((camera, idx) => {
return {
cameraIndexCode: camera, //监控点编号
streamMode, //主子码流标识
transMode, //传输协议
gpuMode, //是否开启GPU硬解
wndId: idx + 1, // 播放窗口序号(在2x2以上布局下可指定播放窗口)
};
}), // 监控点编号集合
}),
})
.then((res) => {
if (res.errorCode === 0) {
console.log("预览成功");
}
});
};
//录像回放功能
export function startPlayback(oWebControl,daterangeMonitorTime,cameraIndexCode) {
var startTimeStamp = new Date(daterangeMonitorTime[0]).getTime(); //回放开始时间戳,必填
var endTimeStamp = new Date(daterangeMonitorTime[1]).getTime(); //回放结束时间戳,必填
startTimeStamp = Math.floor(startTimeStamp / 1000).toString();
endTimeStamp = Math.floor(endTimeStamp / 1000).toString();
var recordLocation = 1; //录像存储位置:0-中心存储,1-设备存储
var transMode = 0; //传输协议:0-UDP,1-TCP
var gpuMode = 0; //是否启用GPU硬解,0-不启用,1-启用
var wndId = 1; //播放窗口序号(在2x2以上布局下可指定播放窗口)
oWebControl.JS_RequestInterface({
funcName: "startPlayback",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, //监控点编号
startTimeStamp, //录像查询开始时间戳,单位:秒
endTimeStamp, //录像结束开始时间戳,单位:秒
recordLocation: recordLocation, //录像存储类型:0-中心存储,1-设备存储
transMode: transMode, //传输协议:0-UDP,1-TCP
gpuMode: gpuMode, //是否启用GPU硬解,0-不启用,1-启用
wndId: wndId //可指定播放窗口
})
})
};
// 停止回放
export function stopPlayback(oWebControl) {
oWebControl.JS_RequestInterface({
funcName: "stopAllPlayback"
})
};
// 批量回放
export function multiPlaybackVideo(oWebControl,daterangeMonitorTime,cameraIndexCodeList) {
if (null == daterangeMonitorTime || '' == daterangeMonitorTime) {
this.$modal.msgError("请选择时间");
return;
}
var startTimeStamp = new Date(daterangeMonitorTime[0]).getTime(); //回放开始时间戳,必填
var endTimeStamp = new Date(daterangeMonitorTime[1]).getTime(); //回放结束时间戳,必填
startTimeStamp = Math.floor(startTimeStamp / 1000).toString();
endTimeStamp = Math.floor(endTimeStamp / 1000).toString();
var recordLocation = 1; //录像存储位置:0-中心存储,1-设备存储
var transMode = 0; //传输协议:0-UDP,1-TCP
var gpuMode = 0; //是否启用GPU硬解,0-不启用,1-启用
let dataList = cameraIndexCodeList;
oWebControl
.JS_RequestInterface({
funcName: "startMultiPlaybackByCameraIndexCode",
argument: JSON.stringify({
list: dataList.map((camera, idx) => {
return {
cameraIndexCode: camera, //监控点编号
startTimeStamp, //录像查询开始时间戳,单位:秒
endTimeStamp, //录像结束开始时间戳,单位:秒
recordLocation: recordLocation, //录像存储类型:0-中心存储,1-设备存储
transMode: transMode, //传输协议:0-UDP,1-TCP
gpuMode: gpuMode, //是否启用GPU硬解,0-不启用,1-启用
wndId: idx + 1, // 播放窗口序号(在2x2以上布局下可指定播放窗口)
};
}), // 监控点编号集合
}),
})
.then((res) => {
if (res.errorCode === 0) {
console.log("回放成功");
}
});
};
//RSA加密
export function setEncrypt(value,pubKey) {
let encrypt = new JSEncrypt();
encrypt.setPublicKey(pubKey);
return encrypt.encrypt(value);
};
// 设置窗口裁剪,当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
export function setWndCover(oWebControl,id,videoWidth,videoHeight) {
let iWidth = $(window).width(); // 获取浏览器宽度 不含滚动条
let iHeight = $(window).height();
let oDivRect = $("#" + id)
.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 > videoWidth ? videoWidth : iCoverLeft;
iCoverTop = iCoverTop > videoHeight ? videoHeight : iCoverTop;
iCoverRight =
iCoverRight > videoWidth ? videoWidth : iCoverRight;
iCoverBottom =
iCoverBottom > videoHeight ? videoHeight : iCoverBottom;
// 多1个像素点防止还原后边界缺失一个像素条
oWebControl.JS_RepairPartWindow(
0,
0,
videoWidth + 1,
videoHeight
);
if (iCoverLeft != 0) {
oWebControl.JS_CuttingPartWindow(
0,
0,
iCoverLeft,
videoHeight
);
}
if (iCoverTop != 0) {
// 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
oWebControl.JS_CuttingPartWindow(
0,
0,
videoWidth + 1,
iCoverTop
);
}
if (iCoverRight != 0) {
oWebControl.JS_CuttingPartWindow(
videoWidth - iCoverRight,
0,
iCoverRight,
videoHeight
);
}
if (iCoverBottom != 0) {
oWebControl.JS_CuttingPartWindow(
0,
videoHeight - iCoverBottom,
videoWidth,
iCoverBottom
);
}
};
// value为字符串,JS_RequestInterface仅接收json格式的变量,且需要先解析出argument,并且将argument字段的内容转为字符串
export function requestInterface(oWebControl,drawOSDParam) {
var JsonParam = drawOSDParam;
var JsonArgument = JsonParam.argument;
JsonParam.argument = JSON.stringify(JsonArgument);
oWebControl.JS_RequestInterface(JsonParam).then(function (oData) {
console.log(oData)
});
};
若各位同伴儿有帮助,动动小手指点个赞呀。