小程序做滑屏视频,按照h5的思路开发。一路采坑……

尝试:

第一次:relative布局,使用translateY来实现实时上滑。直接借鉴H5的思路。

页面布局relative,一个视频宽度空间充满屏幕。

每次向下只多加载一个视频,每次只保持页面存储三个屏幕的内容,也就是三个视频,向上滑动一次,再渲染一个视频。监听手势滑动,改变当前可视区域的translateY。嗯,可以的。

然后第一步核心流程就卡住了,手势touchmove,然后改变translateY非常卡,性能很好的手机,都能看到卡顿现象,差的手机更不用说,set-data本来就是异步的,实时操作set-data太频繁,小程序处理性能完全比不上H5的webview。

那既然是是滚动交互的逻辑层和视图层交互性能差,那我们就要规避这个交互,于是想试试scroll-view,这个可是系统滚动的,不需要Js参与。

第二次:使用scroll-view

外层套一个scroll-view,内层用多个video充满屏幕。

每次当前视频区域内,上滑只有一个视频,下滑也只有一个视频,页面上只有三个视频。手势上滑下滑都非常流畅,简直perfect。

但是在可视区域只有一个视频,用户滑动距离短,松手的时候视频可是要自动滑下去归位呀,监听pageScroll停止之后,手动判断滚动距离,然后设置scroll-top,但是设置完之后页面明显延迟了1s,滚动完之后,停留了1s钟然后才归位,体验……很差。

这个是scroll-view的归位问题。而且文档也说了不要在scroll-view中使用video。

既然scroll-view不能使用video,导致设置值这么慢,swiper是系统支持滚动和归位呢,多好啊。那我是否可以用swiper来试试呢。

第三次:使用swiper

使用一个swiper外层,在swiper-item里面嵌入视频,vertical=true,每一个视频还是充满屏幕,

在swiper-item里面嵌入video之后,video是最高层,并不能触发swiper的滑动事件,swiper的滑动根本不生效,监听video的滑动,去更新swiper,那问题一样,卡卡卡。

来去N回合,还是放弃了实时滑动,看来小程序中要如H5一样,做个好的滑屏不容易呀~

关键实现技术点:

1、页面使用absolute布局,监听视频的touchmove事件,然后在touchend之后,判断是否翻页,如果要翻页,修改animation的Y位移值。

const animation = wx.createAnimation({duration: 300,timingFunction: 'ease',
});
animation.translateY(y).step();

2、video,input,cover-view共存

video,input是最高层,且input覆盖不了video。于是采用在评论页面将视频缩小到顶部。中间用input框,底部用view渲染的评论信息。这样解决了输入框和video的层级问题,更好的解决了cover-view评论渲染慢的问题。

3、视频滑动的时候,上一个视频,或者下一个视频需要的是暂停。

未播放的视频,只能pause,不能stop,否则某些手机无法再次play了。

当弹出键盘的时候,需要隐藏上一个视频,即让left:-200%,否则部分手机上会错位,播放视频和显示不一致。

4、视频未播放,也不能隐藏,或者left:-200%这样类似H5的处理方式,否则闪烁明显。

下一个视频,不能隐藏,必须渲染上去,否则滑动的时候回闪烁。

5、视频滑动增加videoLock。

增加videoLock,防止手势不停的翻页,否则部分手机播放异常,一直加载中,本身也没必要有刷刷刷的快速不停翻屏的需求。

6、视频播放,需要提前静音播放下一个视频。

下一个视频渲染上去的话,如果只是渲染,不去play(),那么部分手机无法播放,只会一直转圈,播放不了,所以需要先muted播放1s,然后timeupdate监听暂停。

const current = e.detail.currentTime;const duration = e.detail.duration;// 兜底if (duration <= 0) return;const {totalindex} = e.currentTarget.dataset;let index = -1;this.data.feedList.some((d, i) => {if (d.totalIndex == totalindex) {index = i;return true;}});if (index >= 0 && index != this.data.current) {if (totalindex != this.currentTotal) {const v = wx.createVideoContext('myVideo' + totalindex);v.pause();// v.stop();  不能stop}this.videoContext = wx.createVideoContext('myVideo' + this.currentTotal);this.videoContext.play();return;}const obj = {play_time: (current * 100) / duration};this.setData(obj);

7、cover-view性能很差,且必须是video加载之后渲染上去的才可以让cover-view盖住video。

这个是大坑,本身渲染性能差,你还得滞后video渲染,所以每次滑屏的时候,需要设置重新渲染一下才可以。

8、视频翻页的时候,需要删除视频。

减少页面上的节点和对象,否则用不了多久就crash了。

9、监听touchend,touchmove,touchstart事件

监听事件需要放在video和,cover-view上,因为部分手机的video是无法响应touch事件,所以双重保护。

this.videoLock = 1;
const windowHeight = this.windowHeight;
const maxHeight = (this.data.feedList.length - 1) * windowHeight * -1;
let y = this.transY;
if (touchY - Math.abs(this.lastY) < 20) {if (this.lastY < 0) {if (y > maxHeight) {y -= windowHeight;}} else {if (y < 0) {y += windowHeight;}}
// video和cover-view都响应touch事件,但是总是只会一个响应的
<video muted="{{current==feedIndex?false:true}}" autoplay="{{true}}" preload="meta" src="{{feedData.videourl}}" id="myVideo{{feedData.totalIndex}}" data-totalindex="{{feedData.totalIndex}}" bindtimeupdate="timeupdate" bindtouchstart="touchstart" catchtouchmove="touchmove" catchtouchend="touchend" data-index="{{feedIndex}}" bindtap="maskTap"  loop="{{true}}" custom-cache="{{false}}" controls="{{false}}"></video><cover-view wx:if="{{feedData.showCover}}" class="video_mask" bindtouchstart="touchstart" catchtouchmove="touchmove" catchtouchend="touchend" bindtap="maskTap"></cover-view>

监听页面滑动动作之后,然后决定视频是否需要位移。当手势滑动之后,需要移动视频的时候,就设置animation,让页面移动到想要的位置。

// touchend之后,计算是上滑还是下滑
this.videoLock = 1;
const windowHeight = this.windowHeight;
const maxHeight = (this.data.feedList.length - 1) * windowHeight * -1;
let y = this.transY;
if (touchY - Math.abs(this.lastY) < 20) {if (this.lastY < 0) {if (y > maxHeight) {y -= windowHeight;}} else {if (y < 0) {y += windowHeight;}}
}

每翻页一个屏幕,去拉取下一个视频。

需要动态删除翻过的视频。如下是翻一页就删除上一个视频,开始我是保存上一个视频。实现方式一样。

//动态删除视频
self.setData(obj, () => {// let cur = self.data.current;// if (cur <= 1) {//     getMore();//     return;// }const obj = {};// cur = 1;const animation = wx.createAnimation({duration: 0,timingFunction: 'ease',});// self.transY = self.windowHeight * -1 + 0.01;self.transY = 0;animation.translateY(self.transY).step();const fl = self.data.feedList.slice(1);self.data.feedList = fl;// console.log('video set fl', self.data.feedList.length);obj.feedList = fl;obj.animData = animation.export();obj.current = 0;self.setData(obj, () => {getMore();});
});

监听视频的timeouupdate,去更新播放视频的进度。totalIndex是所有查询出来的视频的索引。对应每一个视频的节点的id。这里的暂停视频,不能stop,我这里注释了,原因是stop之后,iphone8 6.7.1手机无法play,会一直停留在加载状态。

timeupdate(e) {const current = e.detail.currentTime;const duration = e.detail.duration;// 兜底if (duration <= 0) return;const {totalindex} = e.currentTarget.dataset;let index = -1;this.data.feedList.some((d, i) => { // 因为list会动态删除,所以target的Index不可靠,会出现混乱if (d.totalIndex == totalindex) {index = i;return true;}});if (index >= 0 && index != this.data.current) {if (totalindex != this.currentTotal) {const v = wx.createVideoContext('myVideo' + totalindex);v.pause();// v.stop();}this.videoContext = wx.createVideoContext('myVideo' + this.currentTotal);this.videoContext.play();return;}const obj = {play_time: (current * 100) / duration};this.setData(obj);
}

监听视频的事件,我这边是监听video和cover-view,原因是在部分手机上video上的touch根本不响应(iphone8 6.7.1)。

这里使用muted和autoplay,是因为xxx手机在滑动之后,想要播放视频,用代码无法播放。需要先load,让静音播放一下,然后被timeupdate暂停。

// video和cover-view都响应touch事件,但是总是只会一个响应的
<video muted="{{current==feedIndex?false:true}}" autoplay="{{true}}" preload="meta" src="{{feedData.videourl}}" id="myVideo{{feedData.totalIndex}}" data-totalindex="{{feedData.totalIndex}}" bindtimeupdate="timeupdate" bindtouchstart="touchstart" catchtouchmove="touchmove" catchtouchend="touchend" data-index="{{feedIndex}}" bindtap="maskTap"  width="100%"  loop="{{true}}" custom-cache="{{false}}" controls="{{false}}"></video><cover-view wx:if="{{feedData.showCover}}" class="video_mask" bindtouchstart="touchstart" catchtouchmove="touchmove" catchtouchend="touchend" bindtap="maskTap"></cover-view>

页面截图:好吧,截图被压缩了,这个csdn处理不好,要按比例缩小图片啊~

微信小程序实现多视频video采坑,上下滑动视频相关推荐

  1. 微信小程序后端mysql数据库_微信小程序后台springboot+mybatis+mysql“采坑”集锦

    "采坑"错误集锦 1.service层 错误描述:2019-04-14 22:09:52.027 ERROR 8416 --- [nio-8082-exec-5] o.a.c.c. ...

  2. 微信小程序中播放海康萤石云HLS '.m3u8'视频 video标签

    微信小程序中播放海康萤石云HLS '.m3u8'视频 video标签 前言 萤石云开放平台 微信开发者工具 前言 因为项目需要在微信小程序上展示实时视频流信息,以下内容是我将萤石云平台官方文档和自己实 ...

  3. 微信小程序上传组件(可同时长传图片+视频)

    写了个微信小程序上传组件,同时支持上传视频+图片,并且可以返显. 废话不多说,上代码: upload.wxml <view class="clearfix"><v ...

  4. 微信小程序实现大转盘抽奖----踩坑之路

    微信小程序实现大转盘抽奖----踩坑之路 需求:现在有一个小程序抽奖页面如下,此类抽奖方式为大转盘 思路:由服务端获取抽奖次数和奖品,根据服务端的中奖概率来决定是否中奖,最后利用小程序动画将转盘转起来 ...

  5. php 实现tab切换_微信小程序实例:实现顶部tab切换以及滑动切换时导航栏会随着移动的效果(代码)...

    本篇文章给大家带来的内容是关于微信小程序实例:实现顶部tab切换以及滑动切换时导航栏会随着移动的效果(代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 实现的效果: js: Pa ...

  6. 微信小程序开发经验总结(遇到的坑和问题汇总)

    小编推荐:Fundebug专注于JavaScript.微信小程序.微信小游戏,Node.js和Java实时BUG监控.真的是一个很好用的bug监控费服务,众多大佬公司都在使用. 前言: 前段时间公司打 ...

  7. 微信小程序项目实战:电影购票系统-李宁-专题视频课程

    微信小程序项目实战:电影购票系统-1644人已学习 课程介绍         本课程主要介绍了scrollview布局,导航.从服务端获取数据,以及处理数据的方法. 课程收益     本课程的目标是让 ...

  8. 微信小程序开发区块链钱包-CSDN公开课-专题视频课程

    微信小程序开发区块链钱包-398人已学习 课程介绍         应用微信小程序开发基于区块链的钱包界面,包含余额显示.转账.充值等功能. 课程收益     1.小程序组件介绍 2.相关API介绍 ...

  9. 微信小程序支付最容易犯的坑notify_url(支付回调)

    最近做了微信小程序支付,支付成功之后发现notify_url回调地址竟然没有访问. 检查了无数次代码,下单结果里面的回调地址看了又看,都没有错啊. 把回调地址复制出来到浏览器上面,外网也是可以访问的啊 ...

  10. 【小程序开发】微信小程序开发中遇到的那些坑...

    第一坑: 设置了三个tabBar,却默认显示第二个,不能展示我的第一个[首页]. "list": [{"pagePath":"page/KTGJ/in ...

最新文章

  1. System.PlatformNotSupportedException
  2. odoo8.0+PyCharm4.5开发环境配置
  3. WPF内存泄露:CollectionViewSource.GetDefaultView导致Cache对象
  4. 51单片机数字钟的实现
  5. 剑指 Offer 64. 求1+2+…+n(面试题中的短路与)
  6. dialog的二次封装
  7. DB 管理的重要工具(数据字典)
  8. 2022年天猫618超级红包玩法入口
  9. 如何下载哔哩哔哩视频
  10. vant-list上拉加载onload事件触发多次
  11. 在QQ浏览器打开html,QQ浏览器显示网页打开错误的解决方法
  12. 吐槽 intent:#Intent;S.K_1171477665=;end
  13. flowchart流程图编程语言下载_flowchart.net
  14. C99 designator ‘name’ outside aggregate initializer
  15. 算法笔记(胡凡)刷题收获@Kaysen
  16. 输出数组中满足条件元素的坐标
  17. mac上好用的文档转换器Doxillion Plus
  18. codeforces 250B Restoring IPv6
  19. 卷积法求解系统的零状态响应_利用卷积可以求解系统的零状态响应..ppt
  20. SQL Server之查询检索操作

热门文章

  1. 1/4-36UNS-2A的螺纹
  2. AutoCAD Plant 3d管道设计基础到中高级进阶视频教程
  3. swf是什么文件以及与fla格式的区别
  4. 高端程序员上班摸鱼指南
  5. UnRaid配置文件、启动U盘定时备份方案
  6. spring cloud系列eureka客服端搭建
  7. 软件破解技术之API替换
  8. 相对客观的权重计算方法——熵权法
  9. 中兴java笔试题_中兴Java开发笔试题目及答案(7)
  10. 天珣系统查找计算机登陆,天珣内网安全风险管理与审计系统