| | |
| | | <swiper |
| | | class="video-swiper" |
| | | vertical |
| | | circular |
| | | :current="currentIndex" |
| | | @change="onSwiperChange" |
| | | easing-function="linear" |
| | | > |
| | | <swiper-item v-for="(item, index) in videoList" :key="item.id"> |
| | | <swiper-item |
| | | v-for="(item, index) in videoList" |
| | | :key="item.id" |
| | | @touchstart="handleSwiperStart" |
| | | @touchmove="handleSwiperMove" |
| | | @touchend="handleSwiperEnd(item)" |
| | | > |
| | | <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'"> |
| | | <!-- 播放按钮(仅当视频暂停时显示) --> |
| | | <view |
| | | class="play-icon" |
| | | @click="togglePlay(index)" |
| | | v-if="!currentVideoIsPlaying" |
| | | v-show="!currentVideoIsPlaying" |
| | | > |
| | | <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image> |
| | | </view> |
| | |
| | | :id="'video'+index" |
| | | :ref="'video'+index" |
| | | :src="item.videoUrl" |
| | | :autoplay="currentIndex === index" |
| | | :autoplay="false" |
| | | :controls="false" |
| | | :loop="true" |
| | | :object-fit="item.objectFit" |
| | |
| | | @click="togglePlay(index)" |
| | | @timeupdate="onTimeUpdate($event)" |
| | | @loadedmetadata="onLoadedMetadata($event)" |
| | | |
| | | ></video> |
| | | <!-- 自定义控制条 --> |
| | | <view |
| | |
| | | isFullScreen: false, |
| | | windowHeight: 0, |
| | | currentIndex: 0, // 当前播放的视频索引 |
| | | videoList: [ |
| | | |
| | | ], // 视频列表数据 |
| | | videoList: [], // 视频列表数据 |
| | | videoContexts: [], // 视频上下文对象集合 |
| | | videoBufferOffset: 0.1 ,// 视频预加载参数 |
| | | videoLiveOffset: 5, // 保留当前视频前后各多少个视频上下文 |
| | | touchXY: { // 监听左滑右滑 |
| | | startX: 0, |
| | | endX: 0, |
| | | startY: 0, |
| | | endY: 0 |
| | | }, |
| | | loading: false, // 是否正在加载 |
| | | videoQuery: { |
| | | pageNumber: 1, |
| | | pageSize: 6, |
| | | pageSize: 10, |
| | | videoFrom: 'recommend' |
| | | } |
| | | } |
| | |
| | | } else { |
| | | this.loadVideos(); |
| | | } |
| | | }, |
| | | onReady() { |
| | | // 初始化视频上下文 |
| | | this.initVideoContexts(); |
| | | }, |
| | | onShareAppMessage(e) { |
| | | const userInfo = storage.getUserInfo(); |
| | |
| | | }, |
| | | // 初始化视频上下文 |
| | | initVideoContexts() { |
| | | this.videoContexts = this.videoList.map((_, index) => { |
| | | let videoContent = uni.createVideoContext(`video${index}`, this); |
| | | return videoContent; |
| | | }); |
| | | const start = Math.max(0, this.currentIndex - this.videoLiveOffset); |
| | | const end = Math.min(this.currentIndex + this.videoLiveOffset, this.videoList.length - 1); |
| | | let contextsLength = this.videoContexts.length; |
| | | if (contextsLength === 0) { |
| | | // 第一次初始化 |
| | | for (let i = 0; i < this.videoList.length; i++) { |
| | | if (i < start || i > end) { |
| | | this.videoContexts.push(null) |
| | | } else { |
| | | let videoContent = uni.createVideoContext(`video${i}`, this); |
| | | videoContent.seek(this.videoBufferOffset); |
| | | videoContent.pause(); |
| | | this.videoContexts.push(videoContent); |
| | | } |
| | | } |
| | | } else { |
| | | for (let i = 0; i < this.videoList.length; i++) { |
| | | contextsLength = this.videoContexts.length |
| | | if (contextsLength - 1 >= i) { |
| | | // 如果已经是null了就不用管,因为视频加载只会在后面push,前面已经设置为null则无需处理 |
| | | if (this.videoContexts[i] == null) { |
| | | continue |
| | | } |
| | | // 超出可视化范围的视频直接释放资源,并置为null |
| | | if (i < start || i > end) { |
| | | if (this.videoContexts[i]) { |
| | | this.videoContexts[i].stop(); |
| | | this.videoContexts[i] = null |
| | | } |
| | | } |
| | | } else { |
| | | if (i < start || i > end) { |
| | | this.videoContexts.push(null); |
| | | } else { |
| | | let videoContent = uni.createVideoContext(`video${i}`, this); |
| | | videoContent.seek(this.videoBufferOffset); |
| | | videoContent.pause(); |
| | | this.videoContexts.push(videoContent); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | // 将当前视频设置为播放 |
| | | if (this.videoContexts[this.currentIndex]) { |
| | | this.videoContexts[this.currentIndex].play() |
| | | } |
| | | |
| | | }, |
| | | |
| | | // 加载视频数据 |
| | |
| | | } |
| | | |
| | | this.startPauseTime = 0; |
| | | |
| | | // 设置当前播放视频的总时长 |
| | | this.duration = this.videoList[this.currentIndex].videoDuration; |
| | | this.formartDuration = this.sliderFormatTime(this.duration); |
| | | // 播放当前视频 |
| | | if (this.videoContexts[this.currentIndex]) { |
| | | this.videoContexts[this.currentIndex].play(); |
| | | } |
| | | // 设置当前播放视频的总时长 |
| | | this.duration = this.videoList[this.currentIndex].videoDuration; |
| | | this.formartDuration = this.sliderFormatTime(this.duration); |
| | | this.clearVideoContext() |
| | | }, |
| | | |
| | | // 清除超出视频可视化区域的视频上下文 |
| | | async clearVideoContext() { |
| | | // 对超出可视化区域的视频上下文做销毁处理 |
| | | const start = Math.max(0, this.currentIndex - this.videoLiveOffset); |
| | | const end = Math.min(this.currentIndex + this.videoLiveOffset, this.videoList.length - 1); |
| | | for (let i = 0; i < this.videoContexts.length; i++) { |
| | | if (i < start || i > end) { |
| | | if (this.videoContexts[i]) { |
| | | this.videoContexts[i].stop(); |
| | | this.videoContexts[i] = null |
| | | } |
| | | } else { |
| | | if (this.videoContexts[i] == null) { |
| | | let videoContent = uni.createVideoContext(`video${i}`, this); |
| | | videoContent.seek(this.videoBufferOffset); |
| | | videoContent.pause(); |
| | | this.videoContexts[i] = videoContent; |
| | | } |
| | | } |
| | | } |
| | | // 如果剩余视频不足,触发请求获取更多视频 |
| | | if (this.videoList.length - 1 < this.currentIndex + this.videoLiveOffset) { |
| | | this.loadVideos() |
| | | } |
| | | }, |
| | | |
| | | // 开始触摸 |
| | | handleSwiperStart(e) { |
| | | console.log("开始触摸", e); |
| | | this.touchXY.startX = e.touches[0].pageX |
| | | this.touchXY.startY = e.touches[0].pageY |
| | | }, |
| | | // 触摸中 |
| | | handleSwiperMove(e) { |
| | | console.log("触摸中", e); |
| | | this.touchXY.endX = e.touches[0].pageX |
| | | this.touchXY.endY = e.touches[0].pageY |
| | | }, |
| | | // 结束触摸 |
| | | handleSwiperEnd(item) { |
| | | const diffX = this.touchXY.endX - this.touchXY.startX |
| | | const diffY = this.touchXY.endY - this.touchXY.startY |
| | | |
| | | // 判断是否是横向滑动(X轴变化大于Y轴变化) |
| | | if (Math.abs(diffX) > Math.abs(diffY)) { |
| | | if (diffX > 0) { |
| | | console.log('右滑') |
| | | if (item.goodsList && item.goodsList.length > 0) { |
| | | this.jumpToPay(item.id) |
| | | } |
| | | } else { |
| | | console.log('左滑') |
| | | } |
| | | } |
| | | // 重置坐标 |
| | | this.touchXY = { |
| | | startX: 0, |
| | | endX: 0, |
| | | startY: 0, |
| | | endY: 0 |
| | | } |
| | | }, |
| | | |
| | | // 收藏/取消收藏 |