我这边学习做音乐播放器的项目中的时候,也遇到了这个seek方法跳转的问题,我这边贴出相关代码,供参考,希望能帮到大家! 注意点: 1、这里的setTimeout函数非常重要!! 2、seek()调用后,只是将视频停在所在的播放进度,还需使用play()方法才能让视频继续播放 如果没有setTimeout延时,很可能会出现,切换回之前看过的视频,会出现多个视频在播放。而setTimeout定时器的延时,异步任务保证了能够在界面渲染好之后,再执行。避免因wx:if、wx:for未及时渲染而出现的错误。 这里我这边的视频由于是多个视频,所以用到了image列表优化,选中时将image替换成video。 优化可参考下方社区链接的问答: 同一页面存在多个video时,video无法正常播放一直在加载转圈? - 微信开放社区 https://developers.weixin.qq.com/community/develop/doc/000e4ef22583d8961919efb6b56009 —————————————————————————————————————————— Wxml文件中的相关代码: 注意点: 1、这里我没有给video标签绑定bindplay回调,因为考虑image封面图与video为互斥方式(wx:if wx:else)渲染,在视频未播放时,界面显示的是image封面图,所以只需点击image时候,让image触发播放视频的回调就可以。 2、我这边的模拟器和真机测试下,延时200ms足够,这里视实际情况来调整。 <view class="videoItem" wx:for="{{videoList}}" wx:key="id"> <video src="{{item.data.urlInfo.url}}" id="{{item.data.vid}}" poster="{{item.data.coverUrl}}" class="video" wx:if='{{videoId === item.data.vid}}' object-fit="fill" bindtimeupdate="handleTimeUpdate" bindended="handleEnded" ></video> <!-- 性能优化,使用image图片代替video标签 --> <!-- 一开始video隐藏,所以需要image传入id --> <image wx:else src="{{item.data.coverUrl}}" class="image" bindtap="handlerPlay"id="{{item.data.vid}}"></image> </view> JS中的相关代码: handlerPlay(event) { // 获取当前视频的id let vid = event.currentTarget.id // 更新data中的videoId的状态数据 this.setData({ videoId: vid }) // 创建控制video标签的实例对象 this.videoContextPrev = wx.createVideoContext(vid) // 关闭当前播放的视频 this.videoContextPrev.stop() // 判断当前视屏是否有播放记录,如果有,跳转至指定播放位置 let { videoUpdateTime } = this.data let videoItem = videoUpdateTime.find(item => item.vid === vid) // 情况一:如果有播放记录,从记录处继续播放 if (videoItem) { // 获取播放的时间点,单位/s let timepoint = videoItem.currentTime this.timer1 = setTimeout(() => { let videoContext1 = wx.createVideoContext(vid) // 跳转到指定的时间位置 videoContext1.seek(timepoint) videoContext1.play() }, 200) } // 情况二:如果没有播放记录,开始新的播放 else { this.timer2 = setTimeout(() => { let videoContext2 = wx.createVideoContext(vid) videoContext2.play() }, 200) } }, // 监听视频播放进度的回调 handleTimeUpdate(event) { let { videoUpdateTime } = this.data let videoTimeObj = { vid: event.currentTarget.id, currentTime: event.detail.currentTime } /* 判断记录播放时长的videoUpdateTime数组中是否有当前视频的播放记录 如果有修改原有播放记录,如果没有需要在数组中添加当前视频的播放记录 */ let videoItem = videoUpdateTime.find(item => item.vid === videoTimeObj.vid); if (videoItem) { // 之前有播放记录 videoItem.currentTime = videoTimeObj.currentTime; } else { // 之前没有播放记录 videoUpdateTime.push(videoTimeObj); } // 更新videoUpdateTime的状态 this.setData({ videoUpdateTime }) }, // 视频播放结束调用的回调 handleEnded(event) { // 移除播放记录时长数组中当前视频的对象 let { videoUpdateTime } = this.data let index = videoUpdateTime.findIndex(item => item.vid === event.currentTarget.id) // splice(index,howmany) ——> 删除从index位置开始的数,howmany为删除的个数 // 若 howmany 小于等于 0,则不删除 videoUpdateTime.splice(index, 1) this.setData({ videoUpdateTime: videoUpdateTime, // 这里将videoId重置,使页面渲染的视频均为image封面图覆盖 videoId: '' }) },
VideoContext.seek跳转视频指定位置无效,调用后从头开始播放?VideoContext.seek跳转视频指定位置无效,调用后从头开始播放? 视频长度10 VideoContext.seek(8)调用后重新播放无法跳转正确的位置
2022-05-07