zoukankan      html  css  js  c++  java
  • 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>
  • 相关阅读:
    通用应用程序设计
    咫尺与天涯
    SQL SERVER 自定义函数 split
    asp.net 页面实践执行顺序
    asp.net UpdatePanel 不能局部刷新问题汇总
    DataGrid GridView 单页javascript 表头排序
    存储过程分页方案
    数据库名、数据表名、字段名、主键、标识列相关查询
    c# web 缓存管理
    js笔记---拖动元素
  • 原文地址:https://www.cnblogs.com/ajuan/p/13361336.html
Copyright © 2011-2022 走看看