swiper-vertical-video.uvue 7.6 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
					}

					let visibleList = this.list.slice(3 * page, 3 * page + 3)
					// 换数据
					this.visibleList = visibleList
DCloud_JSON's avatar
DCloud_JSON 已提交
74 75
				}

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

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

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

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

	.swiper-item {
		position: relative;
	}

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

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

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

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

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

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

257 258 259 260 261 262
  .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 已提交
263 264
    width: 28px;
    height: 28px;
265 266 267 268
    justify-content: center;
    align-items: center;
    z-index: 10;
  }
DCloud_JSON's avatar
DCloud_JSON 已提交
269

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