<template>
<div id="playerWrap">
  <!-- H5播放 -->
  <div id="player"></div>
</div>
</template>

<script>
import cAction from '@actions'
import Aliplayer from 'Aliplayer'
import AliPlayerComponent from 'AliPlayerComponent'
import Base64 from 'Base64'

// 播放器ID
const PLAYER_WRAP_ID = 'playerWrap'
const PLAYER_ID = 'player'
const SKIP_BEGIN_TIME = 7 // 跳过片头设置片头时间

// videoPlayer
let videoPlayer = null
let objPlayer = null

let continueStart = 0 // 继续学习初始值

export default {
  props: {
    lastTime: { type: Number, require: false },
    videoId: { type: String, require: false },
    width: { type: Number, require: false },
    height: { type: Number, require: false },
    username: { type: String, require: false },
    videoSrt: { type: String, require: false },
    autoPlay: { type: Boolean, require: false, default: true },
    chapterVideo: { type: Object, require: false }
  },
  data () {
    return {
      videoArr: {} // 视频流
    }
  },
  mounted () {
    this.definWindowFun()
  },
  watch: {
    videoId: {
      handler (oldId, newId) {
        // if (newId === undefined) { return }
        if (this.videoId) {
          /* 注意 flash 初始化时，需要页面DOM存在 + videoId存在 */
          continueStart = this.lastTime || 0 // 如果传递有上次播放时间，则记录缓存，以便player.start时使用
          const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
          cAction.chapterAction.getCurrentChapterDetailAliyun(this.videoId).then(json => {
            this.videoArr = json.video
            let player = this.getPlayer()
            if (!objPlayer || !player.innerHTML) {
              this.renderPlayer(PLAYER_ID, this.videoId, this.autoPlay, this.videoSrt, this.username, this.width, this.height)
            } else {
              this.playNextVideo(PLAYER_ID, this.videoId, this.autoPlay, this.videoSrt, this.username, this.width, this.height)
            }
          }).catch(e => { this.$message.error(e.message) }).finally(() => { loading.close() })
        }
      }
    }
  },
  methods: {
    /* 定义windows下，播放事件和初始化回调 */
    definWindowFun () {
      let that = this
      // 开始播放，如果设置了跳过片头则设置播放时间
      window._playerStart = function () {
        continueStart = videoPlayer.getDuration() < continueStart ? videoPlayer.getDuration() : continueStart
        if (/skip=1/.test(document.cookie)) {
          videoPlayer.seek(parseInt(Math.max(continueStart, SKIP_BEGIN_TIME))) // 跳到第6秒开始播放
        } else if (continueStart) {
          videoPlayer.seek(parseInt(continueStart))
        }
      }
      // 播放过程中不断触发，传递当前播放到的时间
      window._playerIng = function (time) {
        var _quality = videoPlayer.getComponent('QualityComponent').definition
        var rate = videoPlayer.getComponent('RateComponent').html.innerText
        switch (_quality) {
          case 'FD': _quality = '普通'; break
          case 'LD': _quality = '清晰'; break
          case 'SD': _quality = '高清'; break
        }
        if (rate) { _quality += (' ' + rate) }
        time = videoPlayer.getCurrentTime()
        $('#' + PLAYER_WRAP_ID).trigger('player.time', { time, duration: videoPlayer.getDuration(), quality: _quality, isSeek: false })
      }
      // 开始拖拽
      window._playerSeekStart = function (time) {
        /* 点击拖拽时，加载缓存 -> canplay 事件 -> timeupdate 事件 */
        // continueStart = time
      }
      // 拖动播放进度条
      window._playerSeek = function () {
        var _quality = videoPlayer.getComponent('QualityComponent').definition
        var rate = videoPlayer.getComponent('RateComponent').html.innerText
        switch (_quality) {
          case 'FD': _quality = '普通'; break
          case 'LD': _quality = '清晰'; break
          case 'SD': _quality = '高清'; break
        }
        if (rate) { _quality += (' ' + rate) }
        $('#' + PLAYER_WRAP_ID).trigger('player.seek', { time: videoPlayer.getCurrentTime(), duration: videoPlayer.getDuration(), quality: _quality, isSeek: true })
      }
      // 视频播放结束
      window._playerFinish = function () {
        that.$emit('handlePlayfinish', { time: videoPlayer.getDuration() })
      }
      // 视频播放 - error
      window._player403Stop = function (e) {
        /* 采集所有视频播放 - 错误信息 */
        let socket = window.G.socket
        let str = ''
        let version = window.G.VERSION // 客户端版本号，每次更新后，更新版本号。可以方便查看是否客户端都是最新版本
        if (window.G.UserInfo && window.G.UserInfo.student_info) {
          let tmp_info = window.G.UserInfo.student_info // eslint-disable-line
          str = tmp_info.personal_name + ':' + tmp_info.telephone + ':' + tmp_info.email + ':' + tmp_info.id + ':' + window.G.UserInfo.auth_key + ':' + (window.G.pwd || '')
        }
        str += ':' + version
        if (socket && socket.readyState === 1) {
          let _d = e.paramData || {}
          _d.m3u8Url = that.videoArr[videoPlayer.getComponent('QualityComponent').definition || 'LD'] || ''
          _d.m3u8RequestId = window.G.m3u8RequestId
          _d.UA = window.navigator.userAgent
          var arr = JSON.stringify({ 'action': 'aliVideoErr', info: Base64.encode(str), 'auth': 'aliVideoErr', 'code': Base64.encode(e.paramData.error_code), 'err': Base64.encode(JSON.stringify(_d)) }).split('')
          // var arr = JSON.stringify({ 'action': 'aliVideoErr', info: Base64.encode(str), 'auth': 'aliVideoErr', 'code': Base64.encode('4006') }).split('')
          var strArr = []
          for (var i = 0; i < arr.length; i++) {
            strArr[i] = arr[i].charCodeAt()
          }
          var data = new Uint8Array(strArr)
          socket.send(data.buffer)
        } else {
          console.log('not link build success, status: ' + socket.readyState)
        }

        /* 过期 重新刷新 */
        if (e.paramData.error_code === 4006) {
          that.$message.error('视频播放错误，请刷新页面重试！')
        } else if (e.paramData.error_code === 4016) {
          continueStart = videoPlayer.getCurrentTime()
          /* 当视频过期时，重新 获取接口 更改播放地址 重新播放 */
          const loading = that.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
          cAction.chapterAction.getCurrentChapterDetailAliyun(that.videoId).then(json => {
            that.videoArr = json.video
            let player = that.getPlayer()
            if (!objPlayer || !player.innerHTML) {
              that.renderPlayer(PLAYER_ID, that.videoId, that.autoPlay, that.videoSrt, that.username, that.width, that.height)
            } else {
              that.playNextVideo(PLAYER_ID, that.videoId, that.autoPlay, that.videoSrt, that.username, that.width, that.height)
            }
          }).catch(e => { that.$message.error(e.message) }).finally(() => { loading.close() })
        } else {
          that.$message.error('请将该错误，截图发给管理员。err: ' + e.paramData.error_code)
        }
      }
      // 播放控件 - 初始化完成时，注册播放事件
      // window._playerCallback =
    },
    /* 采用 aliyun 播放器 */
    renderPlayer (domId, vid, autoPlay, srt, username, width, height) {
      autoPlay = typeof autoPlay === 'undefined' ? 1 : autoPlay - 0
      objPlayer = new Aliplayer({
        id: domId,
        source: JSON.stringify(this.videoArr),
        width: '100%',
        height: '100%',
        autoplay: !!autoPlay,
        vodRetry: 0, // 将重试 设置为0，可以防止视频过期
        isLive: false,
        controlBarVisibility: 'always',
        definition: 'FD,LD,SD',
        defaultDefinition: 'LD',
        components: [{
          name: 'QualityComponent',
          type: AliPlayerComponent.QualityComponent
        }, {
          name: 'RateComponent',
          type: AliPlayerComponent.RateComponent
        }]
      }, function (player) {
        videoPlayer = player

        console.log('The player is created')

        /* Register the sourceloaded of the player, query the resolution of the video, invoke the resolution component, and call the setCurrentQuality method to set the resolution. */
        player.on('sourceloaded', function (params) {
          var paramData = params.paramData
          var desc = paramData.desc
          var definition = paramData.definition
          player.getComponent('QualityComponent').setCurrentQuality(desc, definition)
        })

        if (videoPlayer) {
          // player.register('onLoadStart', '') // 开始loading加载
          videoPlayer.on('ready', window._playerStart) // 开始播放视频内容
          videoPlayer.on('timeupdate', window._playerIng) // 播放中触发，300ms一次
          // player.register('onPause', '') // 暂停
          // player.register('onResume', '') // 恢复播放
          videoPlayer.on('startSeek', window._playerSeekStart) // 开始拖拽
          videoPlayer.on('completeSeek', window._playerSeek) // 拖动进度条
          videoPlayer.on('ended', window._playerFinish) // 结束
          videoPlayer.on('error', window._player403Stop) // 播放出现未授权情况
        }
      })
      this.setSize(width, height)

      // 绑定事件监听
      this.listenPlayerEvents()
    },
    listenPlayerEvents () {
      $('#' + PLAYER_WRAP_ID).off('player.time player.seek').on('player.time player.seek', (e, data) => {
        this.$emit('handlePlayTime', data)
      })
    },
    playNextVideo (domId, vid, autoPlay, srt, username, width, height) {
      /* 获取视频源 */
      this.changeVideoArr(vid, () => {
        videoPlayer._urls[0].FD = this.videoArr.FD
        videoPlayer._urls[1].LD = this.videoArr.LD
        videoPlayer._urls[2].SD = this.videoArr.SD
        var q = videoPlayer.getComponent('QualityComponent').definition || 'LD'
        objPlayer.loadByUrl(this.videoArr[q])
      })
    },
    changeVideoArr (vid, callback) {
      this.$emit('changeVideoArr', { vid, callback })
    },
    // ========= 提供播放后，其他组件可使用控制播放的方法 ===========
    // 获取视频对象
    getPlayer () {
      return document.getElementById(PLAYER_ID)
    },
    getTime () {
      if (videoPlayer) {
        return videoPlayer.getCurrentTime()
      } else {
        return 0
      }
    },
    // 设置视频跳转时间
    setTimeTo (time) {
      if (videoPlayer) {
        videoPlayer.seek(parseInt(time + 2)) // flash实际播放值会大概小个一两秒，因此添加偏移，改为H5 不知道是否还存在这个问题
      }
    },
    // 执行“跳过片头”操作
    skipBegin () {
      if (videoPlayer && videoPlayer.getCurrentTime() < SKIP_BEGIN_TIME) {
        videoPlayer.seek(parseInt(SKIP_BEGIN_TIME))
      }
    },
    // 设置视频尺寸
    setSize (w, h) {
      let player = this.getPlayer()
      if (player) {
        player.style.width = w + 'px'
        player.style.height = h + 'px'
      }
    }
  }
}
</script>
