| | |
| | | :controls="false" |
| | | :loop="true" |
| | | :object-fit="item.objectFit" |
| | | :enable-progress-gesture="false" |
| | | class="video-item" |
| | | @play="onPlay(item.id, index)" |
| | | @pause="onPause(index)" |
| | | @ended="onEnded(index)" |
| | | @click="togglePlay(index)" |
| | | @timeupdate="onTimeUpdate($event)" |
| | | @loadedmetadata="onLoadedMetadata($event)" |
| | | |
| | | ></video> |
| | | <!-- 自定义控制条 --> |
| | | <view |
| | | @touchstart="handleTouchStart" |
| | | @touchmove="handleTouchMove" |
| | | @touchend="handleTouchEnd" |
| | | class="container"> |
| | | <!-- 进度条 - 整个区域可拖动 --> |
| | | <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }"> |
| | | <!-- 显示当前进度 --> |
| | | <view class="progress-text">{{ hasPlayTime }}/{{formartDuration}}</view> |
| | | <view |
| | | class="progress-bar" |
| | | id="progressBar" |
| | | > |
| | | |
| | | <!-- 已填充部分 --> |
| | | <view class="progress-fill" :style="{ width: progress + '%' }"></view> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | |
| | | </view> |
| | | |
| | | <!-- 悬挂商品链接层 --> |
| | | <view class="goods-link-warp"> |
| | |
| | | import { getRecommendVideos, savePlayRecord, subscribe, getVideoComments, addVideoComment, thubmsUpComment, cancelThubmsUpComment } from "@/api/video.js"; |
| | | import { changeCollect } from "@/api/collect.js"; |
| | | export default { |
| | | computed: { |
| | | hasPlayTime() { |
| | | return this.sliderFormatTime(this.progress > 0 ? this.duration * this.progress / 100 : 0); |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | currentTime: 0, |
| | | formartDuration: '', |
| | | duration: 0, |
| | | startX: 0, |
| | | progress: 0, // 视频进度 |
| | | startProgress : 0, // 开始滑动时的进度 |
| | | barLeft: 0, // 进度条左边界位置 |
| | | barWidth: 0, // 进度条宽度 |
| | | isDragging: false, // 是否正在拖动 |
| | | processHidenTimer: null, // 进度条隐藏定时器 |
| | | showProcess: false, // 是否显示进度条 |
| | | videoNoMore: false, // 是否还有更多视频 |
| | | commentNoMore: false, // 是否还有更多评论 |
| | | commentQuery: { |
| | |
| | | this.initVideoContexts(); |
| | | }, |
| | | methods: { |
| | | // 获取进度条的位置和尺寸 |
| | | getBarRect() { |
| | | const query = uni.createSelectorQuery().in(this); |
| | | query.select('#progressBar').boundingClientRect(rect => { |
| | | if (rect) { |
| | | this.barLeft = rect.left; |
| | | this.barWidth = rect.width; |
| | | } |
| | | }).exec(); |
| | | }, |
| | | // 跳转个人主页 |
| | | jumpToHomePage(authorId) { |
| | | uni.navigateTo({ |
| | |
| | | const input = this.$refs.commentInput; |
| | | if (input) input.focus(); |
| | | }); |
| | | }, |
| | | // 进度条时间格式化 (00:00) |
| | | sliderFormatTime(seconds) { |
| | | const mins = Math.floor(seconds / 60); |
| | | const secs = Math.floor(seconds % 60); |
| | | return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`; |
| | | }, |
| | | // 格式化时间 |
| | | formatTime(time) { |
| | |
| | | }, |
| | | // 视频播放事件 |
| | | onPlay(id, index) { |
| | | this.getBarRect() |
| | | this.progress = 0 |
| | | console.log(id, index, "触发播放"); |
| | | if(index === this.currentIndex) { |
| | | this.currentVideoIsPlaying = true; |
| | |
| | | } |
| | | this.startPauseTime = Date.now() |
| | | }, |
| | | |
| | | // 视频结束事件 |
| | | onEnded(index) { |
| | | // this.currentVideoIsPlaying = false; |
| | |
| | | |
| | | // 记录播放时长 |
| | | onTimeUpdate(e) { |
| | | this.playRecord.playAt = e.detail.currentTime |
| | | this.playRecord.playAt = e.detail.currentTime; |
| | | |
| | | this.currentTime = e.detail.currentTime; |
| | | this.progress = (e.detail.currentTime / this.duration) * 100 |
| | | }, |
| | | // 触摸开始 |
| | | handleTouchStart(e) { |
| | | this.isDragging = true; |
| | | this.showProcess = true; |
| | | this.startProgress = this.progress; // 记录开始时的进度 |
| | | this.startX = e.touches[0].pageX; |
| | | console.log("记录开始时的进度", this.startProgress); |
| | | this.videoContexts[this.currentIndex].pause() |
| | | // this.updateProgress(e); |
| | | }, |
| | | |
| | | // 触摸移动 |
| | | handleTouchMove(e) { |
| | | if (!this.isDragging || !this.barWidth) return; |
| | | clearTimeout(this.processHidenTimer) |
| | | this.videoContexts[this.currentIndex].pause() |
| | | this.updateProgress(e); |
| | | }, |
| | | |
| | | // 触摸结束 |
| | | handleTouchEnd() { |
| | | this.isDragging = false; |
| | | console.log("滑动结束", this.duration * this.progress); |
| | | this.videoContexts[this.currentIndex].seek(this.duration * this.progress / 100) |
| | | this.videoContexts[this.currentIndex].play() |
| | | this.processHidenTimer = setTimeout(() => { |
| | | this.showProcess = false; |
| | | }, 1000); |
| | | }, |
| | | |
| | | // 更新进度 |
| | | updateProgress(e) { |
| | | // 获取当前触摸点X坐标 |
| | | const currentX = e.touches[0].pageX; |
| | | |
| | | // 计算滑动距离(像素) |
| | | const deltaX = currentX - this.startX; |
| | | |
| | | // 将像素距离转换为进度增量 |
| | | const deltaProgress = (deltaX / this.barWidth) * 100; |
| | | console.log("进度增量", deltaProgress); |
| | | // 计算新进度 = 开始时的进度 + 滑动增量 |
| | | let newProgress = this.startProgress + deltaProgress; |
| | | |
| | | // 限制范围在0-100之间 |
| | | newProgress = Math.max(0, Math.min(100, newProgress)); |
| | | |
| | | this.progress = newProgress; |
| | | }, |
| | | // 获取视频总时长 |
| | | onLoadedMetadata(e) { |
| | | this.duration = e.detail.duration; |
| | | this.formartDuration = this.sliderFormatTime(this.duration); |
| | | console.log("视频总时长", this.duration); |
| | | }, |
| | | // 保存播放记录 |
| | | async savePlayRecord() { |
| | | console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime); |
| | |
| | | |
| | | .video-swiper { |
| | | width: 100%; |
| | | height: 100%; |
| | | height: calc(100% - 50px); |
| | | } |
| | | |
| | | .video-item { |
| | |
| | | .thumbs-num { |
| | | margin-left: 4rpx; |
| | | } |
| | | .container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | position: absolute; |
| | | bottom: 0; |
| | | width: 100%; |
| | | } |
| | | |
| | | .progress-bar { |
| | | position: relative; |
| | | width: 100%; |
| | | height: 16px; |
| | | background-color: #eee; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .progress-fill { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | height: 100%; |
| | | background-color: lightgray; |
| | | transition: width 0.1s; |
| | | } |
| | | .process-warp { |
| | | width: 100%; |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | } |
| | | .progress-text { |
| | | margin-top: 10px; |
| | | font-size: 14px; |
| | | color: #666; |
| | | } |
| | | </style> |