项目场景:
项目为智慧园区后台管理系统需求 全部摄像头实时监控&&单个监控直播&&单个监控回放
集成 海康威视监控 WEB插件
网上有非常多的资源代码实例 大多数还需要根据自己的需求改进
实测 完美兼容
演示:
页面监控
弹出层监控
准备
海康开放平台
注册个账号=>下载 =>iSecureCenter=> 视频WEB插件V1.5.1
下载后在bin文件夹 VideoWebPlugin.exe 双击安装 (仅支持Windows)
里面的几个demo非常有用 挨个测试一下 至少知道怎么一回事
最关键 是这个开发指南 所有你想试下的功能 都在里边了
或许能用到的几个网址:
直播地址测试
Vue接入监控视频技术整理
基于vue项目 vue-video-player实现rtmp hls视频流播放
vue cli中播放rtmp&flv/m3u8/rtsp ; 在html原生页面中播放m3u8
vue截图,上传,下载,预览
vue实现播放rtmp直播视频流
阿里云Web端播放器
方案
封装一个海康威视的播放器组件
这里从父组件传入了几个参数 以及一些引入的库 实际开发因人而异
*index :当前组件所属页面 因为由多个页面用到
*type : 回放 || 直播
*code : 监控点编号 监控设备页面String || 实时监控 Array
*time 回放时间设定 暂时废弃
几点注意 :
监控组件的 宽高自适应外层父组件 ;
项目中另外一个监控组件是装在vxe-modal弹出层的,这个modal可以拖拽,拖拽时需要对视频组件进行重新定位,会有卡顿感;
监控视频的显示优先级最高,不知道怎么调整,因此需要确保每次只能初始化一个插件实例;
组件视频采用九宫格3x3展示,超出部分分页实现,我也写过根据监控id总量动态布局,后来默认了;
创建插件实例 initPlugin 这个方法 朝父组件发射了个事件 通知父组件 我这边正在初始化,防止重复加载监控实例;
/**
* @author deep1nBlur
* @email mailbrcee@gmail.com
* @create date 2020-11-05 09:10:05
* @modify date 2020-11-05 09:10:05
* @desc [海康监控视频组件]
* */
<template>
<div
class="root-haikang-video"
id="video-frame"
:style="{
width: sizes.width,
height: sizes.height
}"
>
<div
id="playWnd"
class="playWnd"
v-html="playText"
:style="{ width: swfWidth + 'px', height: swfHeight + 'px' }"
></div>
<el-button-group
v-if="show"
style="margin-top: 5px; display: flex; justify-content: center"
>
<el-button
size="mini"
type="primary"
icon="el-icon-arrow-left"
@click="nextPage('left')"
:disabled="page == 0"
>上一页</el-button
>
<el-button
size="mini"
type="primary"
@click="nextPage('right')"
:disabled="page + 1 == pageNum"
>下一页<i class="el-icon-arrow-right el-icon--right"
/></el-button>
</el-button-group>
</div>
</template>
<script>
import request from "@/utils/request";
import { isArray } from "xe-utils/methods";
export default {
/**
* index :当前组件所属页面 设备管理 为空 ||实时监控 realTime
* type : 回放 || 直播
* code : 监控点编号 监控设备页面String || 实时监控 Array
* time 回放时间 暂时废弃
*/
props: ["index", "type", "code", "time"],
data() {
return {
sizes: {
width: "782px",
height: "490px"
},
layoutFmt: {
1: "1x1",
2: "1x2",
3: "1+2",
4: "2x2",
5: "1+5",
6: "3+4",
7: "3+4",
8: "1+7",
9: "3x3"
},
page: 0,
pageNum: 1,
show: false,
timeRange: "",
swfHeight: "",
swfWidth: "",
//初始化参数
initparam: {},
//监控点编号
pointCode: "",
pubKey: "",
oWebControl: null,
WebControl: null,
playText: "插件正在启动,请稍候..."
};
},
methods: {
nextPage() {
// 实时监控 当code 长度 当大于页面布局 显示 下一页按钮
if (arguments[0] == "left") {
this.page--;
} else {
this.page++;
}
this.startPlay();
},
getInitParams() {
// 获取海康综合安防参数
this.initparam = {};
request({
url: `xxxxxxxxxxxxxxxxxxxxxxxxxxÏ`,
method: "get"
})
.then(res => {
if (res && !res.data.hkApiBackend) {
this.$message({
message: "请完善华为云Roma平台配置!",
type: "error"
});
this.playText = "";
return;
}
this.initparam = res.data;
//页面加载时创建播放实例初始化
this.initPlugin();
})
.catch(err => {
console.log(err);
});
},
// 创建插件实例
initPlugin() {
this.$emit("update:pluginIsInit", true);
this.oWebControl = new WebControl({
szPluginContainer: "playWnd", // 指定容器id
iServicePortStart: 15900, // 指定起止端口号,建议使用该值
iServicePortEnd: 15909,
szClassId: "23BF3B0A-2C56-4D97-9C03-0CB103AA8F11", // 用于IE10使用ActiveX的clsid
// 创建WebControl实例成功
cbConnectSuccess: () => {
this.oWebControl
.JS_StartService("window", {
// WebControl实例创建成功后 启动插件服务接口 参数固定
dllPath: "./VideoPluginConnect.dll" // 值"./VideoPluginConnect.dll"写死
})
.then(
() => {
// 启动插件服务成功
this.oWebControl.JS_SetWindowControlCallback({
// 设置消息回调
cbIntegrationCallBack: this.cbIntegrationCallBack
});
this.oWebControl
.JS_CreateWnd("playWnd", this.swfWidth, this.swfHeight)
.then(() => {
//JS_CreateWnd创建视频播放窗口,宽高可设定
this.init(); // 创建播放实例成功后初始化
});
},
() => {
// 启动插件服务失败
}
);
},
// 创建WebControl实例失败
cbConnectError: () => {
this.oWebControl = null;
this.playText = "插件未启动,正在尝试启动,请稍候...";
this.WebControl.JS_WakeUp("VideoWebPlugin://"); // 程序未启动时执行error函数,采用wakeup来启动程序
this.initCount++;
if (this.initCount < 3) {
setTimeout(() => {
this.initPlugin();
}, 3000);
} else {
this.playText =
'插件启动失败,请检查插件是否安装!<a target="_blank" style="color: #30a8ff;text-decoration: underline;" href=" ' +
this.initparam.hkVideoPlugin +
'">windows下载地址(软件大小:67MB)</a>';
}
},
// 异常断开:bNormalClose = false
cbConnectClose: bNormalClose => {
// JS_Disconnect正常断开:bNormalClose = true
console.log(
"%c海康插件=>插件正常断开",
"color:#00e676",
bNormalClose
);
this.oWebControl = null;
}
});
},
// 设置窗口控制回调
setCallbacks() {
this.oWebControl.JS_SetWindowControlCallback({
cbIntegrationCallBack: this.cbIntegrationCallBack
});
},
// 推送消息
cbIntegrationCallBack(oData) {
console.info(
"%c海康web插件信息推送=>",
"color:#00e676;",
oData.responseMsg
);
/* showCBInfo(JSON.stringify(oData.responseMsg)); */
},
//初始化视频播放
init() {
this.getPubKey(() => {
let appkey = this.initparam.hkAppkey; //综合安防管理平台提供的appkey,必填
let secret = this.setEncrypt(this.initparam.hkSecret); //综合安防管理平台提供的secret,必填
let ip = this.initparam.hkApiBackend.split("//")[1].split(":")[0]; //综合安防管理平台IP地址,必填
let port = this.initparam.hkApiBackend.split("//")[1].split(":")[1]; //综合安防管理平台端口,若启用HTTPS协议,默认443
port = parseInt(port);
let layout = "1x1";
let playMode = this.type == "live" ? 0 : 1; //初始播放模式:0-预览,1-回放
let snapDir = "D:\\SnapDir"; //抓图存储路径
let videoDir = "D:\\VideoDir"; //紧急录像或录像剪辑存储路径
let enableHTTPS = 1; //是否启用HTTPS协议与综合安防管理平台交互,是为1,否为0
let encryptedFields = "secret"; //加密字段,默认加密领域为secret
let showToolbar = 1; //是否显示工具栏,0-不显示,非0-显示
let showSmart = 1; //是否显示智能信息(如配置移动侦测后画面上的线框),0-不显示,非0-显示
let buttonIDs = "256,258,259,260,512,515,516,517,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 //自定义工具条按钮
})
})
.then(oData => {
this.oWebControl.JS_Resize(this.swfWidth, this.swfHeight); // 初始化后resize一次,规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题
this.$emit("update:pluginIsInit", false);
this.playText = "";
if (this.index == "realTime") {
// 实时监控 批量播放 设置布局
if (this.code.length && isArray(this.code)) {
let basicLayout = "1x1"; //基础布局
let totalCode = this.code.length; //实时监控总条数
let layoutPage = Math.ceil(totalCode / 9); //超过十条每页显示十条 向上取整
// console.log("=====总页数", layoutPage);
if (totalCode <= 9) {
basicLayout = this.layoutFmt[totalCode];
} else {
// 大于10 时 按照"2x2" 布局
// 显示下一页 总页数
this.show = true;
this.pageNum = layoutPage;
basicLayout = "3x3";
}
this.oWebControl.JS_RequestInterface({
// 设置窗口布局
funcName: "setLayout",
argument: JSON.stringify({
layout: "3x3" // 窗口布局默认9
})
});
}
}
this.startPlay(); //初始化之后开启预览
});
});
},
// 申请 RSA 公钥,用于对敏感信息(如 appkey、secret)加密。
getPubKey(callback) {
this.oWebControl
.JS_RequestInterface({
funcName: "getRSAPubKey",
argument: JSON.stringify({
keyLength: 1024
})
})
.then(oData => {
// console.log(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 = $("#playWnd")
.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.swfWidth ? this.swfWidth : iCoverLeft;
iCoverTop = iCoverTop > this.swfHeight ? this.swfHeight : iCoverTop;
iCoverRight = iCoverRight > this.swfWidth ? this.swfWidth : iCoverRight;
iCoverBottom =
iCoverBottom > this.swfHeight ? this.swfHeight : iCoverBottom;
this.oWebControl.JS_RepairPartWindow(
0,
0,
this.swfWidth + 1,
this.swfHeight
); // 多1个像素点防止还原后边界缺失一个像素条
if (iCoverLeft != 0) {
this.oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, this.swfHeight);
}
if (iCoverTop != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
0,
this.swfWidth + 1,
iCoverTop
); // 多剪掉一个像素条,防止出现剪掉一部分窗口后出现一个像素条
}
if (iCoverRight != 0) {
this.oWebControl.JS_CuttingPartWindow(
this.swfWidth - iCoverRight,
0,
iCoverRight,
this.swfHeight
);
}
if (iCoverBottom != 0) {
this.oWebControl.JS_CuttingPartWindow(
0,
this.swfHeight - iCoverBottom,
this.swfWidth,
iCoverBottom
);
}
},
//播放监控视频 预览 || 回放 || 批量
startPlay() {
let streamMode = 1; //主子码流标识:0-主码流,1-子码流
let transMode = 1; //传输协议:0-UDP,1-TCP
let gpuMode = 0; //是否启用GPU硬解,0-不启用,1-启用
if (this.index == "realTime") {
// 实时监控 批量播放
// console.log(
// "这是实时页码================================================",
// this.page
// );
if (this.code.length && isArray(this.code)) {
let temp = [];
let arr = [];
if (this.code.length > 9) {
// 大于9 分页显示
arr = this.code.slice(this.page * 9, (this.page + 1) * 9);
} else {
arr = this.code;
}
arr.forEach((item, index) => {
let obj = {};
obj.cameraIndexCode = item.pointInterCode;
obj.wndId = index + 1;
obj.transMode = transMode;
obj.streamMode = streamMode;
obj.gpuMode = gpuMode;
temp.push(obj);
});
this.oWebControl.JS_RequestInterface({
funcName: "startMultiPreviewByCameraIndexCode",
argument: JSON.stringify({
list: temp
})
});
}
} else {
// 监控设备管理 直播 or 回放
let cameraIndexCode = this.code; //获取输入的监控点编号值,必填
let wndId = -1; //播放窗口序号(在2x2以上布局下可指定播放窗口)
cameraIndexCode = cameraIndexCode.replace(/(^\s*)/g, "");
cameraIndexCode = cameraIndexCode.replace(/(\s*$)/g, "");
if (this.type == "live") {
// 视频预览
this.oWebControl.JS_RequestInterface({
funcName: "startPreview",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, //监控点编号
streamMode: streamMode, //主子码流标识
transMode: transMode, //传输协议
gpuMode: gpuMode, //是否开启GPU硬解
wndId: wndId //可指定播放窗口
})
});
} else {
//视频回放
this.oWebControl.JS_RequestInterface({
funcName: "startPlayback",
argument: JSON.stringify({
cameraIndexCode: cameraIndexCode, //监控点编号
startTimeStamp: this.timeRange[0] / 1000, // 录像查询开始时间戳,单位:秒
endTimeStamp: this.timeRange[1] / 1000, // 录像查询结束时间戳,单位:秒
recordLocation: 1, // 录像存储类型 0-中心存储 1-设备存储
transMode: transMode,
gpuMode: gpuMode,
wndId: wndId
})
});
}
}
},
//停止全部预览功能
stopAllPreview() {
this.oWebControl.JS_RequestInterface({
funcName: "stopAllPreview"
});
},
//关闭视频窗口
closeWindow() {
console.log("%c海康插件=>", "color:#00e676;", "关闭页面,销毁插件实例!");
if (this.oWebControl != null) {
this.oWebControl.JS_HideWnd(); // 先让窗口隐藏,规避可能的插件窗口滞后于浏览器消失问题
this.oWebControl.JS_Disconnect().then(
() => {
// 断开与插件服务连接成功
},
() => {
// 断开与插件服务连接失败
}
);
}
}
},
created() {
this.timeRange = this.time;
this.WebControl = WebControl; //调用电脑中的插件
if (this.index == "realTime") {
// 重新计算布局
this.sizes = {
width: this.$parent.$el.clientWidth - 50 + "px",
height: this.$parent.$el.clientHeight - 50 + "px"
};
}
},
mounted() {
this.closeWindow();
this.swfHeight = document.getElementById("video-frame").offsetHeight;
this.swfWidth = document.getElementById("video-frame").offsetWidth;
// 获取海康威视安防配置参数
this.getInitParams();
// 监听resize事件,使插件窗口尺寸跟随DIV窗口变化
$(window).resize(() => {
if (this.oWebControl != null) {
this.oWebControl.JS_Resize(this.swfWidth, this.swfHeight);
this.setWndCover();
}
});
// 监听滚动条scroll事件,使插件窗口跟随浏览器滚动而移动
$(window).scroll(() => {
if (this.oWebControl != null) {
this.oWebControl.JS_Resize(this.swfWidth, this.swfHeight);
this.setWndCover();
}
});
// 监听vxe-modal 拖拽完成事件 仅在监控设备管理页面
if (this.index !== "realTime") {
$(window).mouseup($evt => {
if ($evt.target.className.indexOf("vxe-modal--header") != -1) {
// vxe modal 表头拖拽 动态调整插件位置
console.log(
"%c海康插件=>",
"color:#00e676;",
"Modal被拖拽,动态调整插件位置"
);
if (this.oWebControl != null) {
this.oWebControl.JS_Resize(this.swfWidth, this.swfHeight);
this.setWndCover();
}
}
});
}
},
beforeDestroy() {
$(window).off(); //关闭插件之前 移除jquery所有绑定事件
this.closeWindow(); //关闭插件
},
};
</script>
<style lang="scss" scoped>
.root-haikang-video {
.playWnd {
width: 100%;
height: 100%;
}
}
</style>
组件调用
//展示所有监控时
<haikang
type="live"
index="realTime"
:code="codeList"
:pluginIsInit.sync="pluginIsInit"
/>
//单点监控 直播 或者回放
<haikang
:type="type"
:index="index"
:code="params.pointInterCode"
:time="timeRange"
/>
芜湖 起飞~