首页 > 技术文章 > 小程序之视频

yunjiao 2021-06-29 11:00 原文

<scroll-view scroll-y>
  <view wx:for="{{videoList}}" wx:key="id">
    <video
    src="{{item.data.urlInfo.url}}"
    bindplay="handlePlay"
    id="{{item.data.coverUrl}}"
    poster="{{item.data.coverUrl}}"
    class="common"
    object-fit="cover"
    refresher-enabled="{{isTriggered}}"
    bindrefresherrefresh="handleRefresher"
    bindtimeupdate="handleTimeUpdate"
    bindended="handleEnded"
    bindscrolltolower="handleToLower"
    >
    </video>
    <!-- 性能优化:使用image图片代替video标签,当点击该图片时则将图片转化成video -->
    <image src="{{item.data.coverUrl}}" bindtap="handlePlay" id="{{item.data.vid}}"/>
  </view>
</scroll-view>
Page({
  data:{
    navId:'',// 导航栏id
    videoId:'', // 视频id
    videoUpdateTime:[],// 视频播放进度历史数组
    videoList:[],// 视频列表数据
    isTriggered:false,// 下拉刷新
  },
  // 获取导航数据
  async getVideoGroupListData(){
  
  },
  // 获取视频列表数据
  async getVideoList(navId){
    if(!navId)return;
    let videoListData=await request('路径',{请求发送数据});
    // 关闭消息提示框
    wx.hideLoading();

    let index=0;
    let videoList=videoListData.data.map(item=>{
      item.id=index++;
      return item;
    })
    // 关闭下拉刷新 isTriggered=false
    this.setData({
      videoList,
      isTriggered:false
    })
  },
  // 点击切换导航的回调
  changeNav(e){
  
  },
  // 点击播放 / 继续播放的回调
  handlePlay(e){
    /*
    * 需求:
    *  1、再点击播放中需要找到上一个播放的视频
    *  2、在播放新的视频之前关闭上一个正在播放的视频
    *  关键:
    *  1、 如何找到上一个视频的实例的对象
    * */
    // let vid=e.currentTarget.id;
    // // 关闭上一个播放的视频
    // this.vid !==vid && this.videoContext && this.videoContext.stop();
    // this.vid=vid;
    
    // 更新data中videoId的状态数据
    this.setData({
      videoId:vid
    })
    // 创建控制video标签的实例对象
    this.videoContext=wx.createVideoContext(vid);
    this.video.play();
  },
  // 监听视频播放进度的回调
  handleTimeUpdate(e){
    let videoTimeObj={vid:e.currentTarget.id,currentTime:e.detail.currentTime};
    let {videoUpdateTime}=this.data;
    /*
    * 思路: 判断记录播放时长的videoUpdateTime数组中是否有当前的视频播放记录;
    *       1、有,在原有的播放记录中修改播放时间为当前时间
    *       2、没有,需要在数组中添加当前视频的播放对象
    *
    * */
    let videoItem = videoUpdateTime.find(item=>item.vid===videoTimeObj.vid);
    if(videoItem){ //之前有
      videoItem.currentTime=e.detail.currentTime;
    }else{  //之前没有
      videoUpdateTime.push(videoTimeObj)
    }
    // 更新 videoUpdateTime
    this.setData({
      videoUpdateTime
    })
  },
  // 视频播放结束的回调
  handleEnded(e){
    let {videoUpdateTime} =this.data;
    // findIndex,查找当前元素的下标,然后将该元素从视频播放进度历史数组中移出
    videoUpdateTime.splice(videoUpdateTime.findIndex(item=>item.vid===event.currentTarget.id),1);
    this.setData({
      videoUpdateTime
    })
  },
  // 自定义下拉刷新的回调 :scroll-view
  handleRefresher(){
    // 再次发送请求,获取最新的视频列表数据
    this.getVideoList(this.data.navId);
  },
  // 自定义上拉触底的回调 :scroll-view
  handleToLower(){
    /* 数据分页:1、后端分页 2、前端分页
    * 后端分页: 发送请求,最新的数据追加到视频的后方
    * 前端分页: 在前端截取最新的数据追加到视频的后方
    * */
    let newVideoList=[...获取的数据];
    let videoList=this.data.videoList;
    videoList.push(..newVideoList);
    this.setData({
      videoList
    })
  }
})

推荐阅读