uni-app 上下滑动播放视频
1、视频列表页
<template>
<view>
<view class="f_bottom_box" v-if="videoList.length">
<view class="bottom_box" v-for="(vo,index) in videoList" :key="index" @click="goXiangqing(vo.id)">
<image :src="vo.cover" mode="widthFix" class="bot_img" v-if="vo.cover" :lazy-load="true"></image>
<video @loadeddata="createPreImg($event)" :src="vo.video" mode="widthFix" class="bot_img"
v-else-if="vo.video"></video>
<image :src="vo.imageList[0].url" mode="widthFix" class="bot_img" v-else :lazy-load="true"></image>
<view class="bottom_img_text">
<view class="text">{{vo.title}}</view>
<view class="bottom_img" @click.stop>
<view class="f_img">
<image :src="vo.touxiang" mode="aspectFill" class="tx"></image>
<view class="">{{vo.name}}</view>
</view>
<u-icon name="heart-fill" color="rgba(216, 32, 70, 1)" size="18" class="love"
v-if="vo.isdianzan" @click="isLOve(vo.id,0,index)"></u-icon>
<u-icon name="heart" color="rgba(196, 196, 196, 1)" size="18" class="love" v-else
@click="isLOve(vo.id,1,index)"></u-icon>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import app from '../../App.vue';
export default {
data() {
return {
videoList: [],
}
},
onLoad() {
this.getVideoList()
},
methods: {
// 获取所有视频列表
getVideoList() {
let data = {
uid: app.globalData.uid
}
this.yrApi.request('Zuopin/getVideoList', 'POST', data).then(res => {
if (res.data.code == 0) {
this.videoList = res.data.data
}
})
},
// 跳转到刷视频界面
goXiangqing(id){
uni.navigateTo({
url:`/pages/demo/shipinxiashua?id=${id}&videoList=${JSON.stringify(this.videoList)}`
})
}
}
}
</script>
<style lang="scss">
.f_bottom_box {
// display: flex;
// align-items: center;
// // flex-wrap: wrap;
// overflow: hidden;
padding: 0 30rpx;
justify-content: space-between;
// flex-flow: column wrap;
// height: 100vh;
// display: grid;
// column-count: 2;//想要排成的列数
// column-gap: 10;
column-count: 2;
column-gap: 10px;
margin: 0 auto;
.bottom_box {
// display: inline-block;
// width: 48%;
// margin-left: 4%;
// vertical-align: top;
border-radius: 10rpx;
background-color: #fff;
box-sizing: border-box;
-webkit-column-break-inside: avoid;
break-inside: avoid;
// text-align: center;
margin-bottom: 20rpx;
// &:nth-child(2n-1){
// margin-left: 0;
// }
.bot_img {
width: 100%;
// height: 439rpx;
border-radius: 10rpx 10rpx 0 0;
}
.bottom_img_text {
box-sizing: border-box;
padding: 14rpx 13rpx 20rpx 13rpx;
.text {
font-size: 30rpx;
font-weight: 500;
color: #434342;
margin-bottom: 10rpx;
}
.bottom_img {
display: flex;
justify-content: space-between;
align-items: center;
.f_img {
display: flex;
align-items: center;
.tx {
width: 39rpx;
height: 39rpx;
border-radius: 50%;
margin-right: 10rpx;
}
view {
font-size: 22rpx;
font-weight: 400;
color: #999999;
line-height: 30rpx;
}
}
.love {
width: 30rpx;
height: 30rpx;
}
}
}
}
}
</style>
2、视频详情页
<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" :key="index">
<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"
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){
let data = {
id
}
this.yrApi.request('Zuopin/getVideoById', 'POST', data).then(res=>{
if(res.data.code==0){
this.videoData = res.data.data;
this.id = res.data.data.id
uni.setNavigationBarTitle({
title:this.videoData.title
})
this.description = this.videoData.desc
this.PayVideo = this.videoList //上下滑动总数据
this.current = this.PayVideo.findIndex((item) => {
return item.id === res.data.data.id
})
this.duration = res.data.data.videoTime
// 自动播放当前视频
this.$nextTick(function() {
let videoContext = uni.createVideoContext('id' + this.current)
console.log("index----",videoContext)
setTimeout(() => {
videoContext.play()
}, 500)
})
}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].title
})
if(this.PayVideo[current].desc) {
this.description = this.PayVideo[current].desc
}
this.duration = this.PayVideo[current].videoTime
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="scss">
.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>