You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
326 lines
8.7 KiB
326 lines
8.7 KiB
<template>
|
|
<swiper class="m-tiktok-video-swiper" circular @change="swiperChange" :current="current" :vertical="true"
|
|
duration="300">
|
|
{{originList}}
|
|
<swiper-item v-for="(item, index) in displaySwiperList" :key="index">
|
|
|
|
<view class="swiper-item" @click="handleClick">
|
|
|
|
<ls-dom-video :ref="'DomVideo'+index" v-if="index === 0 || !isFirstLoad" :src="item.video"
|
|
:autoplay="true" :controls="false" @ended="endedVideo" @listener="listener"></ls-dom-video>
|
|
<!-- <video class="m-tiktok-video-player" :src="item.src" :id="`video__${index}`" :controls="controls"
|
|
:show-center-play-btn="controls" :object-fit="item.objectFit" :autoplay="false" :loop="loop"
|
|
:custom-cache="false" @ended="ended" @controlstoggle="controlstoggle" @play="onPlay"
|
|
@error="emits('error')" @loadedmetadata="loadVideoData($event, item)"
|
|
v-if="index === 0 || !isFirstLoad"></video> -->
|
|
<!-- <view class="m-tiktok-video-play-btn" v-if="!controls && displayIndex === index" @click="togglePlay">
|
|
<text class="m-tiktok-video-iconfont video-icon" :class="{ active: !isPlaying }"></text>
|
|
</view>
|
|
<image v-if="item.poster && displayIndex != index" :src="item.poster" class="m-tiktok-video-poster"
|
|
mode="aspectFit"></image>
|
|
<slot :item="item"></slot> -->
|
|
</view>
|
|
</swiper-item>
|
|
</swiper>
|
|
</template>
|
|
<script>
|
|
export default {
|
|
props: {
|
|
/**
|
|
* 视频列表
|
|
*/
|
|
videoList: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
/**
|
|
* 是否循环播放一个视频
|
|
*/
|
|
loop: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
/**
|
|
* 显示原生控制栏
|
|
*/
|
|
controls: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
/**
|
|
* 是否自动播放
|
|
*/
|
|
autoplay: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
/**
|
|
* 是否自动滚动播放
|
|
*/
|
|
autoChange: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
/**
|
|
* 滚动加载阈值(即播放到剩余多少个之后触发加载更多
|
|
*/
|
|
loadMoreOffsetCount: {
|
|
type: Number,
|
|
default: 2,
|
|
},
|
|
|
|
/**
|
|
* 视频自动自适应平铺模式
|
|
* 竖屏cover,横屏自适应
|
|
*/
|
|
autoObjectFit: {
|
|
type: Boolean,
|
|
default: true,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
originList: [], // 源数据
|
|
displaySwiperList: [], // swiper需要的数据
|
|
displayIndex: 0, // 用于显示swiper的真正的下标数值只有:0,1,2。
|
|
originIndex: 0, // 记录源数据的下标
|
|
current: 0,
|
|
oid: 0,
|
|
videoContexts: [],
|
|
isFirstLoad: true,
|
|
isPlaying: false,
|
|
|
|
loadTimer: null,
|
|
|
|
}
|
|
},
|
|
watch: {
|
|
videoList: {
|
|
handler(val) {
|
|
if (val.length) {
|
|
this.originList = val;
|
|
console.log(this.originList);
|
|
if (this.isFirstLoad || this.videoContexts.length) {
|
|
this.initSwiperData(this.originIndex)
|
|
this.initVideoContexts()
|
|
}
|
|
}
|
|
},
|
|
immediate: true,
|
|
deep: true
|
|
|
|
},
|
|
|
|
},
|
|
mounted() {
|
|
console.log(this.videoList);
|
|
},
|
|
methods: {
|
|
initVideoContexts() {
|
|
this.videoContexts = this.videoContexts.map((item, index) => {
|
|
return uni.createVideoContext(`video__${index}`, this);
|
|
})
|
|
},
|
|
onPlay(e) {
|
|
this.isPlaying = true;
|
|
this.initFirstLoad()
|
|
this.$emit('play', e)
|
|
|
|
},
|
|
handleClick(e) {
|
|
this.$emit("click", e);
|
|
},
|
|
ended() {
|
|
if (this.autoChange) {
|
|
if (this.displayIndex < 2) {
|
|
this.current = this.displayIndex + 1
|
|
} else {
|
|
this.current = 0
|
|
}
|
|
}
|
|
this.$emit('ended')
|
|
},
|
|
/**
|
|
* 初始一个显示的swiper数据
|
|
* @originIndex 从源数据的哪个开始显示默认0,如从其他页面跳转进来,要显示第n个,这个参数就是他的下标
|
|
*/
|
|
initSwiperData(originIndex) {
|
|
const originListLength = this.originList.length; // 源数据长度
|
|
const displayList = []; // 显示的swiper数据
|
|
displayList[this.displayIndex] = this.originList[originIndex];
|
|
displayList[this.displayIndex - 1 == -1 ? 2 : this.displayIndex - 1] =
|
|
this.originList[
|
|
originIndex - 1 == -1 ? originListLength - 1 : originIndex - 1
|
|
];
|
|
displayList[this.displayIndex + 1 == 3 ? 0 : this.displayIndex + 1] =
|
|
this.originList[originIndex + 1 == originListLength ? 0 : originIndex + 1];
|
|
this.displaySwiperList = displayList;
|
|
console.log('displaySwiperList', this.displaySwiperList);
|
|
if (this.oid >= this.originList.length) {
|
|
this.oid = 0;
|
|
}
|
|
if (this.oid < 0) {
|
|
this.oid = this.originList.length - 1;
|
|
}
|
|
|
|
//暂停所有视频
|
|
this.videoContexts.map((item) => item?.stop());
|
|
setTimeout(() => {
|
|
if (this.autoplay) {
|
|
uni.createVideoContext(`video__${this.displayIndex}`, this).play();
|
|
}
|
|
}, 500)
|
|
this.$emit('change', {
|
|
index: originIndex,
|
|
detail: this.originList[originIndex],
|
|
})
|
|
// 赋值
|
|
this.originIndex = originIndex;
|
|
// 加载更多
|
|
var pCount = this.originList.length - this.loadMoreOffsetCount;
|
|
if (originIndex == pCount) {
|
|
this.$emit('loadMore')
|
|
}
|
|
},
|
|
/**
|
|
* swiper滑动时候
|
|
*/
|
|
swiperChange(event) {
|
|
const { current } = event.detail;
|
|
this.isFirstLoad = false
|
|
const originListLength = this.originList.length
|
|
// 向后滚动
|
|
if (this.displayIndex - current == 2 || this.displayIndex - current == -1) {
|
|
this.originIndex =
|
|
this.originIndex + 1 == originListLength ? 0 : this.originIndex + 1;
|
|
this.displayIndex =
|
|
this.displayIndex + 1 == 3 ? 0 : this.displayIndex + 1;
|
|
this.oid = this.originIndex - 1;
|
|
this.initSwiperData(this.originIndex);
|
|
}
|
|
// 如果两者的差为-2或者1则是向前滑动
|
|
else if (
|
|
this.displayIndex - current == -2 ||
|
|
this.displayIndex - current == 1
|
|
) {
|
|
this.originIndex =
|
|
this.originIndex - 1 == -1 ?
|
|
originListLength - 1 :
|
|
this.originIndex - 1;
|
|
this.displayIndex =
|
|
this.displayIndex - 1 == -1 ? 2 : this.displayIndex - 1;
|
|
this.oid = this.originIndex + 1;
|
|
this.initSwiperData(this.originIndex);
|
|
}
|
|
},
|
|
controlstoggle(e) {
|
|
this.$emit('controlstoggle', e)
|
|
},
|
|
togglePlay() {
|
|
const video = uni.createVideoContext(`video__${this.displayIndex}`, this)
|
|
if (this.isPlay) {
|
|
video.pause()
|
|
this.isPlay = false
|
|
|
|
} else {
|
|
video.play()
|
|
this.isPlay = true
|
|
|
|
}
|
|
},
|
|
playSeeked(value) {
|
|
const video = uni.createVideoContext(`video__${this.displayIndex}`, this)
|
|
video.seek(value)
|
|
},
|
|
initFirstLoad() {
|
|
if (this.isFirstLoad) {
|
|
this.loadTimer = setTimeout(() => {
|
|
this.isFirstLoad = false
|
|
clearTimeout(this.loadTimer)
|
|
}, 5000)
|
|
}
|
|
},
|
|
/**
|
|
* 视频源数据加载时触发
|
|
* @param $event
|
|
* @param item
|
|
*/
|
|
loadVideoData($event, item) {
|
|
if (item.objectFit) {
|
|
return
|
|
}
|
|
if (!this.autoObjectFit) {
|
|
return
|
|
}
|
|
// 自动计算设置视频平铺模式
|
|
if ($event.detail.width < $event.detail.height) {
|
|
item.objectFit = 'cover'
|
|
} else {
|
|
item.objectFit = 'contain'
|
|
}
|
|
}
|
|
},
|
|
onUnload() {
|
|
clearTimeout(this.loadTimer)
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
// @font-face {
|
|
// font-family: "m-tiktok-play-icon";
|
|
// src: url(data:font/woff2;charset=utf-8;base64,d09GMgABAAAAAAJ0AA0AAAAABlgAAAIiAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0ZGVE0cGh4GYACCQhEICkhaCwoAATYCJAMQBCAFhQIHLxt4BcieBXbLR4jiyygbC491Mg0vz9JsPPz/ft/2ufeMmCQP9fXfRhxvMKHjkcSsTkqWplJJqpFFfn79mr4NG5fvwujI+EPeZCbudGJcy6oVklRVp8IAdgMJUqD853ceuhm3iSafWxNoC0bbskAmUGABTlrDAgwsC+xJ3/SJf3DecLgpCpyFgDcXlRJ8uiufSVcHBjENilBVIVGQKS50UZ6U1+ApeD7+6kcvRVcl2fZub1Q8/BfJG9VHbUp9J0UAYBWhomIRgUZWYFHOKkgp+FFsyVvmRkB0E4AooAg/DwF/49FSQIJeBMbBDIAEQIzfDW+OPVHX48vXUy26fUwfJnN0+tW5bLx3+dz5fHT61rQEIBDc77r579ZI8793IDWgftfb8/q83gC9Cggqvex6gvqcDoBMGojkOvpX4wgU9OtHC2DcOwgwoYpA6LWDQNHjDgJVr8cCpF7PBOgy4JUA3Xq9BYF+29EgMGAiLlSRfVgDlgyjlmQx7JSsRgVQYkeyy7RLstuoF7Lfid+qAWtxbiWmkbDEVgmyA2hRBHx6jOEomxtSuCEvAg5k/U4c0Bh2XJIYfiwLaz88BE9oYgkrKPS0dWGtk7/X7rqFOsU+TZzFM4k9Qx9jOkEXC3iErR+f0LhcASEUC9g0CtaGY3Jrsjf6zPrqiLsTyi1RpN9z3wPOMRaa6+jQAzbblCgVWLpySeZmOVzvLw8uOfSjoLSEEiV7Yg==) format("woff2");
|
|
// font-weight: normal;
|
|
// font-style: normal;
|
|
// font-display: swap;
|
|
// }
|
|
|
|
.m-tiktok-video-iconfont {
|
|
// font-family: m-tiktok-play-icon;
|
|
}
|
|
|
|
.m-tiktok-video-swiper,
|
|
.m-tiktok-video-player {
|
|
width: 100%;
|
|
height: 100vh;
|
|
background-color: #000;
|
|
}
|
|
|
|
.m-tiktok-video-swiper {
|
|
.swiper-item {
|
|
position: relative;
|
|
}
|
|
|
|
.m-tiktok-video-poster {
|
|
background-color: #000;
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
}
|
|
|
|
.m-tiktok-video-play-btn {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
z-index: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
|
|
.video-icon {
|
|
font-size: 50px;
|
|
display: block;
|
|
color: rgba(255, 255, 255, 0.8);
|
|
opacity: 0;
|
|
|
|
&.active {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|