需求要求:app端视频播放可以滑动,记录观看时间

分析:采用swiper中内嵌video方法

遇到的坑

1.直接使用vue页面在APP端不显示,解决:swiper内嵌视频需要使用nvue ,视频需要使用nvue组件
2.视频滑动出现滑动几次才切换bug,解决:禁用swiper touch 使用touchstart和touchend,判断切换
注意:nvue页面调用方法需要使用uni.request,外部封装的无法使用,下方代码只供参考,cv需要注意一下

详细代码:
video组件:

<template>
	<div class="video">
		<video @timeupdate="timeupdate" @pause="pause" :style="style" :initial-time="times" class="myVideo" @error="videoErrorCallback" :id="`video_${index}`" :src="src"
			:enable-play-gesture="true" :enable-progress-gesture="false" :show-fullscreen-btn="false" :show-center-play-btn="true" show-mute-btn title="xxxxxxxx">
		</video>
		<div class="title"><text style="color: #ffffff;">{{title}}</text></div>
	</div>
</template>

<script>
	export default {
		props: {
			index: {
				type: Number,
				default: 0
			},
			src: {
				type: String,
				default: ""
			},
			play: {
				type: Boolean,
				default: false
			},
			title:{
				type: String,
				default: ""
			},
			times:{
				type: Number,
				default: 0
			}
		},
		data() {
			return {
				videoContext: null,
				style: '',
				time:0,
				duration:0
			}
		},
		watch: {
			play(newVal, oldVal) {
				this.videoPlay();
			}
		},
		created() {
			this.videoContext = uni.createVideoContext('video_' + this.index);
			try {
				const res = uni.getSystemInfoSync();
				this.style = "height:" + res.windowHeight + "px;"
			} catch (e) {
				// error
			}
		},
		methods: {
			videoErrorCallback(e) {

			},
			timeupdate(event){
				this.duration = event.detail.duration
				if(!this.play) return
				if(this.time>=this.duration) this.time=0  
				this.time = event.detail.currentTime
			},
			videoPlay() {
				if (this.play) {
					this.videoContext.play();
				} else {
					this.videoContext.pause();
					// this.$emit('pause',this.time)
				}
			},
			pause(e){
				// console.log(e);
				this.$emit('pause',this.time);
			}
		}
	}
</script>

<style scoped>
	.myVideo {
		width: 750rpx;
		position: relative;
	}

	.title {
		width: 700rpx;
		position: absolute;
		bottom: 100px;
		left: 20px;
	}
</style>

视频播放代码:

<template>
	<div class="sw">
		<swiper disable-touch class="swiper" :style="style" vertical :current="wrapIndex" @change="swperChange" duration="300" @touchstart="touchStart" @touchend="touchEnd">
			<swiper-item class="swiper-item" v-for="(item,index) in list">
				<gvideo :index="index" :src="item.src" :play="item.play" :times="item.times?item.times:0"
					:title="item.title" @pause="pause" />
			</swiper-item>
		</swiper>
	</div>
</template>

<script>
	import config from "../../../config";
	import gvideo from "./components/gvideo"
	export default {
		components: {
			gvideo
		},
		data() {
			return {
				style: "",
				//视频对象数组
				videoContext: [],
				//字符串名,用于拼接video ID
				myVideo: "myVideo",
				//视频下标
				current: 0,
				//视频数据,数据格式可以自己定义,一下仅供参考
				list: [{
				id:"xx",
				src:"xxxx",
				play:false,
				time:"xxx"
				}],
				params: {

				},
				count: 0,
				movesh: "",
				wrapIndex: 0,
				pageStartY:0,
				pageEndY:0
			}
		},
		created() {
		//获取视频数据 方法已省略,自己处理
			try {
				const res = uni.getSystemInfoSync();
				this.style = "height:" + res.windowHeight + "px;"
				// this.getList();
			} catch (e) {
				// error
			}
		},
		onBackPress() {
			if (this.count == 0) {
				this.list[this.current].play = false;
				uni.showToast({
					title: "再点一次返回",
					icon: "none"
				})
				this.count = 1;
				return true;
			}
		},
		methods: {
			swperChange(e) {
				this.wrapIndex = e.detail.current;
				this.show = false;
				this.list[this.current].play = false;
				this.params.VideoId = this.list[this.current].id
				this.list[e.detail.current].play = true;
				//重置下标
				this.current = e.detail.current;

			},
			//记录时间
			pause(e) {
				console.log(config.domain.newCnn);
				this.params.Duration = e + '';
				let that = this
				uni.request({
					url:"xxxxxxxxxx",
					method: "POST",
					data: that.params,
					success: res => {
						console.log(res)
						console.log(that.params);
					},
					fail: (r) => {
						console.log(r)
					}
				})
			},
			touchStart(res) {
				this.pageStartY = res.changedTouches[0].pageY;
				// console.log("touchStart:" + this.pageStartY);
			},
			touchEnd(res) {
				this.pageEndY = res.changedTouches[0].pageY;
				// console.log("touchEnd:" + this.pageEndY);
				let platform = uni.getSystemInfoSync().platform;
				if (platform == 'android') {
					if ((this.pageStartY - this.pageEndY) > 60) {
						// console.log("向上滑动:");
						if (this.wrapIndex < (this.list.length - 1)) {
							this.wrapIndex = this.wrapIndex + 1
						}
					} else if ((this.pageStartY - this.pageEndY) < -60) {
						// console.log("向下滑动:",this.wrapIndex);
						if (this.wrapIndex >= 1) {
							this.wrapIndex = this.wrapIndex - 1
						}
					}
				}
			}
		}
	}
</script>
<style lang="scss" scoped>
	.sw {
		color: #ffffff;

		.swiper {

			.swiper-item {
				// width: 750rpx;
				height: 100%;
				border-bottom: 1rpx solid #ffffff;
			}
		}
	}

	.touch {
		width: 750rpx;
		position: fixed;
		top: 0;
		left: 0;
		z-index: 999999;
		background-color: #333333;
		opacity: 0.5;

	}

	.image {
		width: 100rpx;
		height: 100rpx;
		position: fixed;
		bottom: 30rpx;
		right: 20rpx;
	}
</style>

好了,基本就是这些了,如果有什么问题可以私信一下.共同成长

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐