tren de pensamiento
Utiliza principalmente swiper
los componentes del sitio web oficial de Uniapp y luego anida un video
componente. El siguiente es mi efecto de implementación:
pregunta
Cuando uso la autoplay
propiedad oficial para implementar la reproducción automática, hará que la reproducción de sonido permanezca en el video anterior cuando cambie al siguiente video, o el sonido de varios videos se reproducirá al mismo tiempo.
lograr
id
Al principio, obtuvimos los datos swiper
de todos los videos. De acuerdo con current
el subíndice actual en el objeto de video en el que se hizo clic , ubicamos correctamente el video en el que se hizo clic actualmente y luego controlamos la reproducción automática del video
注意
. Este lugar no se cierra manualmente. por lo que definitivamente conducirá al problema que mencioné anteriormente de que la imagen cambia pero el sonido aún permanece en el video anterior. Estos son los dos swiper
eventos más importantes.
Aquí está el valor propósito anterior para el monitoreo dinámico.('id' + this.current)
correspondiente al a todos los códigos y formatos de datos (estos son los cuatro valores útiles):id="'id'+index"
id
this.current
current
todos los códigos
<template>
<view>
<view class="uni-padding-wrap">
<view class="page-section swiper">
<view class="page-section-spacing">
<swiper class="swiper" @change="changefun" @animationfinish="animationfinishfun" :current="current" :circular="false" :vertical="true">
<block v-if="PayVideo">
<swiper-item v-for="(item,index) in PayVideo">
<view class="swiper-item uni-bg-black">
<video
:custom-cache="false"
:show-fullscreen-btn="false"
:controls="true"
:show-center-play-btn="false"
enable-play-gesture
:initial-time="0"
class="video"
:id="'id'+index"
:src="item.video_url"
loop
:enable-progress-gesture="false"
v-if="index == current"
>
</video>
</view>
</swiper-item>
</block>
</swiper>
</view>
</view>
</view>
<view>
<view class="left">
<cover-view class="left_box">
<cover-view class="ke_context height">{
{
description}}</cover-view>
<!-- <cover-view class="auto">
<cover-view>视频总时长:{
{
duration || 0}}</cover-view>
</cover-view> -->
</cover-view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
PayVideo: [],
videoData: {
},
videoList: [],
description: '',
current: 0,
index_: 0,
videoContext: '',
duration: '',//总视频时长
}
},
computed: {
},
onLoad(options) {
this.getVideoInfo(parseInt(options.id))
if(options.videoList) {
this.videoList = JSON.parse(decodeURIComponent(options.videoList))
}
},
methods: {
getVideoInfo(id){
this.$http.get('/video/detail',{
video_id:id
}).then(res=>{
if(res.code==0){
this.videoData = res.data;
this.id = res.data.id
uni.setNavigationBarTitle({
title:this.videoData.video_name
})
this.description = this.videoData.description
this.PayVideo = this.videoList //上下滑动总数据
this.current = this.PayVideo.findIndex((item) => {
return item.id === res.data.id
})
this.duration = res.data.video_time
// 自动播放当前视频
this.$nextTick(function() {
let videoContext = uni.createVideoContext('id' + this.current)
videoContext.play()
})
}else{
uni.showToast({
title:res.msg,
icon:'none'
})
setTimeout(()=>{
uni.redirectTo({
url:'/pages/index/index?index=2'
})
},1500)
}
})
},
// current改变时会触发change 事件
changefun(e) {
let current = e.detail.current
uni.setNavigationBarTitle({
title: this.PayVideo[current].video_name
})
if(this.PayVideo[current].description) {
this.description = this.PayVideo[current].description
}
this.duration = this.PayVideo[current].video_time
let videoContext = uni.createVideoContext('id' + this.current)
videoContext.pause() //停止播放
},
// 动画结束时触发
animationfinishfun(e) {
let current = e.detail.current
let videoContext = uni.createVideoContext('id' + this.current)
videoContext.pause() //停止播放非当前视频
videoContext = uni.createVideoContext('id' + current)
videoContext.play() //开始播放当前视频
this.current = current //保存当前下标 播放下一个视频时停止上一个视频 防止声音重复
}
},
}
</script>
<style scoped lang="less">
.circle {
background: rgba(34, 34, 34, 0.4);
border-radius: 50%;
z-index: 2;
height: 70px;
width: 70px;
position: fixed;
top: 0;
bottom: 441rpx;
left: 31rpx;
margin: auto;
.red {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
z-index: 3;
height: 35px;
width: 35px;
}
}
.swiper {
height: 100vh;
.swiper-item {
height: 100vh;
position: relative;
}
.uni-bg-black {
background: black;
}
}
.video {
width: 100%;
height: 98vh;
position: relative;
}
.left_box {
position: fixed;
bottom: 90rpx;
left: 24rpx;
.ke_context {
overflow-y: scroll;
max-height: 300rpx;
white-space:pre-wrap;
width: 700rpx;
font-size: 30rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(255, 255, 255, 1);
white-space:pre-wrap;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.4);
}
.height {
margin-bottom: 40rpx;
}
.ren {
margin: 20rpx 0;
font-size: 36rpx;
font-family: PingFang SC;
font-weight: bold;
color: rgba(255, 255, 255, 1);
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.4);
}
.auto {
display: flex;
align-items: center;
width: 310rpx;
height: 60rpx;
margin-top: 24rpx;
opacity: 1;
border-radius: 8rpx;
padding-left: 10rpx;
cover-view {
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(255, 255, 255, 1);
line-height: 90px;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.4);
}
cover-image {
margin-right: 10rpx;
height: 28rpx;
width: 26rpx;
}
}
.ke {
display: flex;
align-items: center;
width: 310rpx;
height: 60rpx;
background: rgba(0, 0, 0, 0.3);
opacity: 1;
border-radius: 8rpx;
padding-left: 10rpx;
cover-view {
font-size: 26rpx;
font-family: PingFang SC;
font-weight: 500;
color: rgba(255, 255, 255, 1);
line-height: 90px;
text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.4);
}
cover-image {
margin-right: 10rpx;
height: 40rpx;
width: 40rpx;
}
}
}
.H_T {
z-index: 2;
width: 100%;
display: flex;
box-sizing: border-box;
position: absolute;
padding: 0 30rpx;
background: transparent;
justify-content: space-between;
.back {
height: 48rpx;
width: 48rpx;
}
.search {
height: 48rpx;
width: 48rpx;
}
}
.right_box {
width: 100rpx;
position: absolute;
z-index: 2;
bottom: 60rpx;
right: 12rpx;
display: flex;
flex-direction: column;
.top1 {
position: relative;
height: 124rpx;
.avatar_img {
width: 98rpx;
height: 98rpx;
border-radius: 50%;
}
.add_img {
position: absolute;
z-index: 99;
width: 48rpx;
height: 48rpx;
bottom: 10rpx;
left: 0;
right: 0;
margin: 0 auto;
}
}
.top2 {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 37rpx;
.t_img {
height: 72rpx;
width: 72rpx;
margin-bottom: 10rpx;
}
.font_t {
font-size: 26rpx;
font-family: SF Pro Text;
font-weight: 500;
color: rgba(255, 255, 255, 1);
text-shadow: 0px 1rpx 1rpx rgba(0, 0, 0, 0.4);
text-align: center;
}
}
}
</style>