How to Build a Multi‑Camera Selection and Multi‑Window Preview with SpringBoot, Vue, and Hikvision (Plugin Edition)
This guide walks through integrating Hikvision cameras into a SpringBoot‑Vue application, covering SDK download, backend‑frontend code generation, Vue table multi‑selection limited to four cameras, IE‑mode detection, plugin installation, camera login, real‑time playback, and clean shutdown.
This article demonstrates how to integrate Hikvision cameras into a SpringBoot‑Vue project to enable multi‑camera selection and multi‑window preview using the official WebVideoCtrl plugin.
1. Download the Hikvision Web Development Package
The device does not support WebSocket streaming, so the 3.0 development package is required. The package provides sample code and the WebVideoCtrl.js library.
2. Generate Backend and Frontend Code for Camera Parameters
Using the earlier tutorial, create database tables and generate CRUD code to manage camera IP, port, username, and password.
3. Vue Multi‑Selection Table
In the Vue component, an <el-table> is used with selection enabled. The selection handler stores the chosen rows and limits the number to four to avoid browser slowdown.
<el-table v-loading="loading" :data="videoList" @selection-change="handleSelectionChange"> handleSelectionChange(selection) {
this.openVideoData = [];
this.openVideoData = selection;
this.ids = selection.map(item => item.id);
this.single = selection.length !== 1;
this.multiple = !selection.length;
},4. Preview Button and Routing
The preview button is disabled when no cameras are selected. Clicking it resolves a new route /carVideo and passes the selected camera data as a JSON string.
<el-button type="success" plain icon="el-icon-setting" size="mini" :disabled="multiple" @click="videoChange">预览</el-button> videoChange() {
let routeUrl = this.$router.resolve({
path: "/carVideo",
query: { videoData: JSON.stringify(this.openVideoData) }
});
if (this.openVideoData.length > 4) {
this.$notify({ title: "失败", message: "最多支持预览选择4个摄像头", type: "error" });
} else {
window.open(routeUrl.href, "_blank");
}
},5. Add the Preview Route
In src/router/index.js a hidden route for the preview page is added.
{
path: '/carVideo',
component: Layout,
component: (resolve) => require(['@/views/system/cameramap/component/video'], resolve),
meta: { title: '摄像头' },
hidden: true
},6. Import the Plugin Library
Create a static folder in the project root and place webVideoCtrl.js there. Then import it in video.vue:
import { WebVideoCtrl } from "/static/webVideoCtrl.js";7. Detect IE/Compatibility Mode
The camera SDK only works in IE mode. The component checks the user‑agent and shows an error if the browser is not IE.
created() {
if (this.ua.match(/msie/) != null || this.ua.match(/trident/) != null) {
this.browserType = "IE";
this.videoData = JSON.parse(this.$route.query.videoData);
if (this.videoData.length <= 1) {
this.iWndowType = 1;
} else if (this.videoData.length > 1 && this.videoData.length <= 4) {
this.iWndowType = 2;
}
} else {
this.$notify({ title: "失败", message: "请在ie模式下查看摄像头", type: "error" });
}
},8. Initialize the Plugin
The component checks whether the plugin is installed. If not, it prompts the user to download WebComponentsKit.exe and redirects to it.
videoInitPlugin() {
this.$nextTick(() => {
var iRet = WebVideoCtrl.I_CheckPluginInstall();
if (iRet === -1) {
this.myFunction();
return;
}
this.initPlugin();
});
},
myFunction() {
var r = confirm("您还未安装过插件,请下载后查看摄像!");
if (r == true) {
window.location.href = "/WebComponentsKit.exe";
}
},9. Login to Each Selected Camera
For every selected camera, I_Login is called with the stored IP, port, username, and password. On success the channel list and RTSP port are retrieved, then playback starts.
async onLogin() {
var that = this;
that.loginLoading = true;
WebVideoCtrl.I_Login(
that.hkvInfo.ip,
that.iProtocol,
that.hkvInfo.port,
that.hkvInfo.username,
that.hkvInfo.password,
{
async: false,
success: (xmlDoc) => {
that.getChannelInfo();
that.getDevicePort(that.hkvInfo.ip + "_" + that.hkvInfo.port);
that.loginLoading = false;
this.clickStartRealPlay();
},
error: function () {
that.loginLoading = false;
that.$message({ showClose: true, message: "登录失败", type: "error" });
}
}
);
},10. Start Real‑Time Playback
After a successful login, I_StartRealPlay is invoked for each camera channel. Errors such as unsupported WebSocket streaming (status 403) are logged.
clickStartRealPlay() {
console.log("开始预览", this.index);
this.startPlayLoading = true;
var szDeviceIdentify = this.hkvInfo.ip + "_" + this.hkvInfo.port;
this.startRealPlay(szDeviceIdentify, this.index, this.hkvInfo.channels[0]);
this.startPlayLoading = false;
},
startRealPlay(szDeviceIdentify, iWndIndex, iChannelID) {
var that = this;
WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, {
iRtspPort: that.iRtspPort,
iWndIndex: iWndIndex,
iChannelID: iChannelID,
bZeroChannel: that.bZeroChannel,
success: function () {},
error(status, xmlDoc2) {
console.log(xmlDoc2);
if (status === 403) {
console.log("szInfo 设备不支持Websocket取流!");
} else {
console.log("开始预览失败 ", status, xmlDoc2);
}
}
});
},11. Clean Up on Component Destruction
When the preview page is closed, all playback windows are stopped and each camera is logged out.
destroyed() {
this.clickStopRealPlay();
this.onLogout();
},
clickStopRealPlay: function () {
for (var i = 0; i <= this.index; i++) {
setTimeout(this.stopRealPlay(i), 1000);
}
},
stopRealPlay: function (iWndIndex) {
var that = this;
WebVideoCtrl.I_Stop({
iWndIndex: iWndIndex,
success: function () {},
error: function () {}
});
},
onLogout() {
this.videoData.forEach((element) => {
var szDeviceIdentify = element.ip + "_" + element.port;
var iRet = WebVideoCtrl.I_Logout(szDeviceIdentify);
// iRet === 0 indicates success
});
},Following these steps results in a functional multi‑camera preview page that respects the four‑camera limit, works only in IE mode, and gracefully handles plugin installation, login, playback, and logout.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
The Dominant Programmer
Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
