swiper-vertical-video.uvue 7.7 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">
DCloud_JSON's avatar
DCloud_JSON 已提交
7 8 9 10 11 12
			<swiper-item class="swiper-item" v-for="(item,i) in visibleList" :key="i">
				<video @click="changeState(i)" ref="video" class="video-box" objectFit="cover" :id="'video-'+i"
          @loadstart="onLoadstart(i)" :src="item.src" :poster="item.poster_src"
          :autoplay="false" :show-center-play-btn="false"
          :loop="true" @play="onPlay(i)" @pause="onPause(i)"
        ></video>
13
				<view class="video-cover" @click="changeState(i)">
14
					<image v-if="state[i] === 'pause'" class="play-btn" src="/static/template/swiper-vertical-video/play.png" mode="widthFix"></image>
M
mehaotian 已提交
15
				</view>
16
				<view class="video-info" v-if="0">
M
mehaotian 已提交
17 18 19
					<text class="video-info-text">容器:第 {{i}} 个</text>
					<text class="video-info-text">内容:{{item.content}}</text>
				</view>
20
			</swiper-item>
21
		</swiper>
DCloud_JSON's avatar
DCloud_JSON 已提交
22
    <view class="debug-info" v-if="0">
23
      <text class="status-text">debug-info 播放状态:</text>
24
      <text class="status-text" v-for="(value,index) in state">第{{index+1}}个:{{ value }}</text>
25
    </view>
M
mehaotian 已提交
26
	</view>
DCloud_JSON's avatar
DCloud_JSON 已提交
27
</template>
M
mehaotian 已提交
28
<script>
29
	type ListItem = { _id : string, content : string, src : string, poster_src : string }
30 31
	let page : number = 0,
  currentPageIsShow : boolean = true;
M
mehaotian 已提交
32 33 34 35

	export default {
		components: {},
		data() {
36 37
			return {
        $videoContextMap:new Map<string, VideoContext>(),
M
mehaotian 已提交
38 39 40 41
				list: [] as ListItem[],
				visibleList: [] as ListItem[],// 提高性能 可见的只有3个
				current: 0 as number,
				index: 0,
42
				state: ["unPlay", "unPlay", "unPlay"] as string[]
M
mehaotian 已提交
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
			}
		},
		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 已提交
68
						this.list.push(...list)
M
mehaotian 已提交
69 70 71 72 73 74 75 76
					}

					let visibleList = this.list.slice(3 * page, 3 * page + 3)
					// 换数据
					this.visibleList = visibleList
				}
			},
			current(current) {
77
				this.state.forEach((val : string, index : number) => {
M
mehaotian 已提交
78 79
					if (index === current) {
						this.doPlay(current)
80
					} else {
M
mehaotian 已提交
81
						// 除了选中的其他已经播放的都需要停止
82 83
						this.doStop(index)
						console.log('index:' + index + '已被执行停止');
M
mehaotian 已提交
84 85 86 87 88 89
					}
				})
			}
		},
		onReady() {
			// 一启动完成,就播放第一个
90 91 92 93 94 95 96 97 98 99 100 101 102
			this.doPlay(0)
		},
    onShow(){
      currentPageIsShow = true
    },
    onHide() {
      currentPageIsShow = false
      console.log('pages-onHide');
      this.doPause(this.current)
    },
    onUnload() {
      this.doPause(this.current)
    },
103
		methods: {
M
mehaotian 已提交
104
			changeState(index : number) {
105
				if (this.state[index] === 'play') {
M
mehaotian 已提交
106 107 108 109
					this.doPause(index)
				} else {
					this.doPlay(current)
				}
110 111 112
			},
      onLoadstart(index : number) {
        console.error("onLoadstart  video" + index );
113 114 115 116 117 118 119 120
      },
      getVideoContext(index : number) : VideoContext{
        let videoContext : VideoContext | null = this.$videoContextMap.get('video-'+index)
        if(videoContext == null){
          videoContext = uni.createVideoContext('video-'+index, this) as VideoContext
          this.$videoContextMap.set('video-'+index,videoContext)
        }
        return videoContext
121
      },
122
			doPlay(index : number) {
123 124
        console.log("doPlay  video" + index );
				this.getVideoContext(index).play()
M
mehaotian 已提交
125
			},
126
			doStop(index : number) {
127
				console.log("doStop  video-" + index);
DCloud_JSON's avatar
DCloud_JSON 已提交
128 129
        this.getVideoContext(index).stop();
        // TODO 临时方案:解决.stop()时触发了doPause的问题
130 131 132 133 134
        setTimeout(()=>{
          this.state[index] = 'unPlay'
        },1000)
			},
      doPause(index : number) {
135
      	this.getVideoContext(index).pause()
136 137
      	console.log("doPause  video-" + index);
      },
M
mehaotian 已提交
138
			onPause(index : number) {
139
				this.state[index] = 'pause'
M
mehaotian 已提交
140 141
				console.log('onPause', index);
			},
142 143 144 145 146 147 148
			onPlay(index : number) {
        if(this.current != index || !currentPageIsShow){
          this.onPause(index)
        }else{
          this.state[index] = 'play'
          console.log('onPlay', index);
        }
M
mehaotian 已提交
149 150 151
			},
			getData() : ListItem[] {
				let videoUrlList = [
152 153 154
					'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 已提交
155 156 157
				] as string[]

				let posterSrcList = [
158 159 160
					'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 已提交
161 162 163 164 165 166 167
				] 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 已提交
168
						"content": "这是第" + index + "条数据,url地址" + videoUrlList[i % 3],
M
mehaotian 已提交
169 170 171 172 173 174 175 176 177 178 179 180 181
						"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);
182 183 184 185 186 187 188 189 190 191 192
			},
      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)
193
      		}
194 195
      	})
      }
M
mehaotian 已提交
196 197
		}
	}
DCloud_JSON's avatar
DCloud_JSON 已提交
198 199 200
</script>

<style>
M
mehaotian 已提交
201
	.page {
202 203 204
    width: 750rpx;
    flex: 1;
	}
DCloud_JSON's avatar
DCloud_JSON 已提交
205

M
mehaotian 已提交
206 207
	.swiper,
	.swiper-item,
208
	.video-box,
M
mehaotian 已提交
209
	.video-cover {
210 211 212
		width:750rpx;
    flex: 1;
    height: 100%;
M
mehaotian 已提交
213 214 215 216 217 218
	}

	.swiper-item {
		position: relative;
	}

219 220 221
	.video-box {
    width: 750rpx;
  }
M
mehaotian 已提交
222

223 224
	.video-cover {
    position: absolute;
M
mehaotian 已提交
225 226
		justify-content: center;
		align-items: center;
227 228
		align-content: center;
	}
DCloud_JSON's avatar
DCloud_JSON 已提交
229

230
  .play-btn {
231 232
  	width: 80rpx;
  	height: 80rpx;
233
  }
M
mehaotian 已提交
234 235

	.video-info {
236 237 238
    position: absolute;
    bottom: 0;
    padding: 15px;
M
mehaotian 已提交
239 240 241 242
	}

	.video-info-text {
		font-size: 14px;
243
		color: red;
M
mehaotian 已提交
244 245 246
		line-height: 20px;
	}

247 248 249 250
  .debug-info{
    position: fixed;
    top:15px;
    width: 750rpx;
DCloud_JSON's avatar
DCloud_JSON 已提交
251
    background-color: rgba(255, 255, 255, 0.3);
252 253 254 255 256
  }
  .status-text{
    color:red;
    padding: 15px;
  }
DCloud_JSON's avatar
DCloud_JSON 已提交
257

258 259 260 261 262 263
  .nav-back {
  	position: absolute;
  	top: 20px;
  	left: 8px;
    background-color: rgba(220, 220, 220, 0.8);
    border-radius: 100px;
DCloud_JSON's avatar
DCloud_JSON 已提交
264 265
    width: 28px;
    height: 28px;
266 267 268 269
    justify-content: center;
    align-items: center;
    z-index: 10;
  }
DCloud_JSON's avatar
DCloud_JSON 已提交
270

271
  .nav-back .back-img {
DCloud_JSON's avatar
DCloud_JSON 已提交
272 273
  	width: 18px;
    height: 18px;
274
  }
DCloud_JSON's avatar
DCloud_JSON 已提交
275
</style>