VUE Video視頻(播放/列表)


1. 概述

1.1 說明

  PC項目中的經常會有視頻播放功能,播放一些課程視頻或者直播回放等;視頻有時是單個視頻有時是多個視頻,多個視頻時通過點擊播放列表中的某一項進行播放對應視頻信息。

 2. 代碼

2.1 頁面處理

  • 視頻播放標簽使用h5中的<video>,當需要播放的視頻列表數量大於1時,顯示視頻列表(使用iview中的標簽<Tag>);
  • 視頻中使用muted屬性(規定視頻的音頻輸出應該被靜音);   ----若需進入直接播放,需加上此屬性,因為chrome目前將video和audio的autoplay自動播放功能禁用
<!-- 直播回放視頻組件(視頻列表時展示列表信息) -->
<template>
  <div class="video-item-wrapper">
    <video
      ref="refVideo"
      width="900"
      height="506"
      controls
      muted
      :src="videoSrc" />
     <div class="video-item-tag" v-if="videoItemList.length>1">
       <Tag
        v-for="item in videoItemList"
        :key="item.vid"
        :name="item.name"
        :checked="item.checked"
        :color="item.checked?'error':'default'"
        checkable
        type="border"
        style="cursor:pointer"
        @on-change="videoItemTagChang">
        {{item.name}}
      </Tag>
    </div>
  </div>
</template>

2.2 邏輯處理

  • 需要播放的視頻列表從外部傳值到組件內
  • 判斷是否需要展示視頻列表;如果展示了視頻列表,則視頻列表要與播放的視頻進行對應;
  • 視頻播放后,可進行列表順序播放。如視頻列表中有3個視頻,點擊第一個視頻進行播放后,視頻播放完成后進行第二個視頻自動播放,依此類推,到列表中的最后一個視頻時停止自動播放,第一個視頻待播放
  • 視頻播放功能中加入定時器   -----用來對谷歌不支持有聲音的視頻自動播放問題的解決
<script>
export default {
  name: 'VideoItem',
  props: {
    videoArray: {
      type: Array,
      default() {
        return []
      },
    },
  },
  data() {
    return {
      videoSrc: '',
      videoPlayNum: 0,
      videoItemList: [],
    }
  },
  mounted() {
    this.videoSrc = this.videoArray[this.videoPlayNum].mediaUrl
    this.initvideoItemList()
    this.videoEventListener()
  },
  methods: {
    /**
     * 視頻標簽集合初始化
     */
    initvideoItemList() {
      this.videoItemList = this.videoArray.map(item => {
        return {
          vid: item.vid,
          name: item.name,
          checked: false,
          mediaUrl: item.mediaUrl,
        }
      })
      if (this.videoItemList.length > 1) {
        this.videoItemList[0].checked = true
      }
    },
    /**
     * 視頻標簽處理
     */
    videoItemTagChang(checked, name) {
      let checkedName = ''
      for (let i = 0; i < this.videoItemList.length; i++) {
        if (this.videoItemList[i].checked) {
          checkedName = this.videoItemList[i].name
          break
        }
      }
      // 當前選中標簽再次點擊時不進行處理
      if (checkedName !== name) {
        this.videoItemList.forEach(item => {
          item.checked = false
        })
        if (name) {
          this.videoItemList.forEach(item => {
            if (item.name === name) {
              item.checked = checked
            }
          })
          for (let i = 0; i < this.videoItemList.length; i++) {
            if (this.videoItemList[i].checked) {
              this.videoPlayNum = i
              this.videoSrc = this.videoItemList[i].mediaUrl
              setTimeout(() => {
                this.$refs.refVideo.play()
              }, 150)
              break
            }
          }
        }
      }
    },
    /**
     * 視頻監聽(對視頻插件進行監聽是否播放結束,若結束則去判斷是否無縫銜接播放下一視頻還是回歸初始化)
     */
    videoEventListener() {
      const _this = this
      _this.$refs.refVideo.addEventListener('ended', function () {
        if (_this.videoPlayNum === (_this.videoArray.length - 1)) {
          _this.videoSrc = _this.videoArray[0].mediaUrl
          _this.videoPlayNum = 0
          _this.setVideoTagSelected()
        } else {
          _this.videoPlayNum += 1
          _this.setVideoTagSelected()
          _this.videoSrc = _this.videoArray[_this.videoPlayNum].mediaUrl
          setTimeout(() => {
            _this.$refs.refVideo.play()
          }, 150)
        }
      })
    },
    /**
     * 視頻列表狀態選中設置
     */
    setVideoTagSelected() {
      this.videoItemList.forEach(item => {
        item.checked = false
      })
      for (let i = 0; i < this.videoItemList.length; i++) {
        if (i === this.videoPlayNum) {
          this.videoItemList[i].checked = true
          break
        }
      }
    },
  },
}
</script>

2.3 樣式處理

<style lang="less" scoped>
.video-item-wrapper{
  display: flex;
  flex-direction: column;
  .video-item-tag{
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    >*{
      margin-top: 26px;
    }
  }
}
</style>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM