<template>
  <div v-show="isActive" class="myVideo-container">
    <video
      class="myVideo"
      id="video"
      ref="videoElement"
      preload="auto"
      muted
      autoplay
      :controls="false"
    ></video>
   <!-- <div v-if="loading" class="loading-overlay pointer-events-none">
      <div class="loading-text">{{ loadingText }}</div>
    </div> -->
  </div>
</template>

<script>
  import Hls from 'hls.js'
  import WebRTCWhep from 'whepts'
  export default {
    name: 'HlsPlayer',
    props: {
      url: {
        type: String,
        default: ''
      },
      isActive: {
        type: Boolean,
        default: true
      },
      width: {
        type: [String, Number],
        default: '100%'
      },
      height: {
        type: [String, Number],
        default: '100%'
      }
    },
    data() {
      return {
        hls: null,
        video: null,
        loading: false,
        loadingText: '加载中...',
        retryCount: 0,
        maxRetries: 3,
        isReady: false,
        playAttempts: 0,
        maxPlayAttempts: 3,
        cleanupTimeout: null
      }
    },
    computed: {
      videoStyle() {
        const style = {}
        if (this.width) {
          style.width = typeof this.width === 'number' ? `${this.width}px` : this.width
        }
        if (this.height) {
          style.height = typeof this.height === 'number' ? `${this.height}px` : this.height
        }
        return style
      }
    },
    watch: {
      isActive: {
        handler(newValue) {
          if (newValue) {
            this.$nextTick(this.initializePlayer)
          } else {
            this.immediateCleanup()
          }
        },
        immediate: true
      },
      url(newUrl) {
		  // console.log(newUrl,'77777777777777777777777777777777')
        if (newUrl && this.isActive) {
          this.initializePlayer()
        }
      }
    },
    mounted() {
      this.video = this.$refs.videoElement
      this.registerVideoEvents()
    },
    methods: {
      registerVideoEvents() {
        const events = ['canplay', 'waiting', 'playing', 'error', 'stalled', 'suspend']

        events.forEach((event) => {
          this.video.addEventListener(event, this.handleVideoEvent)
        })
      },

      handleVideoEvent(event) {
        switch (event.type) {
          case 'canplay':
            this.isReady = true
            break
          case 'waiting':
            this.showLoadingIndicator('缓冲中...')
            break
          case 'playing':
            this.loading = false
            break
          case 'error':
            this.handlePlaybackError()
            break
          case 'stalled':
            this.showLoadingIndicator('播放卡顿...')
            break
          case 'suspend':
            this.cleanupNetworkResources()
            break
        }
      },

      immediateCleanup() {
        // 立即停止网络请求
        if (this.hls) {
          this.hls.close();
          this.hls.stopLoad()
          this.hls.detachMedia()
        }

        // 延迟完全清理以避免播放卡顿
        this.cleanupTimeout = setTimeout(() => {
          // 仅在不重新初始化播放器时才调用 fullCleanup
          if (!this.url || !this.isActive) {
            this.fullCleanup()
          }
        }, 1000)
      },

      fullCleanup() {
        if (this.hls) {
          this.hls.destroy()
          this.hls = null
        }

        if (this.video) {
          this.video.pause()
          this.video.removeAttribute('src')
          this.video.load()
        }

        this.loading = false
        this.retryCount = 0
        this.isReady = false
        this.playAttempts = 0

        if (this.cleanupTimeout) {
          clearTimeout(this.cleanupTimeout)
        }
      },

      initializePlayer() {
        if (!this.isActive || !this.url) return

        // 如果是重新初始化播放器，先清理已存在的资源
        if (this.hls) {
          this.immediateCleanup()
        }
        if(this.url.startsWith('http://192.168.77.200:8050/')){
          this.hls = new WebRTCWhep({
            url: this.url, // WHEP 服务器地址
            container: this.video, // 视频播放容器
            onError: (error) => {
              console.error('播放错误:', error)
            }
          })
        }else{
          this.hls = new Hls({
            // 内存优化配置
            maxBufferSize: 0, // 降低缓冲区大小（15MB）
            maxBufferLength: 0.1, // 更小的缓冲窗口
            liveSyncDuration: 1, // 紧跟直播点
            liveMaxLatencyDuration: 5, // 最大延迟5秒
            liveDurationInfinity: true,
            lowLatencyMode: true, // 启用低延迟模式
            maxMaxBufferLength: 60,
            backBufferLength: 1, // 减少保留的缓冲数据
            manifestLoadingTimeOut: 10000,
            manifestLoadingMaxRetry: 5,
            fragLoadingTimeOut: 5000,
            fragLoadingMaxRetry: 2,
            enableWorker: true, // 启用Web Worker
            recycleVideoFrames: true, // 启用帧回收

            startLevel: -1,
            autoStartLoad: true,
            maxBufferHole: 2, // 允许更大的时间缺口
            highBufferWatchdogPeriod: 4, // 延长监控周期
            nudgeMaxRetry: 5, // 增加微调重试次数
            nudgeOffset: 0.05, // 微调步长（秒）
            jumpGaps: false,
            stallThreshold: 1000
          })

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

          // 事件处理
          this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
            this.loading = false
            this.retryCount = 0
            this.safePlay()
          })
          this.hls.on(Hls.Events.ERROR, (event, data) => {
            console.log('核心视频错误',data.type)
            // this.hls.startLoad(); //重连
            if (data.type === Hls.ErrorTypes.BUFFER_STALLED_ERROR) {
              console.error('缓冲停滞错误，尝试重新加载视频');
              this.hls.startLoad(); // 尝试重新加载视频
            }
            this.handleHlsError(data)
          })

          this.hls.on(Hls.Events.BUFFER_EOS, () => {
            this.cleanupNetworkResources()
          })
        }

      },
	initVideo() {
	    this.beforeDestroy()
		this.hls = new Hls({
		  maxBufferLength: 30, // 最大缓冲长度（秒）
		  maxMaxBufferLength: 15, // 缓冲区长度的上限
		  maxBufferSize: 30 * 1000 * 1000 // 最大缓冲大小（字节）
		})
	    this.hls.attachMedia(this.video)
	    this.hls.loadSource(this.url)

	    // 事件处理
	    this.hls.on(Hls.Events.MANIFEST_PARSED, () => {
	      this.loading = false
	      this.retryCount = 0
	      this.safePlay()
	    })
	    this.hls.on(Hls.Events.ERROR, (event, data) => {
	      this.hls.startLoad(); //重连
	      this.handleHlsError(data)
	    })

	    this.hls.on(Hls.Events.BUFFER_EOS, () => {
	      this.cleanupNetworkResources()
	    })
	  },
      cleanupNetworkResources() {
        // 清理已播放的缓冲数据
        if (this.hls && this.video) {
          try {
            const currentTime = this.video.currentTime
            this.hls.mediaBuffer = null
            if (this.hls.bufferTimer) {
              clearInterval(this.hls.bufferTimer)
            }
            this.hls.flushBuffer()
            this.video.currentTime = currentTime
          } catch (e) {
            console.warn('Buffer cleanup error:', e)
          }
        }
      },

      handleHlsError(data) {
        // console.error('HLS Error:', data)
        if (data.fatal) {
          switch (data.type) {
            case Hls.ErrorTypes.NETWORK_ERROR:
              this.retryLoad()
              break
            case Hls.ErrorTypes.MEDIA_ERROR:
              this.hls.recoverMediaError()
              break
            default:
              this.fullCleanup()
              break
          }
        }
      },

      retryLoad() {
        if (this.retryCount < this.maxRetries) {
          this.retryCount++
          this.showLoadingIndicator(`重试第 ${this.retryCount} 次...`)
          setTimeout(() => this.initializePlayer(), 2000)
        } else {
          this.showLoadingIndicator('视频加载失败')
          this.fullCleanup()
        }
      },

      showLoadingIndicator(text) {
        this.loading = true
        this.loadingText = text
      },

      async safePlay() {
        if (!this.video || this.playAttempts >= this.maxPlayAttempts) return

        try {
          this.playAttempts++
          if (this.video.readyState >= 2) {
            await this.video.play()
            this.playAttempts = 0
          } else {
            setTimeout(this.safePlay, 500)
          }
        } catch (error) {
          console.warn('播放失败:', error)
          setTimeout(this.safePlay, 1000)
        }
      }
    },
    beforeDestroy() {
      // 移除所有事件监听
      if (this.video) {
        const events = ['canplay', 'waiting', 'playing', 'error', 'stalled', 'suspend']
        events.forEach((event) => {
          this.video.removeEventListener(event, this.handleVideoEvent)
        })
      }
      this.fullCleanup()
    }
  }
</script>

<style scoped lang="scss">
  .myVideo-container {
    position: relative;
    height: 100%;
  }

  .myVideo {
    width: 100%;
    height: 100%;
    // aspect-ratio: 16/9;
    /* border: 1px solid #ccc; */
    // border-radius: vw(5);
  }

  .loading-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.3);
    display: flex;
    justify-content: center;
    align-items: center;
  }

  .loading-text {
    color: white;
    padding: vw(10);
    border-radius: vw(4);
    background: rgba(0, 0, 0, 0.6);
  }
</style>
