From be80b22a4a0fcd33e1b17ebdb86eba91cc7de4d2 Mon Sep 17 00:00:00 2001 From: peng <peng.com> Date: 星期三, 02 七月 2025 18:59:06 +0800 Subject: [PATCH] Merge remote-tracking branch 'origin/dev' into dev --- pages/video/video-play.vue | 322 ++++++++++++++++++++++++++++++++++++----------------- 1 files changed, 219 insertions(+), 103 deletions(-) diff --git a/pages/video/video-play.vue b/pages/video/video-play.vue index 4cf61c2..cb2bb48 100644 --- a/pages/video/video-play.vue +++ b/pages/video/video-play.vue @@ -1,32 +1,43 @@ <template> <view class="video-container"> + <!-- 瑙嗛鍔犺浇 --> + <zero-loading v-show="videoLoading" type="circle" color="#0ebd57" text=""></zero-loading> <!-- 瑙嗛鍒楄〃 --> <swiper class="video-swiper" vertical - circular :current="currentIndex" @change="onSwiperChange" + :duration="250" + easing-function="linear" > - <swiper-item v-for="(item, index) in videoList" :key="item.id"> - <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'"> + <swiper-item + v-for="(item, index) in videoList" + :key="item.id" + @touchstart="handleSwiperStart" + @touchmove="handleSwiperMove" + @touchend="handleSwiperEnd(item)" + > + <view :style="{width: '100%', height: windowHeight - marginBottom + 'px'}" 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> <video + v-if="index >= currentIndex - videoLiveOffset && index <= currentIndex + videoLiveOffset" :id="'video'+index" :ref="'video'+index" :src="item.videoUrl" - :autoplay="currentIndex === index" + :autoplay="index === currentIndex" :controls="false" :loop="true" - :object-fit="item.objectFit" + :object-fit="item.videoFit" :enable-progress-gesture="false" + :show-center-play-btn="false" class="video-item" @play="onPlay(item.id, index)" @pause="onPause(index)" @@ -34,13 +45,13 @@ @click="togglePlay(index)" @timeupdate="onTimeUpdate($event)" @loadedmetadata="onLoadedMetadata($event)" - + @waiting="videoWaiting(index)" ></video> <!-- 鑷畾涔夋帶鍒舵潯 --> <view - @touchstart="handleTouchStart" - @touchmove="handleTouchMove" - @touchend="handleTouchEnd" + @touchstart.stop="handleTouchStart" + @touchmove.stop="handleTouchMove" + @touchend.stop="handleTouchEnd" class="container"> <!-- 杩涘害鏉� - 鏁翠釜鍖哄煙鍙嫋鍔� --> <view class="process-warp" :style="{ opacity: showProcess ? 1 : 0 }"> @@ -116,31 +127,35 @@ </view> </view> - <!-- 鍙充晶浜掑姩鎸夐挳 --> - <view class="action-buttons"> - <view class="avatar-container"> - <image class="avatar" @click="jumpToHomePage(item.authorId)" :src="item.authorAvatar" mode="aspectFill"></image> - <!-- 鍏虫敞鍥炬爣 - 浣跨敤缁濆瀹氫綅 --> - <view v-if="!item.subscribeThisAuthor" class="follow-icon" @click="subscribeAuth(index, item.authorId)"> - <text class="iconfont"></text> - </view> - </view> - <view class="action-item" @click="toggleCollect(item, index)"> - <text class="iconfont" v-if="item.collected"></text> - <text class="iconfont" v-else></text> - <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text> - </view> - <view class="action-item" @click="showComments(item)"> - <text class="iconfont"></text> - <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text> - </view> - <view class="action-item"> - <button open-type="share" class="custom-share-btn" :data-obj="item"> - <text class="iconfont"></text> - </button> - - </view> - </view> + <!-- 鍙充晶浜掑姩鎸夐挳 --> + <view class="action-buttons"> + <view class="avatar-container"> + <image class="avatar" @click="jumpToHomePage(item.authorId)" :src="item.authorAvatar" mode="aspectFill"></image> + <!-- 鍏虫敞鍥炬爣 - 浣跨敤缁濆瀹氫綅 --> + <view v-if="!item.subscribeThisAuthor" class="follow-icon" @click="subscribeAuth(index, item.authorId)"> + <text class="iconfont"></text> + </view> + </view> + <view class="action-item" @click="toggleThumbsUp(item, index)"> + <text class="iconfont" v-if="item.thumbsUp"></text> + <text class="iconfont" v-else></text> + <text style="font-size: 10px;font-weight: lighter;">{{item.thumbsUpNum}}</text> + </view> + <view class="action-item" @click="showComments(item)"> + <text class="iconfont"></text> + <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text> + </view> + <view class="action-item" @click="toggleCollect(item, index)"> + <text class="iconfont" v-if="item.collected"></text> + <text class="iconfont" v-else></text> + <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text> + </view> + <view class="action-item"> + <button open-type="share" class="custom-share-btn" :data-obj="item"> + <text class="iconfont"></text> + </button> + </view> + </view> </swiper-item> </swiper> @@ -228,7 +243,16 @@ </template> <script> -import { getRecommendVideos, savePlayRecord, subscribe, getVideoComments, addVideoComment, thubmsUpComment, cancelThubmsUpComment } from "@/api/video.js"; +import { + getRecommendVideos, + savePlayRecord, + subscribe, + getVideoComments, + addVideoComment, + thubmsUpComment, + cancelThubmsUpComment, + changeThumbsUp, +} from "@/api/video.js"; import { changeCollect } from "@/api/collect.js"; import { saveShare } from "@/api/share.js"; import storage from "@/utils/storage.js"; @@ -291,24 +315,31 @@ startPlayTime: 0 // 杩欎釜瑙嗛浠庝粈涔堟椂鍊欏紑濮嬫挱鏀剧殑 }, currentVideoIsPlaying: true, // 褰撳墠瑙嗛鏄惁姝e湪鎾斁 - isFullScreen: false, - windowHeight: 0, currentIndex: 0, // 褰撳墠鎾斁鐨勮棰戠储寮� - videoList: [ - - ], // 瑙嗛鍒楄〃鏁版嵁 - videoContexts: [], // 瑙嗛涓婁笅鏂囧璞¢泦鍚� + videoLoading: false, // 瑙嗛缂撳啿涓� + videoList: [], // 瑙嗛鍒楄〃鏁版嵁 + videoBufferOffset: 0.1 ,// 瑙嗛棰勫姞杞藉弬鏁� + videoLiveOffset: 2, // 淇濈暀褰撳墠瑙嗛鍓嶅悗鍚勫灏戜釜瑙嗛涓婁笅鏂� + touchXY: { // 鐩戝惉宸︽粦鍙虫粦 + startX: 0, + endX: 0, + startY: 0, + endY: 0 + }, loading: false, // 鏄惁姝e湪鍔犺浇 videoQuery: { pageNumber: 1, - pageSize: 6, + pageSize: 10, authorId: '', - videoFrom: '' - } + videoFrom: '', + keyword: '' + }, + marginBottom: 0, // 搴曢儴瀹夊叏鍖哄煙 + windowHeight: 0 // 鍙娇鐢ㄥ睆骞曢珮搴� } }, onShow() { - this.loadVideos() + // this.loadVideos() // 濡傛灉瑙嗛鎸変笅鏆傚仠鍚庡垏鎹㈤〉闈㈠啀鍥炲埌椤甸潰鏃讹紝鍙畻鏆傚仠鏃堕棿锛堝洜涓烘殏鍋滄椂闂村拰绂诲紑椤甸潰鏃堕棿鏄噸澶嶇殑锛屽彧绠椾竴涓級 if(this.startHidenTime !== 0 && this.currentVideoIsPlaying) { const duration = Date.now() - this.startHidenTime @@ -320,25 +351,44 @@ }, onUnload() { uni.removeStorageSync("playInfo"); + uni.removeStorageSync("searchPlayInfo"); + }, + onReady() { + }, onLoad(option) { - const playInfo = uni.getStorageSync("playInfo", playInfo); + this.marginBottom = uni.getSystemInfoSync().safeAreaInsets.bottom + this.windowHeight = uni.getSystemInfoSync().windowHeight + const playInfo = uni.getStorageSync("playInfo"); + const searchPlayInfo = uni.getStorageSync("searchPlayInfo"); if(playInfo) { + this.currentIndex = playInfo.playIndex; this.videoList = playInfo.videoList; - console.log("鎷垮埌鏁版嵁浜�",playInfo); this.videoQuery.pageNumber = playInfo.pageNumber; this.videoNoMore = playInfo.nomore; this.videoQuery.authorId = option.authorId; this.videoQuery.videoFrom = option.videoFrom; - this.currentIndex = playInfo.playIndex; + this.currentVideoIsPlaying = true; + this.$nextTick(() => { + const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this); + videoContext.play() + }) + } else if (searchPlayInfo) { // 鎼滅储椤佃烦杞繃鏉ョ殑鏁版嵁鐣ユ湁涓嶅悓 + this.currentIndex = searchPlayInfo.playIndex; + this.videoList = searchPlayInfo.videoList; + this.videoQuery.pageNumber = searchPlayInfo.pageNumber; + this.videoNoMore = searchPlayInfo.nomore; + this.videoQuery.keyword = searchPlayInfo.keyword; + this.videoQuery.videoFrom = option.videoFrom; + this.currentVideoIsPlaying = true; + this.$nextTick(() => { + const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this); + videoContext.play() + }) } else { this.videoQuery.videoFrom = 'recommend'; this.loadVideos(); } - }, - onReady() { - // 鍒濆鍖栬棰戜笂涓嬫枃 - this.initVideoContexts(); }, onShareAppMessage(e) { const userInfo = storage.getUserInfo(); @@ -623,13 +673,6 @@ } }) }, - // 鍒濆鍖栬棰戜笂涓嬫枃 - initVideoContexts() { - this.videoContexts = this.videoList.map((_, index) => { - let videoContent = uni.createVideoContext(`video${index}`, this); - return videoContent; - }); - }, // 鍔犺浇瑙嗛鏁版嵁 async loadVideos() { @@ -647,9 +690,6 @@ ), ]; } - this.$nextTick(() => { - this.initVideoContexts(); - }); this.loading = false; if(res.data.data.length < this.videoQuery.pageSize) { this.videoNoMore = true; @@ -661,29 +701,75 @@ // 婊戝姩鍒囨崲瑙嗛 onSwiperChange(e) { - // 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂� - if(!this.currentVideoIsPlaying) { - if(this.startPauseTime !== 0) { - const duration = Date.now() - this.startPauseTime - this.totalPauseTime += duration - } - } - // 淇濆瓨涓婁竴涓棰戠殑鎾斁璁板綍 - this.savePlayRecord() - const oldIndex = this.currentIndex; - this.currentIndex = e.detail.current; - - // 鏆傚仠涓婁竴涓棰� - if (this.videoContexts[oldIndex]) { - this.videoContexts[oldIndex].pause(); + this.videoLoading = false + // 濡傛灉瑙嗛澶勪簬鏆傚仠鐘舵�佸線涓嬪埛瑙嗛锛岄偅涔堥渶瑕佸啀璁$畻涓�娆℃殏鍋滄椂闂� + if(!this.currentVideoIsPlaying) { + if(this.startPauseTime !== 0) { + const duration = Date.now() - this.startPauseTime + this.totalPauseTime += duration + } + } + // 淇濆瓨涓婁竴涓棰戠殑鎾斁璁板綍 + this.savePlayRecord() + const oldIndex = this.currentIndex; + this.currentIndex = e.detail.current; + const videoContext = uni.createVideoContext(`video${oldIndex}`, this); + // 鏆傚仠涓婁竴涓棰� + videoContext.pause(); + this.startPauseTime = 0; + + // 璁剧疆褰撳墠鎾斁瑙嗛鐨勬�绘椂闀� + this.duration = this.videoList[this.currentIndex].videoDuration; + this.formartDuration = this.sliderFormatTime(this.duration); + + // 鎾斁褰撳墠瑙嗛 + const videoContext1 = uni.createVideoContext(`video${this.currentIndex}`, this); + videoContext1.play() + // 濡傛灉鍓╀綑瑙嗛涓嶈冻锛岃Е鍙戣姹傝幏鍙栨洿澶氳棰� + if (this.videoList.length - 1 < this.currentIndex + this.videoLiveOffset) { + this.loadVideos() + } + }, + + // 寮�濮嬭Е鎽� + handleSwiperStart(e) { + this.touchXY.startX = e.touches[0].pageX + this.touchXY.startY = e.touches[0].pageY + }, + // 瑙︽懜涓� + handleSwiperMove(e) { + this.touchXY.endX = e.touches[0].pageX + this.touchXY.endY = e.touches[0].pageY + }, + // 缁撴潫瑙︽懜 + handleSwiperEnd(item) { + // 闃叉婊戝姩婊氬姩鏉′篃瑙﹀彂璺宠浆 + if (this.showProcess) { + return } - this.startPauseTime = 0; - // 鎾斁褰撳墠瑙嗛 - if (this.videoContexts[this.currentIndex]) { - this.videoContexts[this.currentIndex].play(); + const diffX = this.touchXY.endX - this.touchXY.startX + const diffY = this.touchXY.endY - this.touchXY.startY + + // 鍒ゆ柇鏄惁鏄í鍚戞粦鍔紙X杞村彉鍖栧ぇ浜嶻杞村彉鍖栵級 + 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 } - }, + }, // 鑾峰彇杩涘害鏉$殑浣嶇疆鍜屽昂瀵� getBarRect() { @@ -703,7 +789,8 @@ this.startProgress = this.progress; // 璁板綍寮�濮嬫椂鐨勮繘搴� this.startX = e.touches[0].pageX; console.log("璁板綍寮�濮嬫椂鐨勮繘搴�", this.startProgress); - this.videoContexts[this.currentIndex].pause() + const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this); + videoContext.pause() // this.updateProgress(e); }, @@ -711,7 +798,6 @@ handleTouchMove(e) { if (!this.isDragging || !this.barWidth) return; clearTimeout(this.processHidenTimer) - this.videoContexts[this.currentIndex].pause() this.updateProgress(e); }, @@ -719,11 +805,12 @@ 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() + const videoContext = uni.createVideoContext(`video${this.currentIndex}`, this); + videoContext.seek(this.duration * this.progress / 100) + videoContext.play() this.processHidenTimer = setTimeout(() => { - this.showProcess = false; - }, 1000); + this.showProcess = false; + }, 1000); }, // 鏇存柊杩涘害 @@ -736,7 +823,6 @@ // 灏嗗儚绱犺窛绂昏浆鎹负杩涘害澧為噺 const deltaProgress = (deltaX / this.barWidth) * 100; - console.log("杩涘害澧為噺", deltaProgress); // 璁$畻鏂拌繘搴� = 寮�濮嬫椂鐨勮繘搴� + 婊戝姩澧為噺 let newProgress = this.startProgress + deltaProgress; @@ -768,18 +854,40 @@ } }) }, + // 鐐硅禐/鍙栨秷鐐硅禐 + toggleThumbsUp(item, index) { + let data = { + refId: item.id, + thumbsUpType: 'video' + } + const beforeThumbsUp = item.thumbsUp + const beforeThumbsUpNum = item.thumbsUpNum + if(item.thumbsUp) { + this.videoList[index].thumbsUp = false + this.videoList[index].thumbsUpNum -= 1 + } else { + this.videoList[index].thumbsUp = true + this.videoList[index].thumbsUpNum += 1 + } + changeThumbsUp(data).then(res => { + if(res.data.code !== 200) { + this.videoList[index].thumbsUp = beforeThumbsUp + this.videoList[index].thumbsUpNum = beforeThumbsUpNum + } + }) + }, // 鍗曞嚮灞忓箷锛氭殏鍋滄垨缁х画鎾斁 togglePlay(index) { + console.log("鍗曞嚮瑙嗛", index); + const videoContext = uni.createVideoContext(`video${index}`, this); if(this.currentVideoIsPlaying) { - this.videoContexts[index].pause(); + videoContext.pause(); } else { - this.videoContexts[index].play(); + videoContext.play(); } }, // 瑙嗛鎾斁浜嬩欢 onPlay(id, index) { - this.getBarRect() - this.progress = 0 if(index === this.currentIndex) { this.currentVideoIsPlaying = true; if(! this.duration) { @@ -788,9 +896,11 @@ this.formartDuration = this.sliderFormatTime(this.duration); } } else { - this.currentVideoIsPlaying = false; return } + this.getBarRect() + this.progress = 0 + console.log(id, index, "瑙﹀彂鎾斁"); this.playRecord.videoId = id; // 娌″垵濮嬪寲鎵嶈祴鍊硷紝鍥犱负涓�涓棰戦噸澶嶆挱鏀緊nPlay浼氶噸澶嶈Е鍙� if(this.playRecord.startPlayTime === 0) { @@ -800,6 +910,7 @@ const duration = Date.now() - this.startPauseTime this.totalPauseTime += duration } + this.videoLoading = false }, // 瑙嗛鏆傚仠浜嬩欢 @@ -807,11 +918,8 @@ console.log(index, "瑙﹀彂鏆傚仠"); if(index === this.currentIndex) { this.currentVideoIsPlaying = false; - } else { - this.currentVideoIsPlaying = true; - return + this.startPauseTime = Date.now() } - this.startPauseTime = Date.now() }, // 瑙嗛缁撴潫浜嬩欢 @@ -821,9 +929,17 @@ // 璁板綍鎾斁鏃堕暱 onTimeUpdate(e) { + this.videoLoading = false this.playRecord.playAt = e.detail.currentTime this.currentTime = e.detail.currentTime; this.progress = (e.detail.currentTime / this.duration) * 100 + }, + // 瑙嗛缂撳啿 + videoWaiting(index) { + if (index === this.currentIndex) { + console.log("瑙嗛缂撳啿涓�傘�傘��"); + this.videoLoading = true; + } }, // 鑾峰彇瑙嗛鎬绘椂闀� onLoadedMetadata(e) { @@ -872,7 +988,7 @@ .video-item { width: 100%; height: 100%; - object-fit: cover; + /* object-fit: cover; */ } .play-icon { position: absolute; @@ -888,7 +1004,7 @@ .video-info { width: 70%; position: absolute; - bottom: 20px; + bottom: 40px; left: 20px; color: #f8f8f8; z-index: 10; @@ -1231,7 +1347,7 @@ flex-direction: column; align-items: center; position: absolute; - bottom: 0; + bottom: 20px; width: 100%; } @@ -1260,7 +1376,7 @@ .progress-text { margin-top: 10px; font-size: 14px; - color: #666; + color: #fff; } .swiper-box { width: 100%; -- Gitblit v1.8.0