vue如何实时展示海康威视摄像头多画面?

关于大屏视频监控有三种解决方案:

1.[海康威视] 优点:实时性强。多画面运行流畅,缺点:会覆盖在DOM最上方无法选中可能会导致样式挤压变形等样式问题

2.flv视频流+nodeServer 优点:可配置性强 缺点:服务端大流量稳定性不确定

3.rtsp视频流(默认带声音播放) 优点:插件稳定,可网页调试视频流; 缺点:需向后端发送rtsp地址

一.下载海康威视[演示示例]

下载解压后有使用说明和SDK使用文档非常详细,这里不做赘述。请仔细阅读。

安装插件后注意打开进程管理器查看如果未运行画面一片黑,需要到安装目录手动运行

输入用户名和密码端口号 然后登录=》开始预览即可打开监控查看了;是不是很简单

这里有很多小伙伴可能找不到IP地址,可下载局域网设备[网络搜索神器]

【知识储备和驱动安装】

[HCWebSDK3.3.0编程指南]

海康威视官方的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-->
<template>
  <hkVideo class="video-img1" :props-data="hkList.camera01" />
  <hkVideo class="video-img1" :props-data="hkList.camera02" />
</template>
<script>
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"
                },
            }
        }
       },
 }
</script>      

以上hkList配置中 注意 loadingTime 和 id;其中loadingTime 建议和上一个时间间隔4S以上,id是动态加载生成填充的DOM树结构; 如果间隔时间不够 或DOM的ID一样 可能出现画面加载不出来、画面覆盖重叠等情况;通过配置这2个参数可以避免这样多个摄像头只需要 增加 hkList的配置项即可;

3.子组件:新建hkvideo.vue,并在父组件引入;


<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源码下载]
 

### 集成海康威视摄像头Vue3及WebRTC-Streamer进行RTSP流媒体处理 #### 准备工作 为了使Vue3项目能够成功连接并播放来自海康威视摄像机的RTSP视频流,需先完成必要的准备工作。这包括安装`webrtc-streamer`服务端软件,并将其配置好以便接收来自IP摄像机的RTSP请求[^1]。 #### 安装依赖库 确保已将`webrtcstreamer.js`和`adapter.min.js`这两个JavaScript文件放置于项目的公共资源目录下(通常是`public/html/libs`)。这些脚本对于建立客户端和服务端之间的通信至关重要[^4]。 #### 创建组件用于显示视频流 创建一个新的Vue组件来负责展示接收到的视频数据。此组件内部会初始化WebRTC连接并向指定URL发起获取媒体流的请求: ```javascript <template> <div class="video-container"> <video ref="remoteVideo" autoplay playsinline></video> </div> </template> <script setup lang="ts"> import { onMounted, ref } from 'vue'; // 导入 WebRTC Streamer 库 import * as WRS from '/libs/webrtcstreamer.js'; const remoteVideo = ref<HTMLVideoElement | null>(null); onMounted(() => { const wsUrl = "wss://your-webrtc-server-url"; // 替换成实际的服务端WebSocket URL let wrs = new WRS.WebRtcStream(); wrs.connect(wsUrl).then((_) => { console.log('Connected to WebSocket'); wrs.play(remoteVideo.value!, "rtsp://admin:password@camera-ip-address/stream").catch(console.error); }).catch(console.error); }); </script> <style scoped> .video-container video { width: 100%; height: auto; } </style> ``` 上述代码片段展示了如何在一个Vue3单文件组件内设置WebRTC连接逻辑,其中包含了对远程视频元素的操作以及向特定路径发送RTSP请求的过程[^2]。 #### 处理常见问题 当遇到诸如无法正常加载视频、画面停滞或其他异常情况时,可以尝试调整网络参数或优化服务器性能;另外也要确认所使用的RTSP地址格式无误,并且用户名密码正确无误。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值