swiper-vertical-video.uvue 7.0 KB
Newer Older
DCloud_JSON's avatar
DCloud_JSON 已提交
1
<template>
2
	<view class="page">
3 4 5
    <view @click="back" class="nav-back">
    	<image class="back-img" src="/static/template/scroll-fold-nav/back.png" mode="widthFix"></image>
    </view>
6
    <swiper class="swiper" :current="current" :circular="index != 0" :vertical="true" @change="onSwiperChange" @transition="onTransition">
M
mehaotian 已提交
7
			<swiper-item class="swiper-item" v-for="(item,i) in visibleList" :key="i">
8
				<video ref="video" class="video-box" objectFit="cover" :id="item._id" @loadstart="onLoadstart(i)" :src="item.src" :poster="item.poster_src" :show-center-play-btn="false" :autoplay="false" :controls="false" :loop="true" @play="onPlay(i)" @pause="onPause(i)"></video>
9
				<view class="video-cover" @click="changeState(i)">
10
					<image v-if="state[i] === 'onPause'" class="play-btn" src="/static/template/swiper-vertical-video/play.png" mode="widthFix"></image>
M
mehaotian 已提交
11
				</view>
12
				<view class="video-info" v-if="0">
M
mehaotian 已提交
13 14 15 16
					<text class="video-info-text">容器:第 {{i}} 个</text>
					<text class="video-info-text">内容:{{item.content}}</text>
				</view>
			</swiper-item>
17
		</swiper>
DCloud_JSON's avatar
DCloud_JSON 已提交
18
    <view class="debug-info" v-if="0">
19
      <text class="status-text">debug-info 播放状态:</text>
20
      <text class="status-text" v-for="(value,index) in state">第{{index+1}}个:{{ value }}</text>
21
    </view>
M
mehaotian 已提交
22
	</view>
DCloud_JSON's avatar
DCloud_JSON 已提交
23
</template>
M
mehaotian 已提交
24 25
<script>
	import { VideoNode } from "uts.sdk.modules.DCloudUniVideo";
26
	type ListItem = { _id : string, content : string, src : string, poster_src : string }
M
mehaotian 已提交
27 28 29 30 31 32 33 34 35 36
	let page : number = 0;

	export default {
		components: {},
		data() {
			return {
				list: [] as ListItem[],
				visibleList: [] as ListItem[],// 提高性能 可见的只有3个
				current: 0 as number,
				index: 0,
37
				state: ["unPlay", "unPlay", "unPlay"] as string[]
M
mehaotian 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
			}
		},
		beforeCreate() {
			this.list = this.getData()
			this.visibleList = this.list.slice(0, 3)
		},
		watch: {
			current(current : number, oldCurrent : number) {
				let changeNumber = current - oldCurrent
				if (changeNumber == 1 || changeNumber == -2) {
					// console.error('向右');
					this.index++
				} else {
					// console.error('向左');
					this.index--
				}
				// //翻页(3项为一页)
				if (Math.abs(changeNumber) == 2) {
					// console.log('翻页');
					page = Math.floor(this.index / 3);
					// console.log(this.index);
					// console.log('page',page);
					// console.log('slice',3*page,3*page+3);
					if (this.list.length < 3 * page + 3) {
						let list : ListItem[] = this.getData()
DCloud_JSON's avatar
DCloud_JSON 已提交
63
						this.list.push(...list)
M
mehaotian 已提交
64 65 66 67 68 69 70 71
					}

					let visibleList = this.list.slice(3 * page, 3 * page + 3)
					// 换数据
					this.visibleList = visibleList
				}
			},
			current(current) {
72
				this.state.forEach((val : string, index : number) => {
M
mehaotian 已提交
73 74
					if (index === current) {
						this.doPlay(current)
75
					} else if (val === 'onPlay') {
M
mehaotian 已提交
76
						// 除了选中的其他已经播放的都需要停止
77 78
						this.doStop(index)
						console.log('index:' + index + '已被执行停止');
M
mehaotian 已提交
79 80 81 82 83 84 85 86
					}
				})
			}
		},
		onReady() {
			// 一启动完成,就播放第一个
			this.doPlay(0)
		},
87
		methods: {
M
mehaotian 已提交
88
			changeState(index : number) {
89
				if (this.state[index] === 'onPlay') {
M
mehaotian 已提交
90 91 92 93
					this.doPause(index)
				} else {
					this.doPlay(current)
				}
94 95 96 97
			},
      onLoadstart(index : number) {
        console.error("onLoadstart  video" + index );
      },
98
			doPlay(index : number) {
DCloud_JSON's avatar
DCloud_JSON 已提交
99 100
        // console.log("doPlay  video" + index,(this.$refs["video"] as VideoNode[])[0] );
				(this.$refs["video"] as VideoNode[])[index].play()
M
mehaotian 已提交
101
			},
102 103 104 105 106 107 108 109 110 111 112 113 114
			doStop(index : number) {
				(this.$refs["video"] as VideoNode[])[index].stop()
				console.log("doPause  video-" + index);
        
        // TODO 临时方案:解决.stop()时触发了doPause的问题
        setTimeout(()=>{
          this.state[index] = 'unPlay'
        },1000)
			},
      doPause(index : number) {
      	(this.$refs["video"] as VideoNode[])[index].pause()
      	console.log("doPause  video-" + index);
      },
M
mehaotian 已提交
115
			onPause(index : number) {
116
				this.state[index] = 'onPause'
M
mehaotian 已提交
117 118 119
				console.log('onPause', index);
			},
			onPlay(index : number) {
120
				this.state[index] = 'onPlay'
M
mehaotian 已提交
121 122 123 124
				console.log('onPlay', index);
			},
			getData() : ListItem[] {
				let videoUrlList = [
125 126 127
					'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uts.mp4',
					'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uni-ai.mp4',
					'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/video/swiper-vertical-video/uni-verify.mp4'
M
mehaotian 已提交
128 129 130
				] as string[]

				let posterSrcList = [
131 132 133
					'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-uts.jpg',
					'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-ai.jpg',
					'https://qiniu-web-assets.dcloud.net.cn/uni-app-x/static/images/swiper-vertical-video-poster/uni-verify.jpg'
M
mehaotian 已提交
134 135 136 137 138 139 140
				] as string[]

				let list = [] as ListItem[];
				for (let i = 0; i < 6; i++) {
					let index = this.list.length + i;
					let listItem : ListItem = {
						"_id": "a00" + index,
DCloud_JSON's avatar
DCloud_JSON 已提交
141
						"content": "这是第" + index + "条数据,url地址" + videoUrlList[i % 3],
M
mehaotian 已提交
142 143 144 145 146 147 148 149 150 151 152 153 154
						"src": videoUrlList[i % 3],
						"poster_src": posterSrcList[i % 3]
					}
					list.push(listItem)
				}
				return list
			},
			onSwiperChange(e : SwiperChangeEvent) {
				// console.error('SwiperChangeEvent',e.detail.current);
				this.current = e.detail.current;
			},
			onTransition(/*e : SwiperTransitionEvent*/) {
				// console.log('onTransition e.detail.dx', e.detail.dx);
155 156 157 158 159 160 161 162 163 164 165 166 167 168
			},
      back() {
      	uni.navigateBack({
      		success(result) {
      			console.log('navigateBack success', result.errMsg)
      		},
      		fail(error) {
      			console.log('navigateBack fail', error.errMsg)
      		},
      		complete(result) {
      			console.log('navigateBack complete', result.errMsg)
      		},
      	})
      }
M
mehaotian 已提交
169 170
		}
	}
DCloud_JSON's avatar
DCloud_JSON 已提交
171 172 173
</script>

<style>
M
mehaotian 已提交
174
	.page {
175 176 177 178
    width: 750rpx;
    flex: 1;
	}
  
M
mehaotian 已提交
179 180
	.swiper,
	.swiper-item,
181
	.video-box,
M
mehaotian 已提交
182
	.video-cover {
183 184 185
		width:750rpx;
    flex: 1;
    height: 100%;
M
mehaotian 已提交
186 187 188 189 190 191
	}

	.swiper-item {
		position: relative;
	}

192 193 194
	.video-box {
    width: 750rpx;
  }
M
mehaotian 已提交
195

196 197
	.video-cover {
    position: absolute;
M
mehaotian 已提交
198 199
		justify-content: center;
		align-items: center;
200 201 202 203
		align-content: center;
	}
  
  .play-btn {
204 205
  	width: 80rpx;
  	height: 80rpx;
206 207
  	color: #FFF;
  }
M
mehaotian 已提交
208 209

	.video-info {
210 211 212
    position: absolute;
    bottom: 0;
    padding: 15px;
M
mehaotian 已提交
213 214 215 216
	}

	.video-info-text {
		font-size: 14px;
217
		color: red;
M
mehaotian 已提交
218 219 220
		line-height: 20px;
	}

221 222 223 224
  .debug-info{
    position: fixed;
    top:15px;
    width: 750rpx;
DCloud_JSON's avatar
DCloud_JSON 已提交
225
    background-color: rgba(255, 255, 255, 0.3);
226 227 228 229 230
  }
  .status-text{
    color:red;
    padding: 15px;
  }
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
  
  .nav-back {
  	position: absolute;
  	top: 20px;
  	left: 8px;
    background-color: rgba(220, 220, 220, 0.8);
    border-radius: 100px;
    width: 24px;
    height: 24px;
    justify-content: center;
    align-items: center;
    z-index: 10;
  }
  
  .nav-back .back-img {
  	width: 14px;
    height: 14px;
  }
249
</style>