接口是在其它csdn文章中找的

首先实现上下滑动的基本功能

然后再添加暂停播放功能

最后添加自定义slier进度条,通过点击或拖拽进度条进入到视频对应的时间位置

功能要素如下:

完整代码:

<template>
	<view class="">
		<swiper class="swiper" :style="{height:screenHeight+'px'}" :vertical="true" :duration="1000"
			@transition="transition" @change="changed">
			<swiper-item class="swiper-item" :style="{height:screenHeight+'px'}" v-for="(item,index) in videoList"
				:key="index" >
				<!-- 11111{{index==changeIndex}} -->
				<video id="myVideo" class="playVideo" :style="{height:screenHeight+'px'}" object-fit="cover" autoplay
					:src="item.src" :controls="false" @tap="handleVideoTap" loop @timeupdate="onTimeUpdate($event)"
					@loadeddata="onVideoLoadedData(index)" @play="onVideoPlay" v-if="index==changeIndex||showFlag">
				</video>
				<!-- <image v-else  class="fmBox" :src="item.fmsrc" mode="aspectFill"></image> -->
				<view class="txtWrap">
					<text class="nickname" style="color: #fff;font-size: 18px;">
						@Picnic熊
					</text>
					<text class="tit"
						style="width:500rpx;color: #fff;font-size: 14px;text-overflow: ellipsis; lines:2;">
						{{item.title}}
					</text>
				</view>
			</swiper-item>
		</swiper>
		<view class="iconWrap" :style="{height:screenHeight+'px'}">
			<image class="playIcon" src="/static/play.png" style="" v-if="!playFlag"></image>
			<view class="control_box">
			
				<slider class="sliderbox" :value="currentProgress" min="0" @change="sliderChange"
					@changing="sliderChanging" max="100" activeColor=" #6d6d6d" backgroundColor="#2f2f2f"
					block-color="#6d6d6d" block-size="12" />
		
			</view>
			<view class="changing" v-if="showChanging">
				<text style="color: #fff;font-size: 20px;">{{sliderchanging}}</text>
				<text style="color: #c5c5c5;font-size: 20px;">/ {{totalDuration}}</text>
			</view>
		</view>
	</view>
</template>


<script>
	export default {
		data() {
			return {
				screenHeight: 0,
				originList: [], // 源数据
				displaySwiperList: [], // swiper需要的数据
				displayIndex: 0, // 用于显示swiper的真正的下标数值只有:0,1,2。
				originIndex: 0, // 记录源数据的下标
				changeIndex: 0, //控制video是否渲染
				page: 0, // 视频分页
				num: 0,
				flag: true,
				showFlag:false,
				videoList: [{
						"src": "https://minivideo.xiu123.cn/original/79649956972748019fb7761c6852c5b1/25d3d19-17b2a2529da.mp4",
						"title": "……… 时过尽迁!",
						"fmsrc": "../../static/fm1.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/6b474d2596d742ab8f1c1da42145ee4d/5a8969da-17afdba394d.mp4",
						"title": "完美收官/美女/靓仔",
						"fmsrc": "../../static/fm2.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/95267608f6c94ec786bf2799add0aa7a/d5538f3-17b49507b12.mp4",
						"title": "人生不过如此,且行且珍惜。",
						"fmsrc": "../../static/fm.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/e09a1efc53304a30b14258c9f81c53d3/2ca04e20-17b4ad28fe4.mp4",
						"title": "皮一下🤪🤪🤪",
						"fmsrc": "../../static/fm1.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/41ce5089729b42388d8beeebffa3b0ea/1896b231-17ea06304eb.mp4",
						"title": "❤️🧡💛💚💙💜接受自",
						"fmsrc": "../../static/fm2.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/9866913b960b48aea4ba9795e438e105/324d23bd-17ea0807e3e.mp4",
						"title": "本年度最后一场正式直",
						"fmsrc": "../../static/fm.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/1177f5d195d44404991943fc2ee6afb5/58469ddf-17ea1339711.mp4",
						"title": "555",
						"fmsrc": "../../static/fm1.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/227284517d2a4858bfe36194106f3978/138a8ce0-17ea2217e0b.mp4",
						"title": "村上树说“你要记得那",
						"fmsrc": "../../static/fm2.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/b63ba4528456418f9ded1fb9a568e0ca/3c42538d-17ea016eeb0.mp4",
						"title": "回村过大年了,家人们",
						"fmsrc": "../../static/fm.png"
					},
					{
						"src": "https://minivideo.xiu123.cn/original/9fe073c59b25443fa424a920238d186c/1e9e041d-17d71e53bd0.mp4",
						"title": "最后一个月啦/狂笑",
						"fmsrc": "../../static/fm1.png"
					}
				],
				videoContext: null,
				playFlag: true,
				currentProgress: 0, // 当前播放进度
				totalDuration: "00:00", // 视频总时长
				playTime: "00:00",
				videoPrecent: 0,
				sliderallTime: 0,
				precenting: 0,
				sliderchanging: "00:00",
				timerclear: false,
				showChanging: false, //控制定时器和changing的显示
				// sliderTimer: null, //定时器
				pageStartY: 0,
				pageEndY: 0,
			}
		},
		computed: {
			canCircular() {
				// return (this.originIndex + 1 == this.originList.length ? 0 : this.originIndex + 1) == 1;
			}
		},
		onLoad() {
			/* 获取系统信息 */
			uni.getSystemInfo({
				success: (res) => {
					this.screenHeight = res.windowHeight
				}
			});
			// 调用函数
			this.getPageID()
		},
		onReady: function(res) {
			this.videoContext = uni.createVideoContext('myVideo')
		},
		methods: {
			transition(e) {
				
				// let originListLength = this.originList.length;
				// if ((this.originIndex + 1 == originListLength ? 0 : this.originIndex + 1) == 1 && e.detail.dy < -100) {
				// 	uni.showToast({
				// 		title: '已经到顶了',
				// 		icon: 'none'
				// 	})
				// }
			},
			/* 生成随机的 pageID */
			getPageID() {
				// console.log("getPageID") 
				let pageID = parseInt(Math.random() * (0 - 100 + 1) + 100) //生成 [min,max] 的随机数
				this.getVideoList(pageID)
			},
			/* 获取视频数据 */
			getVideoList(pageID) {
				uni.request({
					url: 'https://api.apiopen.top/api/getMiniVideo?page=' + pageID +
						'&size=10&pageSize=10', // 请求数据接口
					data: {},
					success: (res) => {
						if (res.data.code == 200) {
							res.data.result.list.forEach(item => {
								//取源数据的部分属性组合成新的数组
								let obj = {}
								obj.src = item.playurl
								obj.title = item.title
								this.originList.push(obj)
							})
						}

					}
				})
			},
			changed(event) {
			
				
				this.currentProgress = 0;
				this.playFlag = true
				let {
					current
				} = event.detail;
				this.changeIndex = current;
				// console.log(event)
				let f1 = this.originList.length - 1

				if ((current + 1) >= this.originList.length) {
					console.log("到底")
					this.getPageID()
				}
			},
			handleVideoTap(e) {
				// console.log("hang")
				// this.videoContext.pause();
				if (this.playFlag) {
					this.videoContext.pause();
					this.playFlag = false
				} else {
					this.videoContext.play();
					this.playFlag = true
				}
			},
			onTimeUpdate(e) {
				let playTime = e.detail.currentTime
				this.sliderallTime = e.detail.duration
				this.playTime = this.formatSecondsToMMSS(Math.floor(playTime));
				this.totalDuration = this.formatSecondsToMMSS(Math.floor(this.sliderallTime));

				if (this.timerclear) {
					// clearTimeout(this.sliderTimer)
					// this.sliderTimer = null
					this.showChanging = false
					this.timerclear = false
					return
				}
				// this.sliderTimer = setTimeout(() => {
				// })
				this.currentProgress = playTime / this.sliderallTime * 100;
			},
			formatSecondsToMMSS(seconds) {
				let minutes = Math.floor(seconds / 60);
				let remainingSeconds = seconds % 60;
				minutes = ('0' + minutes).slice(-2);
				remainingSeconds = ('0' + remainingSeconds).slice(-2);
				return `${minutes}:${remainingSeconds}`
			},
			sliderChange(e) {
				this.videoPrecent = e.detail.value
				let designatedTime = (this.videoPrecent / 100) * this.sliderallTime
				this.videoContext.seek(parseInt(designatedTime))
			},
			sliderChanging(e) {
				this.showChanging = true
				this.timerclear = true
				this.precenting = e.detail.value
				let changetiming = (this.precenting / 100) * this.sliderallTime
				this.sliderchanging = this.formatSecondsToMMSS(Math.floor(changetiming));
			},

			onVideoPlay(index) {
				// console.log("onVideoPlay")
			}
		},
		onHide() {
			this.videoContext.pause()
			this.playFlag = false
		},
		onShow() {
			if (this.videoContext) {
				this.videoContext.play()
				this.playFlag = true
			}
		}
	}
</script>

<style lang="scss" scoped>
	.swiper {
		width: 750rpx;
	}

	.swiper-item {
		width: 750rpx;
		position: relative;
		// background-color: red;

		.fmBox {
			width: 750rpx;
			height: 500rpx;
			position: absolute;
			bottom: 0;
			left: 0;
		}

		.txtWrap {
			width: 750rpx;
			height: 100px;
			position: absolute;
			bottom: 0;
			left: 0;
			padding: 10rpx 30rpx 0;
			background: linear-gradient(to top, rgba(25, 25, 25, 1.0), rgba(118, 118, 118, 0.01));
			justify-content: flex-end;
			padding-bottom: 70rpx;

			.nickname {
				margin-bottom: 10rpx;
			}

			.tit {}
		}

	}

	.iconWrap {
		width: 750rpx;
		height: 300rpx;
		position: fixed;
		top: 0;
		left: 0;

		.playIcon {
			position: absolute;
			left: 335rpx;
			top: 400rpx;
			width: 80rpx;
			height: 80rpx;
		}

		.control_box {
			width: 750rpx;
			height: 40rpx;
			position: absolute;
			left: 0;
			bottom: 0rpx;
			flex-direction: row;

			// background:linear-gradient(to top,rgba(0,0,0,1),rgba(94, 94, 94, 0.3)) ;
			.sliderbox {
				// transform: scale(0.9,0.9);
				transform: scale(0.95);
			}

			.time {
				width: 100rpx;
				border: 1px solid blue;
			}
		}

		.changing {
			flex-direction: row;
			position: absolute;
			width: 270rpx;
			height: 50rpx;
			bottom: 220rpx;
			left: 240rpx;
			justify-content: center;
			background-color: rgba(118, 118, 118, 0.1);
		}

	}
</style>

由于用v-if控制视频切换时播放暂停,所以在滑动时会有白屏,用户体验不好

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐