vue如何實時展示海康威視攝像頭多畫面?

林恒發表於2024-06-25

🧑‍💻 寫在開頭

點贊 + 收藏 === 學會🤣🤣🤣

關於大屏影片監控有三種解決方案:

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.父元件

<template>
  <hkVideo class="video-img1" :props-data="hkList.camera01" />
  <hkVideo class="video-img1" :props-data="hkList.camera02" />
</template>

  

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,並在父元件引入;

<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原始碼下載

如果對您有所幫助,歡迎您點個關注,我會定時更新技術文件,大家一起討論學習,一起進步。

vue如何實時展示海康威視攝像頭多畫面?

相關文章