vue的h5页面中使用视频播放插件

vue的h5页面中使用视频播放插件

h5项目中需要做视频课程播放,在网上搜了一下对应的插件,发觉xg-player西瓜播放器用起来不错.当然也踩了一些坑.
**西瓜播放器官方地址: **http://h5player.bytedance.com/
西瓜播放器githuab官网: https://github.com/bytedance/xgplayer-vue

初步使用

因为自己做的是个老项目,freemarker模板语法写的(总之是旧时代那种,你知道jsp就名字了),但是我想用自己的方式开发,所以在里面用了vue.

先写一个静态页面的demo,看下效果

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

功能:

  1. 进入页面根据id播放列表对应的视频
  2. 列表视频之间播放切换
  3. 点击正在播放的视频进行暂停
  4. 点击列表播放按钮暂停,视频暂停
  5. 点击正在播放的视频,课程列表播放暂停

视频播放逻辑

/**
 * 视频播放逻辑
 * 一、点击按钮
 * 1. 视频正在播放
 *    1.1 如果是当前列表项,暂停播放,视频暂停播放 
 * item.play_status = false
 * player.pause()  
 * 2. 视频未播放
 *    2.1 播放的列表暂停播放,点击的列表进行播放
 *    2.2 切换播放视频进行播放
 * 二、点击播放器按钮
 * 1. 视频正在播放
 *    1.1 暂停播放,获取暂停状态,列表暂停播放
 * 2. 视频停止/暂停播放
 *    2.1 播放视频,列表对应按钮播放
 */

静态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">
          全面深化改革,新时代中国的重要命题。党的十八届三中全会以来,以习近平同志为核心的党中央总揽全局、统筹谋划,注重解决体制性的深层次障碍,推出一系列重大体制改革,有效解决了一批结构性矛盾,很多领域实现了历史性变革、系统性重塑、整体性重构;注重克服机制性的梗阻问题,打通理顺了许多堵点难点,增强了全社会发展活力和创新活力。
        </div>
      </div>
      <div class="watcher-footer">
        <div class="footer-title">01初识生殖美学</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="//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">
                  点击次数:{{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: '初识生殖美学',
      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: '初识生殖美学',
      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: '初识生殖美学',
      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);
      // 当前是否播放
      if (course.play_status) {
        console.log('当前正在播放');
        // 如果正在播放
        player.pause()
        this.currentId = course.id
        this.currentIndex = course_index
        courseList[course_index].play_status = false;
      } else {
        //note: 1.如果未播放
        //是否是当前项
        let isCurrentItem = course.id == this.currentId

        if (isCurrentItem) {
          //note: 如果是当前暂停项要进行再次播放
          player.play()
          courseList[course_index].play_status = true;
        } else {
          //note: 如果是要播放新的视频
          console.log('列表中的其他视频播放');
          // console.log(this.currentIndex);
          courseList.forEach((item, index) => {
            if (item.play_status) {
              // 如果有正在播放的项,暂停播放
              item.play_status = !item.play_status
            }
            // 切换当前项进行播放
            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相同,列表中的按钮处于播放状态
      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. 西瓜播放器切换视频

官网写的老的切换方式:
(1)先销毁视频,

player.destroy(isDelDom)

(2)然后重新创建player实例

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

(3)启动播放器,播放视频

player.start(url)
player.play()

我写完了之后重新整理笔记,看到官网有更好的api切换视频,暂时还没有试过.

player.src = 'new url'

项目实战

项目中的课程播放要比这个demo复杂的多,涉及到视频播放,图文播放,视频图文的切换播放

看下项目中的效果

功能:

  1. 点击播放课程,进入播放页面立即播放课程
  2. 图文课程和视频课程的切换播放
  3. 视频课程切换到图文课程要暂停播放视频
  4. 图文课程一直处于播放状态,不可暂停
  5. 课程列表分页
  6. 记录播放次数
  7. 点击播放一次就算播放一次
  8. 记录培训进度
  9. 图文课程点击进入就算此课程已看完,进行培训记录
  10. 视频课程点击播放,播放结束表示课程已看完,进行培训记录
GIF.gif
GIF.gif

项目课程播放逻辑

开始想的是获取课程列表,然后前台筛选判断应该播放哪一项,但是考虑到加载分页时会影响当前播放的视频,所以分页列表和正在播放视频分成了两个接口,并且前台需要处理的只是逻辑判断,不需要遍历操作整个列表,简化了查询匹配课程播放的问题.

/**
 * 初始化播放: 
 *    通过query获取id,请求要播放的视频
 * 判断当前的播放类型
 * 1. 如果历史播放和现在播放都是图文
 *    如果点击项id和历史id相同,则不作任何事情
 *    否则,请求后台,播放图文
 * 2. 如果历史播放是图文,现在播放是视频
 *    请求后台,播放视频
 * 3. 如果历史播和现在播放都是视频
 *    如果正在播放的视频url和点击项视频url相同
 *        如果选择视频正在播放,则暂停播放
 *        否则播放视频
 *    否则请求后台播放新的视频
 * 4. 如果历史播放是视频,现在播放是图文
 *    销毁视频播放实例
 *    请求后台播放图文
 * 5. 如果加载分页,当前有正在播放的视频,则不请求播放接口
 */

在视频播放中需要监听视频的暂停,继续,结束状态.

<!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="//cdn.jsdelivr.net/npm/xgplayer/browser/index.js" charset="utf-8"></script>
<script src="//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">
                  点击次数:{{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, // 当前播放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:如果历史播放和现在播放都是图文
            if (playHistoryType ==0 && this.watch_type == 0) {
                console.log('都是图文');
                if(classId==course.id) {
                    console.log('选择重复项了');
                    return
                }
                classId = course.id;
                // getPlayingCourse();
                collegeRead(course);
            }
            // TODO:如果历史播放是图文,现在播放是视频
            if (playHistoryType == 0 && this.watch_type == 1) {
                console.log('播放视频');
                classId = course.id;
                // getPlayingCourse();
                collegeRead(course);
                // this._switchVideo(course.videourl);
                return
            }
            // TODO:如果历史播和现在播放都是视频
            if (playHistoryType ==1 && this.watch_type == 1) {
                console.log('都是视频播放');
                // 如果当前视频src和点击src相同,( 继续播放
                if (this.playingCourseData.videourl == course.videourl) {
                    console.log('选择的是当前视频');
                    // 如果现在正在播放,( 暂停播放
                    if (course.play_status) {
                        console.log('正在播放');
                        player.pause();
                        return;
                    }
                    // 如果现在没有播放, (继续播放
                    player.play();
                    return
                }
                classId = course.id;
                // getPlayingCourse();
                collegeRead(course);
                // this._switchVideo(course.videourl)
            }
            // TODO:如果历史播放是视频,现在播放是图文,( 暂停播放
            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: 播放器销毁并再次初始化后,需要先调用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: 播放器销毁并再次初始化后,需要先调用start方法
                player.start(url);
                player.play();
                player.once('ready', () => {
                    console.log('启动')
                });
                this._monitorPlaying();
                this._monitorPause();
                this._monitorEnded();
                // this._monitorDestroy();
            }, 0);
        },
        // 监听继续播放
        _monitorPlaying() {
            player.on('playing', () => {
                this.courseList.forEach(item => {
                    if (item.id == classId) {
                        item.play_status = true;
                    }
                });
            })
        },
        // 监听暂停播放
        _monitorPause() {
            player.on('pause', () => {
                console.log('暂停');
                this.courseList.forEach(item => {
                    if (item.id == classId) {
                        item.play_status = false;
                    }
                });
            })
        },
        // 监听结束播放
        _monitorEnded() {
            player.on('ended', () => {
                console.log('结束')
                updateUserCourseSchedule()
            });
        },
        // 监听销毁
        _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;
                            // 图文教程默认请求到就是培训完成
                            updateUserCourseSchedule();
                        }
                    });
                    return
                }
                // TODO: 视频课程
                app.watch_type = 1;
                playHistoryType = 1;
                playHistoryId = classId
                // console.log('视频课程')
                app._playVideo(courseData.videourl);
                app.playingCourseData = courseData;
                // 如果获取的id和列表id相同,列表中的按钮处于播放状态
                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("网络繁忙");
        },
        complete: function () {
            loadComplete();
        }
    })
}
// 初始化加载分页
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("网络繁忙");
        },
        complete: function () {
            loadComplete();
        }
    })
}

// 记录播放次数
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("网络繁忙");
        },
        complete: function () {
            loadComplete();
        }
    })
}

// 记录培训进度
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("网络繁忙");
        },
        complete: function () {
            loadComplete();
        }
    })
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350