vue的h5頁(yè)面中使用視頻播放插件

vue的h5頁(yè)面中使用視頻播放插件

h5項(xiàng)目中需要做視頻課程播放,在網(wǎng)上搜了一下對(duì)應(yīng)的插件,發(fā)覺(jué)xg-player西瓜播放器用起來(lái)不錯(cuò).當(dāng)然也踩了一些坑.
**西瓜播放器官方地址: **http://h5player.bytedance.com/
西瓜播放器githuab官網(wǎng): https://github.com/bytedance/xgplayer-vue

初步使用

因?yàn)樽约鹤龅氖莻€(gè)老項(xiàng)目,freemarker模板語(yǔ)法寫(xiě)的(總之是舊時(shí)代那種,你知道jsp就名字了),但是我想用自己的方式開(kāi)發(fā),所以在里面用了vue.

先寫(xiě)一個(gè)靜態(tài)頁(yè)面的demo,看下效果

1575120446634-3075155d-2183-47a7-9e46-6ed621c78f17.gif

功能:

  1. 進(jìn)入頁(yè)面根據(jù)id播放列表對(duì)應(yīng)的視頻
  2. 列表視頻之間播放切換
  3. 點(diǎn)擊正在播放的視頻進(jìn)行暫停
  4. 點(diǎn)擊列表播放按鈕暫停,視頻暫停
  5. 點(diǎn)擊正在播放的視頻,課程列表播放暫停

視頻播放邏輯

/**
 * 視頻播放邏輯
 * 一、點(diǎn)擊按鈕
 * 1. 視頻正在播放
 *    1.1 如果是當(dāng)前列表項(xiàng),暫停播放,視頻暫停播放 
 * item.play_status = false
 * player.pause()  
 * 2. 視頻未播放
 *    2.1 播放的列表暫停播放,點(diǎn)擊的列表進(jìn)行播放
 *    2.2 切換播放視頻進(jìn)行播放
 * 二、點(diǎn)擊播放器按鈕
 * 1. 視頻正在播放
 *    1.1 暫停播放,獲取暫停狀態(tài),列表暫停播放
 * 2. 視頻停止/暫停播放
 *    2.1 播放視頻,列表對(duì)應(yīng)按鈕播放
 */

靜態(tài)demo代碼

1. 引入reset.css

body, h1, h2, h3, h4, p, dl, dd, ul, ol, form, input, textarea, th, td, select {
    margin: 0;
    padding: 0;
    font-family: '微軟雅黑';
}

em {
    font-style: normal;
}

li {
    list-style: none;
}

a {
    text-decoration: none;
}

img {
    border: none;
    vertical-align: middle;
}

table {
    border-collapse: collapse;
}

input, textarea {
    outline: none;
}

textarea {
    resize: none;
    overflow: auto;
}

html{
    font-size: 100px !important;
}

@media only screen and (min-width: 320px) {
    html {
        font-size: 85.4px !important
    }
}

@media only screen and (min-width: 360px) {
    html {
        font-size: 96px !important
    }
}

@media only screen and (min-width: 375px) {
    html {
        font-size: 100px !important
    }
}

@media only screen and (min-width: 410px) {
    html {
        font-size: 110.4px !important
    }
}

@media only screen and (min-width: 500px) {
    html {
        font-size: 133.4px !important
    }
}

@media only screen and (min-width: 750px) {
    html {
        font-size: 200px !important
    }
}

.nav-menu-open:checked ~ .nav-menu-bg {
    -webkit-transform: scale(42) !important;
    transform: scale(42) !important;
}

2. 引入rem.js的CDN(https://www.bootcdn.cn/rem/)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>播放課程</title>
  <link rel="stylesheet" href="../common/css/reset.css">
  <link rel="stylesheet" href="./courseList.css">
  <link rel="stylesheet" href="./index.css">
</head>
<style>
  [v-cloak] {
    display: none;
  }
</style>

<body>
  <div id="app" v-cloak>
    <div class="course-deatil-warper">
      <div v-if="watch_type==1" class="movie-warper" id="mse"></div>
      <div v-if="watch_type==0" class="course-image-text">
        <div class="image-warper">
          <img src="../agent/phoenixAcademy/phoenixAcademy/b-progressbar2@2x.png" alt="">
        </div>
        <div class="text-warper">
          全面深化改革,新時(shí)代中國(guó)的重要命題。黨的十八屆三中全會(huì)以來(lái),以習(xí)近平同志為核心的黨中央總攬全局、統(tǒng)籌謀劃,注重解決體制性的深層次障礙,推出一系列重大體制改革,有效解決了一批結(jié)構(gòu)性矛盾,很多領(lǐng)域?qū)崿F(xiàn)了歷史性變革、系統(tǒng)性重塑、整體性重構(gòu);注重克服機(jī)制性的梗阻問(wèn)題,打通理順了許多堵點(diǎn)難點(diǎn),增強(qiáng)了全社會(huì)發(fā)展活力和創(chuàng)新活力。
        </div>
      </div>
      <div class="watcher-footer">
        <div class="footer-title">01初識(shí)生殖美學(xué)</div>
        <div class="footer-content">
          <div class="footer-teacher">主講老師:李四</div>
          <div class="footer-watcher">
            <img src="../agent/phoenixAcademy/phoenixAcademy/openoneseyes.png" alt="">
            12131
          </div>
        </div>
      </div>
    </div>
    <div class="course-list-warper">
      <div class="course-list-title">課程列表</div>
      <div class="course-list-box" v-for="(course,index) in courseList" :key="index">
        <course-list @onplay="onPlay" :course="course" :index="index"></course-list>
      </div>
    </div>
  </div>
</body>
<script src="https://cdn.bootcss.com/rem/1.3.4/js/rem.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="http://cdn.jsdelivr.net/npm/xgplayer/browser/index.js" charset="utf-8"></script>
<script src="./index.js"></script>
</html>

3. js代碼

Vue.component('courseList', {
  props: {
    course: Object,
    index: Number
  },
  data: function () {
    return {
      pauseSrc: '../agent/phoenixAcademy/phoenixAcademy/player@pause.png',
      playSrc: '../agent/phoenixAcademy/phoenixAcademy/player@play.png',
      playing: false,
    }
  },
  template: `
        <div class="course-list" >
            <div class="list-left">
              <div class="item-img">
                <img :src="course.img" alt="">
              </div>
              <div class="item-content">
                <div class="item-index">{{index+1>9?index+1:'0'+(index+1)}}</div>
                <div class="item-title">{{course.title}}</div>
                <div class="item-play-times">
                  點(diǎn)擊次數(shù):{{course.play_times}}
                </div>
                <div class="item-teacher">主講老師:{{course.teacher}}</div>
              </div>
            </div>
            <div class="list-right" @click="onHandle(index,course)">
              <img :src="course.play_status?pauseSrc:playSrc" alt="">
              <div v-if="course.play_status" class="playing-text">正在播放</div>
            </div>
          </div>
        `,
  methods: {
    onHandle(course_index, course) {
      this.$emit('onplay', course_index, course)
    }
  },
})
let player = null;
var app = new Vue({
  el: '#app',
  data: {
    watch_type: '1',
    courseList: [{
      id: 1,
      img: '../agent/phoenixAcademy/phoenixAcademy/f-photograph@2x.png',
      title: '初識(shí)生殖美學(xué)',
      play_times: '3000',
      teacher: 'zhangsan',
      play_status: false,
      url: 'https://st.wssqxt.com/pcImg-20191125195819.mp4',
    }, {
      id: 2,
      img: '../agent/phoenixAcademy/phoenixAcademy/f-photograph@2x.png',
      title: '初識(shí)生殖美學(xué)',
      play_times: '3000',
      teacher: 'zhangsan',
      play_status: false,
      url: 'https://st.wssqxt.com/pcImg-20191125211214.mp4'
    }, {
      id: 3,
      img: '../agent/phoenixAcademy/phoenixAcademy/f-photograph@2x.png',
      title: '初識(shí)生殖美學(xué)',
      play_times: '3000',
      teacher: 'zhangsan',
      play_status: false,
      url: 'https://st.wssqxt.com/pcImg-20191125195819.mp4',
    }],
    currentId: null,
    currentIndex: null
  },
  methods: {
    onPlay(course_index, course) {
      const courseList = this.courseList
      console.log(course_index, course.play_status);
      // 當(dāng)前是否播放
      if (course.play_status) {
        console.log('當(dāng)前正在播放');
        // 如果正在播放
        player.pause()
        this.currentId = course.id
        this.currentIndex = course_index
        courseList[course_index].play_status = false;
      } else {
        //note: 1.如果未播放
        //是否是當(dāng)前項(xiàng)
        let isCurrentItem = course.id == this.currentId

        if (isCurrentItem) {
          //note: 如果是當(dāng)前暫停項(xiàng)要進(jìn)行再次播放
          player.play()
          courseList[course_index].play_status = true;
        } else {
          //note: 如果是要播放新的視頻
          console.log('列表中的其他視頻播放');
          // console.log(this.currentIndex);
          courseList.forEach((item, index) => {
            if (item.play_status) {
              // 如果有正在播放的項(xiàng),暫停播放
              item.play_status = !item.play_status
            }
            // 切換當(dāng)前項(xiàng)進(jìn)行播放
            if (course_index === index) {
              item.play_status = !item.play_status
              this.currentId = item.id
              this._switchVideo(course.url)
            }
          });
        }
      }
    },
    _switchVideo(url) {
      if (player) {
        player.destroy();
      }
      setTimeout(() => {
        player = null;
        player = new Player({
          id: 'mse',
          url: url,
          fluid: true,
        });
        player.start(url)
        player.play()
      }, 0);
    },
    _playVideo(url) {
      player = new Player({
        id: 'mse',
        url: url,
        fluid: true,
        poster: 'http://st.wssqxt.com/pcImg-20191011173312.png'
      });
      player.start(url)
      player.play()
    },
    navTo(course_index) {
      console.log(course_index);

    }
  },
  created() {

  },
  mounted() {
    let id = 1;
    this.courseList.forEach(item => {
      // console.log(item);
      // 如果獲取的id和列表id相同,列表中的按鈕處于播放狀態(tài)
      if (item.id == id) {
        item.play_status = true;
        this._playVideo(item.url)
      }
    });
  }
})

4. less樣式表

body {
  font-size: 0.12rem;
  background: #f0f0f0;
}

.reward-warpper {
  position: relative;
  padding-top: 0.2rem;
  padding-bottom: 0.9rem;
  background: linear-gradient(to right, #08abb2, #04bdc8, #00d0de);
  z-index: -1;

  .togger-btn-box {
    display: flex;
    justify-content: center;
    align-content: center;
    color: #ccc;
    font-size: 0.16rem;

    .btn-item {
      // width: 25%;
      margin: 0 0.1rem;
      padding-bottom: 0.05rem;
      text-align: center;
    }

    .active {
      color: #fff;
      border-bottom: 1px solid #fff;
    }
  }
}

.reward-panel {
  position: relative;
  width: 90%;
  margin: 0 auto;
  margin-top: -0.7rem;
  z-index: 1;
  padding: 0.1rem 0.1rem 0.3rem 0.1rem;
  background: #fff;

  .panel-date {
    font-size: 0.12rem;
  }

  .panel-bounty {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    margin-top: 0.1rem;

    .title {
      margin-bottom: 0.1rem;
    }

    .money {
      font-size: 0.25rem;
      font-weight: bold;
      margin-bottom: 0.1rem;
    }

    .opposite-money-warper {
      padding: 0.03rem 0.1rem;
      border-radius: 20px;
      background: #fafafa;
      font-size: 0.12rem;

      .opposite-money {
        margin: 0 0.03rem;
        font-size: 0.16rem;
        font-weight: 500;
        color: red;
      }
    }
  }

  .grid-warpper {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    transition: all 2s;

    .warper-item {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
      // width: 30%;
      width: calc((100% - 24px)/3);
      padding: 0.1rem 0.07rem;
      margin: 0.05rem;

      // background: #ccc;
      .item-title {
        color: #afaaaa;
      }

      .item-number {
        margin-top: 0.1rem;
        font-weight: 600;
      }
    }
  }

  .btn-warper {
    position: absolute;
    bottom: -0.16rem;
    left: 50%;
    margin-left: -0.2rem;

    .btn {
      padding: 0.06rem 0.1rem;
      border-radius: 16px;
      background: #fafafa;
    }
  }
}

.award-user-warper {
  margin-top: 0.2rem;

  .award-user-title {
    padding: 0 0.1rem;
    font-size: 0.14rem;
  }
}

.award-list-box {
  .award-list {
    position: relative;
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.1rem;
    background: #fff;

    // border-bottom: 1px solid #000;
    &::after {
      content: '';
      position: absolute;
      bottom: 0;
      background: #aba3a3;
      width: 100%;
      height: 1px;
      -webkit-transform: scaleY(0.5);
      transform: scaleY(0.5);
      -webkit-transform-origin: 0 0;
      transform-origin: 0 0;
    }

    &:last-child {
      &::after {
        height: 0;
      }
    }

    .list-left {
      width: 80%;

      .left-item {
        display: flex;
        // justify-content: space-around;
        align-items: center;

        .item-ranking {
          margin-right: 0.1rem;

          .ranking-img {
            width: 0.1rem;
          }
        }

        .item-user-img {
          margin-right: 0.1rem;

          img {
            width: 0.45rem;
          }
        }

        .item-user-info {
          .user-name {
            width: 1.5rem;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
          }

          .user-cont {
            margin-top: 0.1rem;

            img {
              width: 0.12rem;
              // height: 0.15rem;
            }
          }
        }
      }
    }

    .list-right {
      flex: 1;
      display: flex;
      justify-content: space-between;
      align-items: center;

      .right-cont {
        margin-right: 0.05rem;
        font-size: 0.16rem;
        font-weight: 500;
        color: #000;
      }

      .right-img {
        margin-bottom: 0.03rem;

        img {
          width: 0.05rem;
        }
      }
    }
  }
}

5. 遇到的坑

1. 西瓜播放器切換視頻

官網(wǎng)寫(xiě)的老的切換方式:
(1)先銷毀視頻,

player.destroy(isDelDom)

(2)然后重新創(chuàng)建player實(shí)例

new Player({
  id:'mse',
  url:'/mp4/'
})

(3)啟動(dòng)播放器,播放視頻

player.start(url)
player.play()

我寫(xiě)完了之后重新整理筆記,看到官網(wǎng)有更好的api切換視頻,暫時(shí)還沒(méi)有試過(guò).

player.src = 'new url'

項(xiàng)目實(shí)戰(zhàn)

項(xiàng)目中的課程播放要比這個(gè)demo復(fù)雜的多,涉及到視頻播放,圖文播放,視頻圖文的切換播放

看下項(xiàng)目中的效果

功能:

  1. 點(diǎn)擊播放課程,進(jìn)入播放頁(yè)面立即播放課程
  2. 圖文課程和視頻課程的切換播放
  3. 視頻課程切換到圖文課程要暫停播放視頻
  4. 圖文課程一直處于播放狀態(tài),不可暫停
  5. 課程列表分頁(yè)
  6. 記錄播放次數(shù)
  7. 點(diǎn)擊播放一次就算播放一次
  8. 記錄培訓(xùn)進(jìn)度
  9. 圖文課程點(diǎn)擊進(jìn)入就算此課程已看完,進(jìn)行培訓(xùn)記錄
  10. 視頻課程點(diǎn)擊播放,播放結(jié)束表示課程已看完,進(jìn)行培訓(xùn)記錄
GIF.gif
GIF.gif

項(xiàng)目課程播放邏輯

開(kāi)始想的是獲取課程列表,然后前臺(tái)篩選判斷應(yīng)該播放哪一項(xiàng),但是考慮到加載分頁(yè)時(shí)會(huì)影響當(dāng)前播放的視頻,所以分頁(yè)列表和正在播放視頻分成了兩個(gè)接口,并且前臺(tái)需要處理的只是邏輯判斷,不需要遍歷操作整個(gè)列表,簡(jiǎn)化了查詢匹配課程播放的問(wèn)題.

/**
 * 初始化播放: 
 *    通過(guò)query獲取id,請(qǐng)求要播放的視頻
 * 判斷當(dāng)前的播放類型
 * 1. 如果歷史播放和現(xiàn)在播放都是圖文
 *    如果點(diǎn)擊項(xiàng)id和歷史id相同,則不作任何事情
 *    否則,請(qǐng)求后臺(tái),播放圖文
 * 2. 如果歷史播放是圖文,現(xiàn)在播放是視頻
 *    請(qǐng)求后臺(tái),播放視頻
 * 3. 如果歷史播和現(xiàn)在播放都是視頻
 *    如果正在播放的視頻url和點(diǎn)擊項(xiàng)視頻url相同
 *        如果選擇視頻正在播放,則暫停播放
 *        否則播放視頻
 *    否則請(qǐng)求后臺(tái)播放新的視頻
 * 4. 如果歷史播放是視頻,現(xiàn)在播放是圖文
 *    銷毀視頻播放實(shí)例
 *    請(qǐng)求后臺(tái)播放圖文
 * 5. 如果加載分頁(yè),當(dāng)前有正在播放的視頻,則不請(qǐng)求播放接口
 */

在視頻播放中需要監(jiān)聽(tīng)視頻的暫停,繼續(xù),結(jié)束狀態(tài).

<!DOCTYPE html>
<html>
<head lang="en">
  <title id="title">播放課程</title>
  <#include "../../../../common/header.ftl"/>
  <link rel="stylesheet" href="/static/css/chaozhimei/agent/phoenixAcademy/courseList/courseList.css?${version}" />
  <link rel="stylesheet" href="/static/css/chaozhimei/agent/phoenixAcademy/playCourse/playCourse.css?${version}" />
  <script src="/static/js/vue/vue.min.js"></script>
</head>
<style>
  [v-cloak] {
    display: none;
  }
</style>
<body>
<div id="app" v-cloak>
  <div class="course-deatil-warper" v-show="watch_type==1">
    <div class="movie-warper" id="mse">
    </div>
    <div class="watcher-footer">
      <div class="footer-title">{{playingCourseData.sort>9?playingCourseData.sort:'0'+(playingCourseData.sort)}}
        {{playingCourseData.title}}</div>
      <div class="footer-content">
        <div class="footer-teacher">{{playingCourseData.summary}}</div>
        <div class="footer-watcher">
          <img src="/static/img/chaozhimei/agent/phoenixAcademy/openoneseyes.png" alt="">
          {{playingCourseData.is_read}}
        </div>
      </div>
    </div>
  </div>
  <div class="course-graphic-warper" v-show="watch_type==0">
    <div class="course-image-text" v-html="graphicCourseData.content"></div>
    <div class="watcher-footer">
      <div class="footer-title">
        {{graphicCourseData.sort>9?graphicCourseData.sort:'0'+(graphicCourseData.sort)}}
        {{graphicCourseData.title}}
      </div>
      <div class="footer-content">
        <div class="footer-teacher">{{graphicCourseData.summary}}</div>
        <div class="footer-watcher">
          <img src="/static/img/chaozhimei/agent/phoenixAcademy/openoneseyes.png" alt="">
          {{graphicCourseData.is_read}}
        </div>
      </div>
    </div>
  </div>
<#-- :style="watch_type==1?'margin-top: 2.8rem;' : 'margin-top: 0.1rem;'" -->
  <div class="course-list-warper" >
    <div class="course-list-title">課程列表</div>
    <div class="course-list-box" v-for="(course,index) in courseList" :key="index">
      <course-list @onplay="onPlay" :course="course" :index="index"></course-list>
    </div>
  </div>
</div>
<script type="text/javascript" src="/static/js/chaozhimei/common/utils.js"></script>
<script src="http://cdn.jsdelivr.net/npm/xgplayer/browser/index.js" charset="utf-8"></script>
<script src="http://cdn.jsdelivr.net/npm/xgplayer-mp4/browser/index.js" charset="utf-8"></script>
<script type="text/javascript" src="/static/js/chaozhimei/agent/phoenixAcademy/playCourse/playCourse.js?${version}"></script>
</body>
</html>
removejscssfile('/static/css/indexAll.css', 'css');
Vue.component('courseList', {
    props: {
        course: {
            type: Array,
            required: true
        },
        index: Number
    },
    data: function () {
        return {
            pauseSrc: '/static/img/chaozhimei/agent/phoenixAcademy/player@pause.png',
            playSrc: '/static/img/chaozhimei/agent/phoenixAcademy/player@play.png',
            playing: false,
        }
    },
    template: `
        <div class="course-list" >
            <div class="list-left">
              <div class="item-img">
                <img :src="course.logo_url" alt="">
              </div>
              <div class="item-content">
<!--                <div class="item-index">{{index+1>9?index+1:'0'+(index+1)}}</div>-->
                <div class="item-index">{{course.sort>9?course.sort:'0'+(course.sort)}}</div>
                <div class="item-title">{{course.title}}</div>
                <div class="item-play-times">
                  點(diǎn)擊次數(shù):{{course.is_read}}
                </div>
                <div class="item-teacher">{{course.summary}}</div>
              </div>
            </div>
            <div class="list-right" @click="onHandle(index,course)">
              <img :src="course.play_status?pauseSrc:playSrc" alt="">
              <div v-if="course.play_status" class="playing-text">正在播放</div>
            </div>
          </div>
        `,
    methods: {
        onHandle(course_index, course) {
            this.$emit('onplay', course_index, course)
        }
    },
});
let player = null;
let initNum = 0;
let params = {
    pageNo: 1,
    pageSize: 2,
    typeId: ''
};
let classId = null;
let playHistoryType = null;
let playHistoryId = null;
var app = new Vue({
    el: '#app',
    data: {
        watch_type: 1,  //0:圖文課程 1:視頻課程
        courseList: [],
        currentId: null, // 當(dāng)前播放id
        graphicCourseData: '', // 圖文課程
        playingCourseData: {}, // 播放的課程
    },
    methods: {
        onPlay(course_index, course) {
            utils.toTop();
            // console.log(course.videourl);
            if (course.videourl=='') {
                this.watch_type = 0
            } else {
                this.watch_type = 1
            }
            // note:如果歷史播放和現(xiàn)在播放都是圖文
            if (playHistoryType ==0 && this.watch_type == 0) {
                console.log('都是圖文');
                if(classId==course.id) {
                    console.log('選擇重復(fù)項(xiàng)了');
                    return
                }
                classId = course.id;
                // getPlayingCourse();
                collegeRead(course);
            }
            // TODO:如果歷史播放是圖文,現(xiàn)在播放是視頻
            if (playHistoryType == 0 && this.watch_type == 1) {
                console.log('播放視頻');
                classId = course.id;
                // getPlayingCourse();
                collegeRead(course);
                // this._switchVideo(course.videourl);
                return
            }
            // TODO:如果歷史播和現(xiàn)在播放都是視頻
            if (playHistoryType ==1 && this.watch_type == 1) {
                console.log('都是視頻播放');
                // 如果當(dāng)前視頻src和點(diǎn)擊src相同,( 繼續(xù)播放
                if (this.playingCourseData.videourl == course.videourl) {
                    console.log('選擇的是當(dāng)前視頻');
                    // 如果現(xiàn)在正在播放,( 暫停播放
                    if (course.play_status) {
                        console.log('正在播放');
                        player.pause();
                        return;
                    }
                    // 如果現(xiàn)在沒(méi)有播放, (繼續(xù)播放
                    player.play();
                    return
                }
                classId = course.id;
                // getPlayingCourse();
                collegeRead(course);
                // this._switchVideo(course.videourl)
            }
            // TODO:如果歷史播放是視頻,現(xiàn)在播放是圖文,( 暫停播放
            if (playHistoryType == 1 && this.watch_type == 0) {
                // this.currentId = course.id;
                console.log('播放圖文');
                // console.log(player);

                if (player!=null&&player) {
                    player.destroy();
                    player = null
                }
                classId = course.id;
                // getPlayingCourse();
                collegeRead(course);
                return;
            }
        },
        _switchVideo(url) {
            if (player) {
                player.destroy();
            }
            setTimeout(() => {
                player = null;
                player = new Player({
                    id: 'mse',
                    url: url,
                    fluid: true,
                });
                //note: 播放器銷毀并再次初始化后,需要先調(diào)用start方法
                player.start(url);
                player.play();
                this._monitorPlaying();
                this._monitorPause();
                this._monitorEnded();
                this._monitorDestroy();
            }, 0);
        },
        _playVideo(url) {
            // console.log(url)
            if (player) {
                player.destroy();
            }
            setTimeout(() => {
                player = null;
                player = new Player({
                    id: 'mse',
                    url: url,
                    fluid: true,
                });
                //note: 播放器銷毀并再次初始化后,需要先調(diào)用start方法
                player.start(url);
                player.play();
                player.once('ready', () => {
                    console.log('啟動(dòng)')
                });
                this._monitorPlaying();
                this._monitorPause();
                this._monitorEnded();
                // this._monitorDestroy();
            }, 0);
        },
        // 監(jiān)聽(tīng)繼續(xù)播放
        _monitorPlaying() {
            player.on('playing', () => {
                this.courseList.forEach(item => {
                    if (item.id == classId) {
                        item.play_status = true;
                    }
                });
            })
        },
        // 監(jiān)聽(tīng)暫停播放
        _monitorPause() {
            player.on('pause', () => {
                console.log('暫停');
                this.courseList.forEach(item => {
                    if (item.id == classId) {
                        item.play_status = false;
                    }
                });
            })
        },
        // 監(jiān)聽(tīng)結(jié)束播放
        _monitorEnded() {
            player.on('ended', () => {
                console.log('結(jié)束')
                updateUserCourseSchedule()
            });
        },
        // 監(jiān)聽(tīng)銷毀
        _monitorDestroy() {
            player.on('destroy', () => {
                console.log('destroy')
                this.courseList.forEach(item => {
                    if (item.id == classId) {
                        item.play_status = 0;
                    }
                });
            })
        },
    },
    mounted() {
        loadStart();
        params.typeId = utils.getQueryVariable('typeId');
        classId = utils.getQueryVariable('classId');
        // this.currentId = classId;
        initUserList();
    }
});

// 獲取正在播放課程
function initPlayingCourse() {
    let isPlaying = app.courseList.some(item=>item.play_status == 1);
    console.log(isPlaying);
    if(isPlaying) return ;
    getPlayingCourse();
}
function getPlayingCourse() {
    $.ajax({
        url: '/college/getCourse',
        type: 'POST',
        dataType: 'json',
        data: {
            id: classId
        },
        success: function (res) {
            // console.log(res.data)
            let courseData = res.data;
            if (res.code == 0) {
                // console.log(courseData.videourl)
                if(!courseData.videourl) {
                    // TODO: 圖文課程
                    // console.log('圖文課程')
                    app.watch_type = 0;
                    playHistoryType = 0;
                    playHistoryId = classId;
                    app.graphicCourseData = courseData;
                    app.courseList.forEach(item => {
                        item.play_status = 0;
                        if (item.id == classId) {
                            item.play_status = 1;
                            // 圖文教程默認(rèn)請(qǐng)求到就是培訓(xùn)完成
                            updateUserCourseSchedule();
                        }
                    });
                    return
                }
                // TODO: 視頻課程
                app.watch_type = 1;
                playHistoryType = 1;
                playHistoryId = classId
                // console.log('視頻課程')
                app._playVideo(courseData.videourl);
                app.playingCourseData = courseData;
                // 如果獲取的id和列表id相同,列表中的按鈕處于播放狀態(tài)
                app.courseList.forEach(item => {
                    item.play_status = 0;
                    if (item.id == classId) {
                        item.play_status = 1;
                    }
                });
            } else {
                if (res.message) {
                    layer.msg(res.message);
                }
            }
        },
        error: function () {
            layer.msg("網(wǎng)絡(luò)繁忙");
        },
        complete: function () {
            loadComplete();
        }
    })
}
// 初始化加載分頁(yè)
function initUserList() {
    initNum++;
    var initIndex = initNum;
    // console.log(initIndex)
    $('.layui-flow-more').remove();
    getPageDatas('#app', function (page, next) {
        // console.log(page)
        if (initIndex != initNum) {
            return;
        }
        getClassList(page, function (pages) {
            next(null, page < pages);
        });
    });
}

// 獲取課程列表
function getClassList(page, callback) {
    params.pageNo = page;
    $.ajax({
        url: '/college/selectCollegeDetails',
        type: 'POST',
        dataType: 'json',
        data: params,
        success: function (res) {
            // console.log(res)
            if (res.code == 0) {
                callback(res.data.pages);
                app.courseList = app.courseList.concat(res.data.list);
                // console.log(JSON.stringify(app.courseList))
                initPlayingCourse();
            } else {
                if (res.message) {
                    layer.msg(res.message);
                }
                callback(1);
            }
        },
        error: function () {
            layer.msg("網(wǎng)絡(luò)繁忙");
        },
        complete: function () {
            loadComplete();
        }
    })
}

// 記錄播放次數(shù)
function collegeRead(course) {
    $.ajax({
        url: `/college/read/${course.id}`,
        type: 'POST',
        dataType: 'json',
        data: {
            id: course.id
        },
        success: function (res) {
            // console.log(res)
            if (res.code == 0) {
                // window.location.href = `/view/user/play/course?classId=${course.id}&typeId=${course.train_typeid}`;
                getPlayingCourse();
                app.courseList.forEach(item=> {
                    if(item.id==course.id) {
                        item.is_read++
                    }
                })
            } else {
                if (res.message) {
                    layer.msg(res.message);
                }
            }
        },
        error: function () {
            layer.msg("網(wǎng)絡(luò)繁忙");
        },
        complete: function () {
            loadComplete();
        }
    })
}

// 記錄培訓(xùn)進(jìn)度
function updateUserCourseSchedule() {
    $.ajax({
        url: `/college/updateUserCourseSchedule`,
        type: 'POST',
        dataType: 'json',
        data: {
            id: classId
        },
        success: function (res) {
            // console.log(res)
            if (res.code == 0) {
                // console.log('完成課程')
            } else {
                if (res.message) {
                    layer.msg(res.message);
                }
            }
        },
        error: function () {
            layer.msg("網(wǎng)絡(luò)繁忙");
        },
        complete: function () {
            loadComplete();
        }
    })
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容