<template> 
 | 
  <div id="pushVideoList" style="width: 100%"> 
 | 
    <div class="page-header"> 
 | 
      <div class="page-title">推流列表</div> 
 | 
      <div class="page-header-btn"> 
 | 
        搜索: 
 | 
        <el-input @input="getPushList" style="margin-right: 1rem; width: auto;" size="mini" placeholder="关键字" 
 | 
                  prefix-icon="el-icon-search" v-model="searchSrt" clearable></el-input> 
 | 
        流媒体: 
 | 
        <el-select size="mini" @change="getPushList" style="margin-right: 1rem;" v-model="mediaServerId" 
 | 
                   placeholder="请选择" default-first-option> 
 | 
          <el-option label="全部" value=""></el-option> 
 | 
          <el-option 
 | 
            v-for="item in mediaServerList" 
 | 
            :key="item.id" 
 | 
            :label="item.id" 
 | 
            :value="item.id"> 
 | 
          </el-option> 
 | 
        </el-select> 
 | 
        推流状态: 
 | 
        <el-select size="mini" style="margin-right: 1rem;" @change="getPushList" v-model="pushing" placeholder="请选择" 
 | 
                   default-first-option> 
 | 
          <el-option label="全部" value=""></el-option> 
 | 
          <el-option label="推流进行中" value="true"></el-option> 
 | 
          <el-option label="推流未进行" value="false"></el-option> 
 | 
        </el-select> 
 | 
        <el-button icon="el-icon-upload2" size="mini" style="margin-right: 1rem;" type="primary" @click="importChannel"> 
 | 
          通道导入 
 | 
        </el-button> 
 | 
        <el-button icon="el-icon-download" size="mini" style="margin-right: 1rem;" type="primary"> 
 | 
          <a style="color: #FFFFFF; text-align: center; text-decoration: none" href="/static/file/推流通道导入.zip" 
 | 
             download='推流通道导入.zip'>下载模板</a> 
 | 
        </el-button> 
 | 
        <el-button icon="el-icon-delete" size="mini" style="margin-right: 1rem;" 
 | 
                   :disabled="multipleSelection.length === 0" type="danger" @click="batchDel">批量移除 
 | 
        </el-button> 
 | 
        <el-button icon="el-icon-plus" size="mini" style="margin-right: 1rem;" type="primary" @click="addStream">添加通道 
 | 
        </el-button> 
 | 
        <el-button icon="el-icon-refresh-right" circle size="mini" @click="refresh()"></el-button> 
 | 
      </div> 
 | 
    </div> 
 | 
    <devicePlayer ref="devicePlayer"></devicePlayer> 
 | 
    <addStreamTOGB ref="addStreamTOGB"></addStreamTOGB> 
 | 
    <el-table ref="pushListTable" :data="pushList" style="width: 100%" :height="winHeight" 
 | 
              @selection-change="handleSelectionChange" :row-key="(row)=> row.app + row.stream"> 
 | 
      <el-table-column  type="selection" :reserve-selection="true" min-width="55"> 
 | 
      </el-table-column> 
 | 
      <el-table-column prop="name" label="名称" min-width="200"> 
 | 
      </el-table-column> 
 | 
      <el-table-column prop="app" label="APP" min-width="200"> 
 | 
      </el-table-column> 
 | 
      <el-table-column prop="stream" label="流ID" min-width="200"> 
 | 
      </el-table-column> 
 | 
      <el-table-column prop="gbId" label="国标编码" min-width="200" > 
 | 
      </el-table-column> 
 | 
      <el-table-column prop="mediaServerId" label="流媒体" min-width="200" > 
 | 
      </el-table-column> 
 | 
      <el-table-column label="开始时间"  min-width="200"> 
 | 
        <template slot-scope="scope"> 
 | 
          <el-button-group> 
 | 
            {{ scope.row.pushTime == null? "-":scope.row.pushTime }} 
 | 
          </el-button-group> 
 | 
        </template> 
 | 
      </el-table-column> 
 | 
      <el-table-column label="正在推流"  min-width="100"> 
 | 
        <template slot-scope="scope"> 
 | 
          {{scope.row.pushIng ? '是' : '否' }} 
 | 
        </template> 
 | 
      </el-table-column> 
 | 
      <el-table-column label="本平台推流"  min-width="100"> 
 | 
        <template slot-scope="scope"> 
 | 
          {{scope.row.pushIng && !!scope.row.self ? '是' : '否' }} 
 | 
        </template> 
 | 
      </el-table-column> 
 | 
  
 | 
      <el-table-column label="操作" min-width="360"  fixed="right"> 
 | 
        <template slot-scope="scope"> 
 | 
          <el-button size="medium" icon="el-icon-video-play" 
 | 
                     v-if="scope.row.pushIng === true" 
 | 
                     @click="playPush(scope.row)" type="text">播放 
 | 
          </el-button> 
 | 
          <el-divider direction="vertical"></el-divider> 
 | 
          <el-button size="medium" icon="el-icon-delete" type="text" @click="stopPush(scope.row)" style="color: #f56c6c" >移除</el-button> 
 | 
          <el-divider direction="vertical"></el-divider> 
 | 
          <el-button size="medium" icon="el-icon-position" type="text" v-if="!!!scope.row.gbId" 
 | 
                     @click="addToGB(scope.row)">加入国标 
 | 
          </el-button> 
 | 
          <el-divider v-if="!!!scope.row.gbId" direction="vertical"></el-divider> 
 | 
          <el-button size="medium" icon="el-icon-position" type="text" v-if="!!scope.row.gbId" 
 | 
                     @click="removeFromGB(scope.row)">移出国标 
 | 
          </el-button> 
 | 
        </template> 
 | 
      </el-table-column> 
 | 
    </el-table> 
 | 
    <el-pagination 
 | 
      style="float: right" 
 | 
      @size-change="handleSizeChange" 
 | 
      @current-change="currentChange" 
 | 
      :current-page="currentPage" 
 | 
      :page-size="count" 
 | 
      :page-sizes="[15, 25, 35, 50]" 
 | 
      layout="total, sizes, prev, pager, next" 
 | 
      :total="total"> 
 | 
    </el-pagination> 
 | 
    <streamProxyEdit ref="streamProxyEdit"></streamProxyEdit> 
 | 
    <importChannel ref="importChannel"></importChannel> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script> 
 | 
import streamProxyEdit from './dialog/StreamProxyEdit.vue' 
 | 
import devicePlayer from './dialog/devicePlayer.vue' 
 | 
import addStreamTOGB from './dialog/pushStreamEdit.vue' 
 | 
import uiHeader from '../layout/UiHeader.vue' 
 | 
import importChannel from './dialog/importChannel.vue' 
 | 
import MediaServer from './service/MediaServer' 
 | 
  
 | 
export default { 
 | 
  name: 'pushVideoList', 
 | 
  components: { 
 | 
    devicePlayer, 
 | 
    addStreamTOGB, 
 | 
    streamProxyEdit, 
 | 
    uiHeader, 
 | 
    importChannel, 
 | 
  }, 
 | 
  data() { 
 | 
    return { 
 | 
      pushList: [], //设备列表 
 | 
      currentPusher: {}, //当前操作设备对象 
 | 
      updateLooper: 0, //数据刷新轮训标志 
 | 
      currentDeviceChannelsLenth: 0, 
 | 
      winHeight: window.innerHeight - 250, 
 | 
      mediaServerObj: new MediaServer(), 
 | 
      currentPage: 1, 
 | 
      count: 15, 
 | 
      total: 0, 
 | 
      searchSrt: "", 
 | 
      pushing: "", 
 | 
      mediaServerId: "", 
 | 
      mediaServerList: [], 
 | 
      multipleSelection: [], 
 | 
      getDeviceListLoading: false 
 | 
    }; 
 | 
  }, 
 | 
  computed: {}, 
 | 
  mounted() { 
 | 
    this.initData(); 
 | 
    this.updateLooper = setInterval(this.getPushList, 2000); 
 | 
  }, 
 | 
  destroyed() { 
 | 
    clearTimeout(this.updateLooper); 
 | 
  }, 
 | 
  methods: { 
 | 
    initData: function () { 
 | 
      this.mediaServerObj.getOnlineMediaServerList((data) => { 
 | 
        this.mediaServerList = data.data; 
 | 
      }) 
 | 
      this.getPushList(); 
 | 
    }, 
 | 
    currentChange: function (val) { 
 | 
      this.currentPage = val; 
 | 
      this.getPushList(); 
 | 
    }, 
 | 
    handleSizeChange: function (val) { 
 | 
      this.count = val; 
 | 
      this.getPushList(); 
 | 
    }, 
 | 
    getPushList: function () { 
 | 
      let that = this; 
 | 
      this.getDeviceListLoading = true; 
 | 
      this.$axios({ 
 | 
        method: 'get', 
 | 
        url: `/api/push/list`, 
 | 
        params: { 
 | 
          page: that.currentPage, 
 | 
          count: that.count, 
 | 
          query: that.searchSrt, 
 | 
          pushing: that.pushing, 
 | 
          mediaServerId: that.mediaServerId, 
 | 
        } 
 | 
      }).then(function (res) { 
 | 
          if (res.data.code === 0) { 
 | 
            that.total = res.data.data.total; 
 | 
            that.pushList = res.data.data.list; 
 | 
          } 
 | 
  
 | 
        that.getDeviceListLoading = false; 
 | 
      }).catch(function (error) { 
 | 
        console.error(error); 
 | 
        that.getDeviceListLoading = false; 
 | 
      }); 
 | 
    }, 
 | 
  
 | 
    playPush: function (row) { 
 | 
      let that = this; 
 | 
      this.getListLoading = true; 
 | 
      this.$axios({ 
 | 
        method: 'get', 
 | 
        url: '/api/push/getPlayUrl', 
 | 
        params: { 
 | 
          app: row.app, 
 | 
          stream: row.stream, 
 | 
          mediaServerId: row.mediaServerId 
 | 
        } 
 | 
      }).then(function (res) { 
 | 
        that.getListLoading = false; 
 | 
        if (res.data.code === 0 ) { 
 | 
          that.$refs.devicePlayer.openDialog("streamPlay", null, null, { 
 | 
            streamInfo: res.data.data, 
 | 
            hasAudio: true 
 | 
          }); 
 | 
        }else { 
 | 
          that.$message.error(res.data.msg); 
 | 
        } 
 | 
  
 | 
      }).catch(function (error) { 
 | 
        console.error(error); 
 | 
        that.getListLoading = false; 
 | 
      }); 
 | 
    }, 
 | 
    stopPush: function (row) { 
 | 
      let that = this; 
 | 
      that.$axios({ 
 | 
        method: "post", 
 | 
        url: "/api/push/stop", 
 | 
        params: { 
 | 
          app: row.app, 
 | 
          streamId: row.stream 
 | 
        } 
 | 
      }).then((res) => { 
 | 
        if (res.data.code === 0) { 
 | 
          that.initData() 
 | 
        } 
 | 
      }).catch(function (error) { 
 | 
        console.error(error); 
 | 
      }); 
 | 
    }, 
 | 
    addToGB: function (row) { 
 | 
      this.$refs.addStreamTOGB.openDialog({ 
 | 
        app: row.app, 
 | 
        stream: row.stream, 
 | 
        mediaServerId: row.mediaServerId 
 | 
      }, this.initData); 
 | 
    }, 
 | 
    removeFromGB: function (row) { 
 | 
      let that = this; 
 | 
      that.$axios({ 
 | 
        method: "delete", 
 | 
        url: "/api/push/remove_form_gb", 
 | 
        data: row 
 | 
      }).then((res) => { 
 | 
        if (res.data.code === 0) { 
 | 
          that.initData() 
 | 
        } 
 | 
      }).catch(function (error) { 
 | 
        console.error(error); 
 | 
      }); 
 | 
    }, 
 | 
    importChannel: function () { 
 | 
      this.$refs.importChannel.openDialog(() => { 
 | 
  
 | 
      }) 
 | 
    }, 
 | 
    addStream: function (){ 
 | 
      this.$refs.addStreamTOGB.openDialog(null, this.initData); 
 | 
    }, 
 | 
    batchDel: function () { 
 | 
      this.$confirm(`确定删除选中的${this.multipleSelection.length}个通道?`, '提示', { 
 | 
        confirmButtonText: '确定', 
 | 
        cancelButtonText: '取消', 
 | 
        type: 'warning' 
 | 
      }).then(() => { 
 | 
        let that = this; 
 | 
        that.$axios({ 
 | 
          method: "delete", 
 | 
          url: "/api/push/batchStop", 
 | 
          data: { 
 | 
            gbStreams: this.multipleSelection 
 | 
          } 
 | 
        }).then((res) => { 
 | 
          this.initData(); 
 | 
          this.$refs.pushListTable.clearSelection(); 
 | 
        }).catch(function (error) { 
 | 
          console.error(error); 
 | 
        }); 
 | 
      }).catch(() => { 
 | 
  
 | 
      }); 
 | 
    }, 
 | 
    handleSelectionChange: function (val) { 
 | 
      this.multipleSelection = val; 
 | 
    }, 
 | 
    refresh: function () { 
 | 
      this.initData(); 
 | 
    }, 
 | 
  } 
 | 
}; 
 | 
</script> 
 | 
  
 | 
<style> 
 | 
.videoList { 
 | 
  display: flex; 
 | 
  flex-wrap: wrap; 
 | 
  align-content: flex-start; 
 | 
} 
 | 
  
 | 
.video-item { 
 | 
  position: relative; 
 | 
  width: 15rem; 
 | 
  height: 10rem; 
 | 
  margin-right: 1rem; 
 | 
  background-color: #000000; 
 | 
} 
 | 
  
 | 
.video-item-img { 
 | 
  position: absolute; 
 | 
  top: 0; 
 | 
  bottom: 0; 
 | 
  left: 0; 
 | 
  right: 0; 
 | 
  margin: auto; 
 | 
  width: 100%; 
 | 
  height: 100%; 
 | 
} 
 | 
  
 | 
.video-item-img:after { 
 | 
  content: ""; 
 | 
  display: inline-block; 
 | 
  position: absolute; 
 | 
  z-index: 2; 
 | 
  top: 0; 
 | 
  bottom: 0; 
 | 
  left: 0; 
 | 
  right: 0; 
 | 
  margin: auto; 
 | 
  width: 3rem; 
 | 
  height: 3rem; 
 | 
  background-image: url("../assets/loading.png"); 
 | 
  background-size: cover; 
 | 
  background-color: #000000; 
 | 
} 
 | 
  
 | 
.video-item-title { 
 | 
  position: absolute; 
 | 
  bottom: 0; 
 | 
  color: #000000; 
 | 
  background-color: #ffffff; 
 | 
  line-height: 1.5rem; 
 | 
  padding: 0.3rem; 
 | 
  width: 14.4rem; 
 | 
} 
 | 
</style> 
 |