Prechádzať zdrojové kódy

1、视频墙完善

slowslo 4 rokov pred
rodič
commit
9f85d172a4

+ 0 - 2
src/components/scene/wvp/jessibuca.vue

@@ -11,8 +11,6 @@
         </div>
         <div class="buttons-box-right">
           <span class="jessibuca-btn">{{kBps}} kb/s</span>
-<!--          <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->
-<!--          <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>-->
           <i class="icon-jietu jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)" style="font-size: 0.2rem !important"></i>
           <i class="icon-shuaxin jessibuca-btn" @click="playBtnClick"></i>
           <i v-if="!fullscreen" class="iconfont icon-quanping  jessibuca-btn" @click="fullscreenSwich"></i>

+ 116 - 69
src/views/videoapply/comp/jessibuca.vue

@@ -1,31 +1,26 @@
 <template>
-  <div id="jessibuca" style="width: auto; height: auto">
-    <div id="container" ref="container" style="width: 100%; height: 10rem; background-color: #000" @dblclick="fullscreenSwich">
-      <div class="buttons-box" id="buttonsBox">
-        <div class="buttons-box-left">
-          <i v-if="!playing" class="iconfont icon-bofang jessibuca-btn" @click="playBtnClick"></i>
-          <i v-if="playing" class="iconfont icon-zanting jessibuca-btn" @click="pause"></i>
-          <i class="icon-stop jessibuca-btn" @click="destroy"></i>
-          <i v-if="isNotMute" class="iconfont icon-hanhan-01-01 jessibuca-btn" @click="jessibuca.mute()"></i>
-          <i v-if="!isNotMute" class="iconfont icon-jingyin  jessibuca-btn" @click="jessibuca.cancelMute()"></i>
-        </div>
-        <div class="buttons-box-right">
-          <span class="jessibuca-btn">{{kBps}} kb/s</span>
-<!--          <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->
-<!--          <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>-->
-          <i class="icon-jietu jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)" style="font-size: 0.2rem !important"></i>
-          <i class="icon-shuaxin jessibuca-btn" @click="playBtnClick"></i>
-          <i v-if="!fullscreen" class="iconfont icon-quanping  jessibuca-btn" @click="fullscreenSwich"></i>
-          <i v-if="fullscreen" class="iconfont icon-tuichuquanping  jessibuca-btn" @click="fullscreenSwich"></i>
-        </div>
+    <div>
+      <div :id="container" :ref="container" class="container-shell"></div>
+<!--      <div class="buttons-box" id="buttonsBox">-->
+<!--        <div class="buttons-box-left">-->
+<!--          <i v-if="!playing" class="iconfont icon-bofang jessibuca-btn" @click="playBtnClick"></i>-->
+<!--          <i v-if="playing" class="iconfont icon-zanting jessibuca-btn" @click="pause"></i>-->
+<!--          <i class="icon-stop jessibuca-btn" @click="destroy"></i>-->
+<!--          <i v-if="isNotMute" class="iconfont icon-hanhan-01-01 jessibuca-btn" @click="jessibuca.mute()"></i>-->
+<!--          <i v-if="!isNotMute" class="iconfont icon-jingyin  jessibuca-btn" @click="jessibuca.cancelMute()"></i>-->
+<!--        </div>-->
+<!--        <div class="buttons-box-right">-->
+<!--          <span class="jessibuca-btn">{{kBps}} kb/s</span>-->
+<!--          <i class="icon-jietu jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)" style="font-size: 0.2rem !important"></i>-->
+<!--          <i class="icon-shuaxin jessibuca-btn" @click="playBtnClick"></i>-->
+<!--          <i v-if="!fullscreen" class="iconfont icon-quanping  jessibuca-btn" @click="fullscreenSwich"></i>-->
+<!--          <i v-if="fullscreen" class="iconfont icon-tuichuquanping  jessibuca-btn" @click="fullscreenSwich"></i>-->
+<!--        </div>-->
+<!--      </div>-->
     </div>
-
-    </div>
-  </div>
 </template>
 
 <script scope>
-  // import "@/styles/wvp/css/iconfont.css"
   export default {
     name: 'jessibuca',
     data() {
@@ -47,52 +42,43 @@
           forceNoOffscreen: false,
         };
     },
-    props: ['videoUrl', 'error', 'hasAudio', 'height'],
+    props: ['videoUrl', 'error', 'hasAudio', 'height', 'jessibucaId', 'container', 'buttonsBoxId'],
     mounted () {
       window.onerror = (msg) => {
-        // console.error(msg)
+
       };
       let paramUrl = decodeURIComponent(this.$route.params.url)
        this.$nextTick(() =>{
-         let dom = document.getElementById("container");
-         dom.style.height = (9/16 ) * dom.clientWidth + "px"
+         console.log('container=====' + this.container)
+         let dom = document.getElementById(this.container);
           if (typeof (this.videoUrl) == "undefined") {
             this.videoUrl = paramUrl;
           }
-         this.btnDom = document.getElementById("buttonsBox");
+         this.btnDom = document.getElementById(this.buttonsBoxId);
           console.log("初始化时的地址为: " + this.videoUrl)
-         this.play(this.videoUrl)
         })
     },
-    watch:{
-        videoUrl(newData, oldData){
-            this.play(newData)
-        },
-        immediate:true
-    },
     methods: {
-        create(){
+      create(){
           let options =  {};
-          console.log(this.$refs.container)
-          console.log("hasAudio  " + this.hasAudio)
-
+          console.log(this.$refs['container' + this.container.charAt(this.container.length-1)]);
           this.jessibuca = new window.Jessibuca(Object.assign(
             {
-              container: this.$refs.container,
+              container: document.getElementById(this.container),
               videoBuffer: 0.5, // 最大缓冲时长,单位秒
               isResize: true,
+              isFullResize: true,
               decoder: "./js/jessibuca/index.js",
-              // text: "WVP-PRO",
-              // background: "bg.jpg",
+              background: "bg.jpg",
               loadingText: "加载中",
               hasAudio: typeof (this.hasAudio) =="undefined"? true: this.hasAudio,
               debug: false,
               supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。
               operateBtns: {
-                fullscreen: false,
-                screenshot: false,
-                play: false,
-                audio: false,
+                fullscreen: true,
+                screenshot: true,
+                play: true,
+                audio: true,
               },
               record: "record",
               vod: this.vod,
@@ -101,7 +87,6 @@
             },
             options
           ));
-
           let _this = this;
           this.jessibuca.on("load", function () {
             console.log("on load init");
@@ -195,10 +180,10 @@
 
           });
         },
-        playBtnClick: function (event){
+      playBtnClick: function (event){
           this.play(this.videoUrl)
         },
-        play: function (url) {
+      play: function (url) {
           console.log(url)
             if (this.jessibuca) {
               this.destroy();
@@ -218,7 +203,7 @@
               });
             }
         },
-        pause: function () {
+      pause: function () {
           if (this.jessibuca) {
             this.jessibuca.pause();
           }
@@ -226,35 +211,39 @@
           this.err = "";
           this.performance = "";
         },
-        destroy: function () {
-          if (this.jessibuca) {
-            this.jessibuca.destroy();
-          }
-          if (document.getElementById("buttonsBox") == null) {
-            document.getElementById("container").appendChild(this.btnDom)
-          }
-          this.jessibuca = null;
-          this.playing = false;
-          this.err = "";
-          this.performance = "";
+      destroy: function () {
+        if (this.jessibuca) {
+          this.jessibuca.destroy();
+        }
+        // if (document.getElementById(this.buttonsBoxId) == null) {
+        //   document.getElementById(this.container).appendChild(this.btnDom)
+        // }
+        this.create();
+        this.jessibuca = null;
+        this.playing = false;
+        this.err = "";
+        this.performance = "";
 
         },
-        eventcallbacK: function(type, message) {
+      eventcallbacK: function(type, message) {
             // console.log("player 事件回调")
             // console.log(type)
             // console.log(message)
         },
-        fullscreenSwich: function (){
-            let isFull = this.isFullscreen()
-            this.jessibuca.setFullscreen(!isFull)
-            this.fullscreen = !isFull;
+      fullscreenSwitch: function (){
+          let isFull = this.isFullscreen()
+          this.jessibuca.setFullscreen(!isFull)
+          this.fullscreen = !isFull;
         },
-        isFullscreen: function (){
+      isFullscreen: function (){
           return document.fullscreenElement ||
             document.msFullscreenElement  ||
             document.mozFullScreenElement ||
             document.webkitFullscreenElement || false;
-        }
+        },
+      resize(){
+        this.jessibuca.resize();
+      }
     },
     destroyed() {
       if (this.jessibuca) {
@@ -271,7 +260,7 @@
   .buttons-box{
     width: 100%;
     height: 28px;
-    background-color: rgba(43, 51, 63, 0.7);
+    background-color: #000000;
     position: absolute;
     display: -webkit-box;
     display: -ms-flexbox;
@@ -295,4 +284,62 @@
     position: absolute;
     right: 0;
   }
+  .containerClass{
+    background-color: #000;
+  }
+  .container-shell {
+    backdrop-filter: blur(5px);
+    background: #000000;
+    width: auto;
+    position: relative;
+    border-radius: 5px;
+    box-shadow: 0 5px 5px;
+  }
+  .container-shell:before {
+    position: absolute;
+    color: darkgray;
+    top: 4px;
+    left: 10px;
+    text-shadow: 1px 1px black;
+  }
+  .input {
+    display: flex;
+    margin-top: 10px;
+    color: white;
+    place-content: stretch;
+  }
+  .input2 {
+    bottom: 0px;
+  }
+  .input input {
+    flex: auto;
+  }
+  .err {
+    position: absolute;
+    top: 40px;
+    left: 10px;
+    color: red;
+  }
+  .option {
+    position: absolute;
+    top: 4px;
+    right: 10px;
+    display: flex;
+    place-content: center;
+    font-size: 12px;
+  }
+  .option span {
+    color: white;
+  }
+  .page {
+    background: url(/bg.jpg);
+    background-repeat: no-repeat;
+    background-position: top;
+  }
+  @media (max-width: 720px) {
+    #container {
+      width: 90vw;
+      height: 52.7vw;
+    }
+  }
 </style>

+ 72 - 48
src/views/videoapply/comp/videowall.vue

@@ -35,37 +35,19 @@
       </el-col>
       <el-col :span="20">
         <basic-container>
-          <div>
+          <div style="margin-bottom: 20px">
             <el-radio-group v-model="screen" size="mini" @change="screenChange">
               <el-radio-button :label="4">四屏</el-radio-button>
               <el-radio-button :label="6">六分屏</el-radio-button>
               <el-radio-button :label="9">九分屏</el-radio-button>
               <el-radio-button :label="16">十六分屏</el-radio-button>
-<!--              <el-radio-button :label="0">重置</el-radio-button>-->
             </el-radio-group>
           </div>
-          <div id="videoSurveillance" style="margin-top: 20px;">
-            <div class="item4" v-for="(item,index) in data4" :key="index" v-if="screen == 4">
-              <div align="center">{{item.name}}</div>
-              <video :id="'videoId' + index" controls="true" width="100%" height="100%">
-              </video>
-            </div>
-            <div class="item6" v-for="(item,index) in data6" :key="index" v-if="screen == 6">
-              <div align="center">{{item.name}}</div>
-              <video :id="'videoId' + index" controls="true" width="100%" height="100%">
-              </video>
-            </div>
-            <div class="item9" v-for="(item,index) in data9" :key="index" v-if="screen == 9">
-              <div align="center">{{item.name}}</div>
-              <video :id="'videoId' + index" controls="true" width="100%" height="100%">
-              </video>
-            </div>
-            <div class="item16" v-for="(item,index) in data16" :key="index" v-if="screen == 16">
-              <div align="center">{{item.name}}</div>
-              <video :id="'videoId' + index" controls="true" width="100%" height="100%">
-              </video>
-            </div>
-          </div>
+          <el-row :gutter="4">
+            <el-col :span="screenSpan" v-for="(item,index) in screenData" :key="index">
+              <player class="itemClass" :jessibucaId="'jessibucaId' + index" :container="'container' + index" :buttonsBoxId="'buttonsBoxId' + index" :ref="'videoPlayer' + index" :hasaudio="hasaudio" fluent autoplay live ></player>
+            </el-col>
+          </el-row>
         </basic-container>
       </el-col>
     </el-row>
@@ -73,12 +55,16 @@
 
 <script>
     import {getGbChannelLazyTree, startPlay, stopPlay} from "@/api/device/gb/gbdevicechannel";
+    import player from './jessibuca.vue'
     export default {
       name: "videowall",
+      components: {player},
       data () {
         return {
+          screenSpan: 12,
           screen: 4,
           screenData:[],
+          playerRef: "4videoPlayer",
           filterText: '',
           treeData : [],
           treeProps:{
@@ -105,10 +91,31 @@
       created(){
         this.initData();
       },
+      computed: {
+        classItem: function () {
+          if(this.screen == 4){
+            return {
+              item4 : true
+            }
+          }else if(this.screen == 6){
+            return {
+              item6 : true
+            }
+          }else if(this.screen == 9){
+            return {
+              item9 : true
+            }
+          }else if(this.screen == 16){
+            return {
+              item16 : true
+            }
+          }
+        }
+      },
       methods:{
         initData(){
           for(let i = 0; i < 16; i++){
-            let item = {name:"", isPlay:false, index:i, channelId:null};
+            let item = {name:"", isPlay:false, index:i, channelId:null, display:true};
             if(i <= 3){
               this.data4.push(item);
               this.data6.push(item);
@@ -125,17 +132,38 @@
               this.data16.push(item);
             }
           }
+          this.screenData = this.data4;
+          this.$nextTick(() =>{
+            for(let i = 0; i < this.screenData.length; i++){
+              let containerDom = document.getElementById("container" + i);
+              containerDom.style.height = (9/16) * containerDom.clientWidth + "px";
+              console.log(containerDom.style.height)
+            }
+          });
         },
         screenChange(value){
           if(value === 4){
+            this.screenSpan = 12;
             this.screenData = this.data4;
           }else if(value === 6){
+            this.screenSpan = 8;
             this.screenData = this.data6;
           }else if(value === 9){
+            this.screenSpan = 8;
             this.screenData = this.data9;
           }else if(value === 16){
+            this.screenSpan = 6;
             this.screenData = this.data16;
           }
+          this.$nextTick(() =>{
+            for(let i = 0; i < this.screenData.length; i++){
+              let containerDom = document.getElementById("container" + i);
+              containerDom.style.height = (9/16) * containerDom.clientWidth + "px";
+              if(this.screenData[i].isPlay){
+                this.$refs['videoPlayer' + i][0].resize();
+              }
+            }
+          });
         },
         treeLoad(node, resolve){
           const parentId = (node.level === 0) ? null : node.data.id;
@@ -187,14 +215,16 @@
           //找到第一个没有播放的屏幕
           let emptyIndex = this.screenData.findIndex((item) => item.isPlay == false);
           if(emptyIndex >= 0){ //表示找到
-            this.playVideo(data, emptyIndex);
-            this.screenData[emptyIndex].isPlay = true;
-            this.screenData[emptyIndex].channelId = data.channelId;
+            this.playVideo(data, emptyIndex).then(res => {
+              this.screenData[emptyIndex].isPlay = true;
+              this.screenData[emptyIndex].channelId = data.channelId;
+            });
             return false;
           }else{
-            this.playVideo(data, 0);
-            this.screenData[0].isPlay = true;
-            this.screenData[0].channelId = data.channelId;
+            this.playVideo(data, 0).then(res => {
+              this.screenData[0].isPlay = true;
+              this.screenData[0].channelId = data.channelId;
+            });
           }
         },
         playVideo(treeItem, index){
@@ -202,33 +232,19 @@
           let channelId = treeItem.channelId;
           startPlay(deviceId, channelId).then(res => {
             if (res.data.data) {
-              let streamInfo = res.data.data
-              try {
-                let videoElement = document.getElementById("videoId" + index);
-                let flvPlayer = flvjs.createPlayer({
-                  type: 'flv',
-                  url: streamInfo.ws_flv
-                });
-                flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {});
-                flvPlayer.on(flvjs.Events.MEDIA_SOURCE_CLOSE || flvjs.Events.MEDIA_SOURCE_ENDED, () => {});
-                flvPlayer.attachMediaElement(videoElement);
-                flvPlayer.load();
-                flvPlayer.play();
-                treeItem.isPlay = true;
-              } catch (e) {
-                console.log(e);
-              }
+              let streamInfo = res.data.data;
+              this.$refs['videoPlayer' + index][0].play(streamInfo.ws_flv);
             }
           });
         },
         clickStop(node, treeItem){
           this.$message.warning("正在停止");
-          let screenData = null;
           let deviceId = treeItem.deviceId;
           let channelId = treeItem.channelId;
           let channelVideoIndex = this.screenData.findIndex((item,index) => {return item.channelId == treeItem.channelId});
           stopPlay(deviceId, channelId).then(res => {
             this.$message.success("停止成功");
+            this.$refs['videoPlayer' + channelVideoIndex][0].destroy();
             this.screenData[channelVideoIndex].isPlay = false;
             this.screenData[channelVideoIndex].channelId = null;
           });
@@ -261,6 +277,7 @@
       overflow: hidden;
       border-radius: 5px;
       margin: 5px;
+      position: sticky;
     }
 
     .item6 {
@@ -268,6 +285,7 @@
       overflow: hidden;
       border-radius: 5px;
       margin: 5px;
+      position: sticky;
     }
 
     .item9 {
@@ -275,6 +293,7 @@
       overflow: hidden;
       border-radius: 5px;
       margin: 5px;
+      position: sticky;
     }
 
     .item16 {
@@ -282,8 +301,13 @@
       overflow: hidden;
       border-radius: 5px;
       margin: 5px;
+      position: sticky;
     }
   }
+  .itemClass {
+    position: sticky;
+  }
+  //}
   .custom-tree-node {
     flex: 1;
     display: flex;

+ 333 - 0
src/views/videoapply/comp/videowallbak2.vue

@@ -0,0 +1,333 @@
+<template>
+    <el-row>
+      <el-col :span="4">
+        <div class="box">
+          <el-scrollbar>
+            <basic-container>
+              <el-input
+                placeholder="输入关键字进行过滤"
+                v-model="filterText">
+              </el-input>
+              <el-tree ref="tree" class="filter-tree" :props="treeProps" :data="treeData" @node-click="handleNodeClick"
+                       lazy :load="treeLoad":filter-node-method="filterNode">
+                <span class="custom-tree-node" slot-scope="{ node, data }">
+                  <span>{{ node.label }}</span>
+                  <span v-if="node.isLeaf">
+                    <el-button
+                      type="text"
+                      size="mini"
+                      @click="() => clickPlay(data)">
+                      播放
+                    </el-button>
+                    <el-button
+                      style="color:red"
+                      type="text"
+                      size="mini"
+                      @click="() => clickStop(node, data)">
+                      停止
+                    </el-button>
+                  </span>
+                </span>
+              </el-tree>
+            </basic-container>
+          </el-scrollbar>
+        </div>
+      </el-col>
+      <el-col :span="20">
+        <basic-container>
+          <div style="margin-bottom: 20px">
+            <el-radio-group v-model="screen" size="mini" @change="screenChange">
+              <el-radio-button :label="4">四屏</el-radio-button>
+              <el-radio-button :label="6">六分屏</el-radio-button>
+              <el-radio-button :label="9">九分屏</el-radio-button>
+              <el-radio-button :label="16">十六分屏</el-radio-button>
+            </el-radio-group>
+          </div>
+            <el-row :gutter="4">
+              <div class="item4" v-for="(item,index) in data4" :key="index" v-if="screen == 4">
+                <div align="center">{{item.name}}</div>
+                <video :id="'videoId' + index" controls="true" width="100%" height="100%">
+                </video>
+              </div>
+              <el-col :span="screenSpan" v-for="(item,index) in screenData" :key="screen + index" v-if="item.display">
+                <player style="position:sticky;overflow: hidden;" :jessibucaId="'jessibucaId' + index" :container="'container' + index" :buttonsBoxId="'buttonsBoxId' + index" :ref="'videoPlayer' + index" :hasaudio="hasaudio" fluent autoplay live ></player>
+              </el-col>
+            </el-row>
+          </div>
+        </basic-container>
+      </el-col>
+    </el-row>
+</template>
+
+<script>
+    import {getGbChannelLazyTree, startPlay, stopPlay} from "@/api/device/gb/gbdevicechannel";
+    import player from './jessibuca.vue'
+    export default {
+      name: "videowall",
+      components: {player},
+      data () {
+        return {
+          // itemClass: {
+          //   width: '500px',
+          //   overflow: 'hidden',
+          //   borderRadius: '5px',
+          //   margin: '5px',
+          //   position: 'sticky'
+          // },
+          screenSpan: 4,
+          screen: 4,
+          screenData:[],
+          playerRef: "4videoPlayer",
+          filterText: '',
+          treeData : [],
+          treeProps:{
+            labelText: '标题',
+            label: 'label',
+            parentLabel: 'parentLabelName',
+            children: 'children',
+            isLeaf: "leaf"
+          },
+          form:{},
+          data4:[],
+          data6:[],
+          data9:[],
+          data16:[],
+          loading:true,
+          data:[],
+        }
+      },
+      watch: {
+        filterText(val) {
+          this.$refs.tree.filter(val);
+        }
+      },
+      created(){
+        this.initData();
+      },
+      methods:{
+        initData(){
+          for(let i = 0; i < 16; i++){
+            let item = null;
+            if(i <= 3){
+              item = {name:"", isPlay:false, index:i, channelId:null, display:true};
+            }else{
+              item = {name:"", isPlay:false, index:i, channelId:null, display:false};
+            }
+            this.screenData.push(item);
+
+            // if(i <= 3){
+            //   this.data4.push(item);
+            //   this.data6.push(item);
+            //   this.data9.push(item);
+            //   this.data16.push(item);
+            // }else if(i > 3 && i <= 5){
+            //   this.data6.push(item);
+            //   this.data9.push(item);
+            //   this.data16.push(item);
+            // }else if(i > 5 && i <= 8){
+            //   this.data9.push(item);
+            //   this.data16.push(item);
+            // }else if(i > 8 && i <= 15){
+            //   this.data16.push(item);
+            // }
+          }
+        },
+        screenChange(value){
+          if(value === 4){
+            this.screenSpan = 12;
+            for(let i=0; i<16; i++){
+              if(i < 4){
+                this.screenData[i].display = true;
+              }else{
+                this.screenData[i].display = false;
+              }
+            }
+          }else if(value === 6){
+            this.screenSpan = 8;
+            for(let i=4; i<16; i++){
+              if(i < 6){
+                this.screenData[i].display = true;
+              }else{
+                this.screenData[i].display = false;
+              }
+            }
+          }else if(value === 9){
+            this.screenSpan = 8;
+            for(let i=6; i<9; i++){
+              if(i < 9){
+                this.screenData[i].display = true;
+              }else{
+                this.screenData[i].display = false;
+              }
+              this.screenData[i].display = true;
+            }
+          }else if(value === 16){
+            this.screenSpan = 6;
+            for(let i=4; i<16; i++){
+              this.screenData[i].display = true;
+            }
+          }
+        },
+        treeLoad(node, resolve){
+          const parentId = (node.level === 0) ? null : node.data.id;
+          let parentColumn = null;
+          const tenantId = localStorage.getItem("tenantId");
+          if(tenantId === "000000"){
+            if(node.level === 0){
+              parentColumn = "0";
+            }else if(node.level === 1){
+              parentColumn = "agency";
+            }else if(node.level === 2){
+              parentColumn = "residential";
+            }else if(node.level === 3){
+              parentColumn = "building";
+            }else if(node.level === 4){
+              parentColumn = "floor";
+            }else{
+              parentColumn = null;
+            }
+          }else{
+            if(node.level === 0){
+              parentColumn = "0";
+            }else if(node.level === 1){
+              parentColumn = "residential";
+            }else if(node.level === 2){
+              parentColumn = "building";
+            }else if(node.level === 3){
+              parentColumn = "floor";
+            }else{
+              parentColumn = null;
+            }
+          }
+          getGbChannelLazyTree(parentColumn, parentId).then(res => {
+            resolve(res.data.data.map(item => {
+              return {
+                ...item,
+                leaf: !item.hasChildren
+              }
+            }))
+          });
+        },
+        filterNode(value, data) {
+          if (!value) return true;
+          return data.label.indexOf(value) !== -1;
+        },
+        handleNodeClick(node, resolve){},
+        clickPlay(data){
+          this.$message.success("开始调取视频");
+          //找到第一个没有播放的屏幕
+          let emptyIndex = this.screenData.findIndex((item) => item.isPlay == false);
+          if(emptyIndex >= 0){ //表示找到
+            this.playVideo(data, emptyIndex);
+            this.screenData[emptyIndex].isPlay = true;
+            this.screenData[emptyIndex].channelId = data.channelId;
+            return false;
+          }else{
+            this.playVideo(data, 0);
+            this.screenData[0].isPlay = true;
+            this.screenData[0].channelId = data.channelId;
+          }
+        },
+        playVideo(treeItem, index){
+          let deviceId = treeItem.deviceId;
+          let channelId = treeItem.channelId;
+          console.log(this.$refs[this.playerRef + index]);
+          startPlay(deviceId, channelId).then(res => {
+            if (res.data.data) {
+              let streamInfo = res.data.data;
+              this.$refs[this.playerRef + index][0].play(streamInfo.ws_flv);
+              // try {
+              //   let videoElement = document.getElementById("videoId" + index);
+              //   let flvPlayer = flvjs.createPlayer({
+              //     type: 'flv',
+              //     url: streamInfo.ws_flv
+              //   });
+              //   flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => {});
+              //   flvPlayer.on(flvjs.Events.MEDIA_SOURCE_CLOSE || flvjs.Events.MEDIA_SOURCE_ENDED, () => {});
+              //   flvPlayer.attachMediaElement(videoElement);
+              //   flvPlayer.load();
+              //   flvPlayer.play();
+              //   treeItem.isPlay = true;
+              // } catch (e) {
+              //   console.log(e);
+              // }
+            }
+          });
+        },
+        clickStop(node, treeItem){
+          this.$message.warning("正在停止");
+          let screenData = null;
+          let deviceId = treeItem.deviceId;
+          let channelId = treeItem.channelId;
+          let channelVideoIndex = this.screenData.findIndex((item,index) => {return item.channelId == treeItem.channelId});
+          this.$refs[this.playerRef + channelVideoIndex][0].pause();
+          // stopPlay(deviceId, channelId).then(res => {
+          //   this.$message.success("停止成功");
+          //   this.screenData[channelVideoIndex].isPlay = false;
+          //   this.screenData[channelVideoIndex].channelId = null;
+          // });
+        }
+      },
+    }
+</script>
+
+<style lang="less">
+  .box {
+    height: 800px;
+  }
+
+  .el-scrollbar {
+    height: 100%;
+  }
+
+  .box .el-scrollbar__wrap {
+    overflow: scroll;
+  }
+  #videoSurveillance {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-wrap: wrap;
+    box-sizing: border-box;
+
+    .item4 {
+      width: calc(~"49%");
+      overflow: hidden;
+      border-radius: 5px;
+      margin: 5px;
+      position: sticky;
+    }
+
+    .item6 {
+      width: calc(~"32%");
+      overflow: hidden;
+      border-radius: 5px;
+      margin: 5px;
+      position: sticky;
+    }
+
+    .item9 {
+      width: calc(~"32%");
+      overflow: hidden;
+      border-radius: 5px;
+      margin: 5px;
+      position: sticky;
+    }
+
+    .item16 {
+      width: calc(~"24%");
+      overflow: hidden;
+      border-radius: 5px;
+      margin: 5px;
+      position: sticky;
+    }
+  }
+  .custom-tree-node {
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-size: 14px;
+    padding-right: 8px;
+  }
+</style>