vue如何实时展示海康威视摄像头多画面?
🧑💻 写在开头
点赞 + 收藏 === 学会🤣🤣🤣
关于大屏视频监控有三种解决方案:
1.海康威视 优点:实时性强。多画面运行流畅,缺点:会覆盖在DOM最上方无法选中可能会导致样式挤压变形等样式问题
2.[flv视频流]+[nodeServer] 优点:可配置性强 缺点:服务端大流量稳定性不确定
3.rtsp视频流(默认带声音播放) 优点:插件稳定,可网页调试视频流; 缺点:需向后端发送rtsp地址
一.下载海康威视演示示例
下载解压后有使用说明和SDK使用文档非常详细,这里不做赘述。请仔细阅读。
安装插件后注意打开进程管理器查看如果未运行画面一片黑,需要到安装目录手动运行
输入用户名和密码端口号 然后登录=》开始预览即可打开监控查看了;是不是很简单
这里有很多小伙伴可能找不到IP地址,可下载局域网设备网络搜索神器
【知识储备和驱动安装】
[HCWebSDK3.3.0编程指南] (open.hikvision.com/fileserver/…)
海康威视官方的RTSP最新取流格式如下:
rtsp://用户名:密码@IP:554/Streaming/Channels/101 用户名和密码
IP就是登陆摄像头时候的IP 在浏览器直接输入192.168.1.212回车可打开该摄像头的登录页
可进行对应的设置
rtsp流地址就是rtsp://用户名:密码@192.168.1.212:554/Streaming/Channels/101
二. 测试rtsp流是否可以播放 1.实现RTSP协议推流需要做的配置 1.1关闭萤石云的接入 1.2调整视频编码为H.264 2.安装VLC播放器 在此下载 video mediaplay官网 即(VLC)
安装完成之后 打开VLC播放器
在VLC播放器中打开网络串流 输入rtsp地址
成功的话可以看到所显示的摄像头画面
RTSP流地址正确且取流成功,VLC的界面会显示监控画面。否则会报错,报错信息写在了日志里,在[工具]>[消息]里可以看到
三.函数的调用顺序
现在根据RTSP视频流 和 函数调用顺序来写代码进行实操:
1.在public中引用demo中的3个文件
这里要注意引用顺序,
2.父组件
1 2 3 4 | <template> <hkVideo class = "video-img1" :props-data= "hkList.camera01" /> <hkVideo class = "video-img1" :props-data= "hkList.camera02" /> </template> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | import hkVideo from "../hkvideo.vue" ; export default { name: "videoBox" , components: { hkVideo }, data() { return { // 方案1 hkList: { camera01: { szIP: "192.168.1.218" , //IP地址 szPort: "80" , //端口号 szUsername: "admin" , szPassword: "123456" , iChannelID: 5, //通道ID loadingTime: "1000" , // 多视频窗口睡眠加载时长。同时多个加载会卡死或不显示 width: "420" , height: "350" , type: "camera01" , id: "divPlugin1" }, camera02: { szIP: "192.168.1.218" , //IP地址 szPort: "80" , //端口号 szUsername: "admin" , szPassword: "123456" , iChannelID: 1, loadingTime: "5000" , width: "420" , height: "350" , type: "camera02" , id: "divPlugin2" }, } } }, } |
以上hkList配置中 注意 loadingTime 和 id;其中loadingTime 建议和上一个时间间隔4S以上,id是动态加载生成填充的DOM树结构; 如果间隔时间不够 或DOM的ID一样 可能出现画面加载不出来、画面覆盖重叠等情况;通过配置这2个参数可以避免 这样多个摄像头只需要 增加 hkList的配置项即可;
3.子组件:新建hkvideo.vue,并在父组件引入;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 | <template> <div style= "position: relative;height: 100%;text-align: center;" > <div :id= "newId" class = "plugin" ></div> </div> </template> <script> export default { name: 'hkVideo' , inheritAttrs: false , props:{ propsData:{ type: Object || Array, require: true } }, watch:{ propsData: { deep: true , immediate: true , handler(newVal, oldVal) { if (newVal){ this .camera152 = newVal this .newId = newVal.id; let t = newVal.loadingTime || 1000 setTimeout(() => { this .initS(); },t) } else { this .camera152 = { szIP: "192.168.1.218" , //IP地址 szPort: "80" , //端口号 szUsername: "admin" , //用户名 szPassword: "123456" , //管理员密码 iChannelID: 5, loadingTime: "3000" , width: "800" , height: "360" , type: "camera01" , id: "divPlugin1" } this .initS(); } } } }, data() { return { camera152:{}, newId: null }; }, mounted() { console.log( '插件下载地址:https://open.hikvision.com/download/5cda567cf47ae80dd41a54b3?type=10&id=4c945d18fa5f49638ce517ec32e24e24' ); // this.initS(); }, methods: { // 销毁插件 解决窗口在其他页面显示可以在切换页面时销毁 回到当前页时重新加载 destruction() { WebVideoCtrl.I_DestroyPlugin(); console.log( "播放窗口插件销毁" ); }, async initS() { let that = this ; // 初始化 await WebVideoCtrl.I_InitPlugin({ bWndFull: true , //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持 iWndowType: 1, // 画面分割数 1 就是1*1 2就是2*2 cbSelWnd: function (xmlDoc) { //此属性是窗口分割切换窗口时触发 // that.clickStartRealPlay(); // console.log("当前选择的窗口编号是1"); }, cbInitPluginComplete: function () { WebVideoCtrl.I_InsertOBJECTPlugin(that.newId).then( () => { // 检查插件是否最新 WebVideoCtrl.I_CheckPluginVersion().then((bFlag) => { if (bFlag) { let str = "检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!" ; that.$message.error(str); console.log(str); } }); }, () => { let str1 = "插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!" ; that.$message.error(str1); console.log(str1); } ); }, }); setTimeout(() => { let cw = Math.round(document.body.clientWidth/1920); let ch = Math.round(document.body.clientHeight/1080); let width = parseInt(( this .camera152.width*cw),10); let height = parseInt(( this .camera152.height*ch),10); if (height <= 200){ height = 200; } if (height <= 200){ height = 200; } let w1 = (window.innerWidth - document.getElementById(that.newId).offsetLeft) - 1500; let w2 = document.getElementById(that.newId).clientHeight; console.log( '00000===>' ,width,height); // 对窗口大小重新规划 WebVideoCtrl.I_Resize( width, height ); this .setVideoWindowResize(that.newId,width,height); this .clickLogin(); }, 2000); }, // 根据设备宽高和windowchange设置窗口大小 setVideoWindowResize(pid,width,height){ document.getElementById(pid).style.width = width + 'px' ; document.getElementById(pid).style.height = height + 'px' ; }, // 登录 clickLogin() { let that = this ; var szIP = this .camera152.szIP, szPort = this .camera152.szPort, szUsername = this .camera152.szUsername, szPassword = this .camera152.szPassword; const iRet = WebVideoCtrl.I_Login(szIP, 1, szPort, szUsername, szPassword, { timeout: 3000, success: function (xmlDoc) { setTimeout(function () { setTimeout(function() { that.getChannelInfo(); }, 1000); that.getDevicePort(); }, 10); }, error: function (err) { console.log( "登录-err===>" ,err); }, }); if (iRet === -1) { console.log( this .szDeviceIdentify + " 已登录过!" ); // 登录过直接进行预览 this .clickStartRealPlay(); } }, // 获取端口 getDevicePort() { var szDeviceIdentify = this .camera152.szIP; if ( null == szDeviceIdentify) { return ; } WebVideoCtrl.I_GetDevicePort(szDeviceIdentify).then((oPort) => { console.log( "152获取端口" ,oPort); }); }, // 获取通道 async getChannelInfo() { let that = this ; var szDeviceIdentify = this .camera152.szIP+ '_' + this .camera152.szPort; if ( null == szDeviceIdentify) { return ; } console.log( 'szDeviceIdentify==============>' ,szDeviceIdentify); // 模拟通道 WebVideoCtrl.I_GetAnalogChannelInfo(szDeviceIdentify, { success: function (xmlDoc) { that.clickStartRealPlay(); }, error: function (oError) { console.log(szDeviceIdentify + "模拟通道" , oError.errorCode, oError.errorMsg); } }); // 数字通道 WebVideoCtrl.I_GetDigitalChannelInfo(szDeviceIdentify, { success: function (xmlDoc) { that.clickStartRealPlay(); }, error: function (oError) { console.log(szDeviceIdentify + " 数字通道" , oError.errorCode, oError.errorMsg); } }); }, // 开始预览 clickStartRealPlay(iStreamType) { let that = this ; var g_iWndIndex = 0; var oWndInfo = WebVideoCtrl.I_GetWindowStatus(g_iWndIndex) || null ; var szDeviceIdentify = this .camera152.szIP+ '_' + this .camera152.szPort, iChannelID = this .camera152.iChannelID, // 5=>4楼测试电子 2=>4楼前台 1=>4楼后门 bZeroChannel = false ; if ( "undefined" === typeof iStreamType) { iStreamType = 1; } if ( null == szDeviceIdentify) { return ; } var startRealPlay = function () { WebVideoCtrl.I_StartRealPlay(szDeviceIdentify, { iStreamType: iStreamType, iChannelID: iChannelID, bZeroChannel: bZeroChannel, success: function () { WebVideoCtrl.I_Logout(szDeviceIdentify) console.log( "开始预览成功!" ); }, error: function (oError) { // that.$message.error(szDeviceIdentify+"开始预览失败!"); console.log(szDeviceIdentify+ "开始预览失败!" ); }, }); }; if (oWndInfo != null ) { // 已经在播放了,先停止 WebVideoCtrl.I_Stop({ success: function () { startRealPlay(); } }); } else { startRealPlay(); } }, // 停止预览 clickStopRealPlay() { WebVideoCtrl.I_Stop({ success: function () { console.log( "停止预览成功!" ); }, error: function (oError) { console.log( " 停止预览失败!" ); }, }); }, loginOut(){ WebVideoCtrl.I_Logout( this .szDeviceIdentify); }, stopAllPlay(){ WebVideoCtrl.I_StopAllPlay(); }, breakDom(){ WebVideoCtrl.I_DestroyPlugin() }, viewReload(){ window.location.reload() }, }, beforeDestroy(){ this .loginOut(); this .stopAllPlay(); window.removeEventListener( this .viewReload); }, destroyed() { setTimeout(() => { this .breakDom(); },100) }, }; </script> <style scoped lang= "less" > .plugin { height: 350px; width: 490px; margin-top: 10px; } </style> |
展示正常!功能没问题;gitee源码下载
__EOF__
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 本地部署 DeepSeek:小白也能轻松搞定!
· 如何给本地部署的DeepSeek投喂数据,让他更懂你
· 从 Windows Forms 到微服务的经验教训
· 李飞飞的50美金比肩DeepSeek把CEO忽悠瘸了,倒霉的却是程序员
· 超详细,DeepSeek 接入PyCharm实现AI编程!(支持本地部署DeepSeek及官方Dee
2023-06-25 记录--强制缓存这么暴力,为什么不使用协商缓存
2021-06-25 TP6框架--EasyAdmin学习笔记:列表调用搜索,开发常见问题记录