<template>
  <div class="miniProgramVideoHls">
    <div class="top-button-box">
      <p :class="checkType == 1?'checkP':''" @click="checkButton(1)">实验室监控</p>
      <p :class="checkType == 2?'checkP':''" @click="checkButton(2)" v-if="toButtonType == 5">楼道监控</p>
    </div>
    <p class="null-text" v-if="nullType">{{nullType}}</p>
    <div class="video-max-box" v-if="buttonType&&!fullVideoType">
      <video class="video-box" id="video" controls autoplay muted playsinline
             v-for="(item,index) in videoList" :key="index"
             :width="item.width" :height="item.height"
             :id="item.cameraIndexCode" :ref="item.cameraIndexCode"
      ></video>
    </div>
    <div class="bottom-broadcast-box">
      <voiceBroadcast :trumpetList="trumpetList" v-show="voiceType"></voiceBroadcast>
      <p class="right-button-p" @click="voiceButton()">语音广播</p>
    </div>
  </div>
</template>
<script>
  import Hls from 'hls.js'
  import { iotCameraFindByCondition,iotAppSpeakerFindHorn } from "@/api/index";
  import voiceBroadcast from '@/components/voiceBroadcast/voiceBroadcast.vue';
  export default {
    name: 'index',
    components: {
      voiceBroadcast
    },
    data () {
      return {
        checkType:1,
        buttonType: false,
        width: null,
        height: null,
        videoList: [],
        nullType:false,
        //报警视频数据
        videoProps:null,
        //全屏视频参数
        fullVideoProps:{},
        fullVideoType:false,
        hlsPlayers: {}, // 存储每个视频的Hls实例
        errors: {},      // 存储每个视频的错误状态
        //喇叭数据
        trumpetList:[],
        voiceType:false,
        //顶部按钮状态
        toButtonType:0,
      }
    },
    created(){
      const ratio = 0.5625;
      const winWidth = window.innerWidth;
      let width = parseInt(winWidth - 20);
      let height = parseInt(this.accMul(width, ratio));
      this.$set(this, 'width', width);
      this.$set(this, 'height', height)
    },
    mounted(){
      this.getUrl();
    },
    beforeDestroy() {
      // 组件销毁前清理所有HLS实例
      this.destroyAllHlsPlayers();
    },
    methods:{
      voiceButton(){
        this.$set(this,'voiceType',!this.voiceType);
      },
      checkButton(type){
        if(this.checkType != type){
          // 切换类型前先清理之前的HLS流
          this.destroyAllHlsPlayers();
          this.$set(this,'checkType',type);
          this.$set(this, 'nullType', false);
          this.$set(this,'videoList',[]);
          this.$set(this, 'buttonType', false);
          this.getUrl();
        }
      },
      getUrl() {
        let text = decodeURIComponent(window.location.href);
        if(text.indexOf('touken') != -1){
          this.subVideo(text);
        }else{
          this.$set(this,'nullType','参数异常,请联系管理员');
        }
      },
      subVideo(text){
        let self = this;
        if(text.indexOf('touken') == -1){
          this.$set(this,'nullType','touken参数异常,请联系管理员');
          return
        }
        if(text.indexOf('source') == -1){
          this.$set(this,'nullType','source参数异常,请联系管理员');
          return
        }
        if(text.indexOf('type') == -1){
          this.$set(this,'nullType','type参数异常,请联系管理员');
          return
        }
        let urlList = text.split("?")[1].split("&");
        let urlData = {};
        urlList.forEach((item) => {
          urlData[item.split("=")[0]] = item.split("=")[1];
        });
        localStorage.setItem('touken',urlData.touken)
        // type 1.楼栋 2.楼层 3.楼道 4.实验室 5.楼道+实验室
        let obj = {
          page:'1',
          pageSize:'20',
          // protocol:window.location.href.indexOf('https') !== -1?'wss':'ws',
          protocol:'wss',
          streamType:1,
          videoStreamType:'hls',
        };
        if(urlData.type == 1){
          obj.buildId = urlData.buildId;
        }else  if(urlData.type == 2){
          obj.floorId = urlData.floorId;
        }else  if(urlData.type == 3){
          obj.passageway = urlData.floorId;
        }else  if(urlData.type == 4 || urlData.type == 5){
          if(urlData.type == 4){
            this.$set(this,'toButtonType','4');
          }else if(urlData.type == 5){
            this.$set(this,'toButtonType','5');
          }
          if(this.checkType == 1){
            obj.subIds = [urlData.subId];
          }else if(this.checkType == 2){
            obj.passageway = urlData.floorId;
          }
        }
        if(urlData.source == '2'){
          obj.source = 2;
        }else if (urlData.source == '5'){
          obj.source = 5;
        }
        if(urlData.type){
          iotAppSpeakerFindHorn({subId:urlData.subId,floorId:urlData.floorId}).then(response => {
            for (let i = 0; i < response.data.length; i++) {
              response.data[i].type = false;
            }
            this.$set(this, 'trumpetList', response.data)
          })
          iotCameraFindByCondition(obj).then(response => {
            if (!response.data.records[0]){
              this.$set(this,'nullType','该实验室未配置摄像头');
            }else{
              let list = [];
              for(let i=0;i<response.data.records.length;i++){
                let obj = {
                  width: this.width, //(宽度:非必传-默认600)
                  height: this.height, //(高度:非必传-默认338)
                  cameraIndexCode: response.data.records[i].deviceNo,
                };
                if(response.data.records[i].streamUrl.indexOf('wss://') != -1){
                  obj.url = 'https://'+response.data.records[i].streamUrl.split("://")[1];
                }else{
                  obj.url = response.data.records[i].streamUrl;
                }
                list.push(obj)
              }
              this.$set(this,'videoList',list)
              self.$set(self, 'buttonType', true);
              this.$nextTick(()=>{
                setTimeout(function(){
                  // 组件挂载后初始化所有视频播放器
                  self.initVideoPlayers()
                },1000);
              })
            }
          });
        }else{
          this.$set(this,'nullType','参数异常,请联系管理员');
        }
      },
      initVideoPlayers() {
        let self = this;
        // 先清理之前的HLS实例
        self.destroyAllHlsPlayers();

        for(let i=0;i<self.videoList.length;i++){
          let url = self.videoList[i].url;
          let videoId = self.videoList[i].cameraIndexCode;
          let video = document.getElementById(videoId);

          if (!video) continue;

          // 先停止当前视频播放
          video.pause();
          video.src = '';
          video.load();

          if (Hls.isSupported()) {
            let hls = new Hls({
              enableWorker: true,
              lowLatencyMode: true,
              backBufferLength: 90
            });

            hls.loadSource(url);
            hls.attachMedia(video);

            hls.on(Hls.Events.MANIFEST_PARSED, function () {
              console.log('m3u8 加载成功，可以播放');
              video.play().catch(e => {
                console.warn('自动播放被阻止:', e);
              });
            });

            hls.on(Hls.Events.ERROR, function (e, data) {
              console.error('hls.js 报错：', data);
              if (data.fatal) {
                switch(data.type) {
                  case Hls.ErrorTypes.NETWORK_ERROR:
                    console.log('网络错误，尝试重新加载');
                    hls.startLoad();
                    break;
                  case Hls.ErrorTypes.MEDIA_ERROR:
                    console.log('媒体错误，尝试恢复');
                    hls.recoverMediaError();
                    break;
                  default:
                    hls.destroy();
                    delete self.hlsPlayers[videoId];
                    break;
                }
              }
            });

            // 保存HLS实例
            self.hlsPlayers[videoId] = hls;

          } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
            // iOS 原生支持
            video.src = url;
            video.play().catch(e => {
              console.warn('iOS自动播放被阻止:', e);
            });
          }
        }
      },
      // 清理指定视频的HLS实例
      destroyHlsPlayer(videoId) {
        if (this.hlsPlayers[videoId]) {
          const hls = this.hlsPlayers[videoId];
          hls.destroy();
          delete this.hlsPlayers[videoId];

          // 清理video元素
          const video = document.getElementById(videoId);
          if (video) {
            video.pause();
            video.src = '';
            video.load();
          }
          console.log(`已销毁视频 ${videoId} 的HLS实例`);
        }
      },
      // 清理所有HLS实例
      destroyAllHlsPlayers() {
        Object.keys(this.hlsPlayers).forEach(videoId => {
          this.destroyHlsPlayer(videoId);
        });
        this.hlsPlayers = {};
        console.log('已清理所有HLS实例');
      },
      //乘法
      accMul(arg1, arg2) {
        var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
        try {
          m += s1.split(".")[1].length
        } catch (e) {
        }
        try {
          m += s2.split(".")[1].length
        } catch (e) {
        }
        return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m)
      },
    },
  }
</script>
<style scoped lang="scss">
  .miniProgramVideoHls{
    flex:1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    .top-button-box{
      display: flex;
      border-bottom:1px solid #999;
      p{
        flex:1;
        text-align: center;
        font-size:36px;
        line-height:80px;
        height:80px;
        color:#999;
      }
      .checkP{
        background-color: #0183FA;
        color:#fff;
      }
    }
    .null-text{
      text-align: center;
      font-size:16px;
      line-height:80px;
    }
    .video-max-box {
      flex:1;
      padding-top:10px;
      overflow-y: scroll;
      overflow-x: hidden;
    }
    .bottom-broadcast-box{
      height:100px;
      .right-button-p{
        color:#fff;
        background-color: #0183fa;
        flex:1;
        height:80px;
        line-height:82px;
        border-radius:6px;
        font-size:30px;
        margin:10px 10px 10px 10px;
      }
    }
    .video-box {
      margin: 0 auto 10px;
      display: inline-block
    }
    /*video::-webkit-media-controls-play-button {*/
      /*display: none !important;*/
    /*}*/
    /*video::-webkit-media-controls-current-time-display {*/
      /*display: none !important;*/
    /*}*/
    /*video::-webkit-media-controls-time-remaining-display {*/
      /*display: none !important;*/
    /*}*/
    /*video::-webkit-media-controls-timeline {*/
      /*display: none !important;*/
    /*}*/
    /*video::-webkit-media-controls-mute-button {*/
      /*display: none !important;*/
    /*}*/
    /*video::-webkit-media-controls-volume-slider {*/
      /*display: none !important;*/
    /*}*/
    /*!*video::-webkit-media-controls-fullscreen-button {*!*/
      /*!*display: none !important;*!*/
    /*!*}*!*/
    /*video::-webkit-media-controls-toggle-closed-captions-button {*/
      /*display: none !important;*/
    /*}*/
    /*!* 隐藏画中画按钮（非标准） *!*/
    /*video::-webkit-media-controls-picture-in-picture-button {*/
      /*display: none !important;*/
    /*}*/

    /*!* 隐藏下载按钮（部分浏览器） *!*/
    /*video::-internal-media-controls-download-button {*/
      /*display: none !important;*/
    /*}*/

    /*!* 移动端额外控制 *!*/
    /*video {*/
      /*-webkit-tap-highlight-color: transparent;*/
    /*}*/
  }
</style>
