使用uniapp开发多端短视频(用swiper+video去实现)
1.首先我们封装video播放器注意:video的层级进行修改在H5中要加入x5-video-player-type="h5-page"属性进行内核处理(目前仅在微信浏览器中处理过),微信小程序IOS的版的可以动态获取video的id进行createVideoContext操作,然而安卓机中并不行,安卓机仅支持一个video的ID去操作createVideoContext<template&
·
1.首先我们封装video播放器
注意:video的层级进行修改在H5中要加入x5-video-player-type="h5-page"属性进行内核处理(目前仅在微信浏览器中处理过),微信小程序IOS的版的可以动态获取video的id进行createVideoContext操作,然而安卓机中并不行,安卓机仅支持一个video的ID去操作createVideoContext
<template>
<view style="height: 100%;" class="video-fix-box">
<view style="height: 100%;" v-if="videoUrlStr != ''">
<!-- #ifdef MP-WEIXIN -->
<video v-if="phoneType" class="video" id="videoWatch" :src="videoUrl" :controls="controlsType" :loop="true" :show-center-play-btn="false" :show-play-btn="false" @timeupdate="onUpdata" :enable-progress-gesture="false" :enable-play-gesture="false" :muted="mutedType" objectFit="contain" :poster="thumbnailUrl" @loadedmetadata="loadeFn" @error="videoError" :custom-cache="false" ></video>
<video v-else class="video" :id="`video${videoId}`" :src="videoUrl" :controls="controlsType" :loop="true" :show-center-play-btn="false" :show-play-btn="false" @timeupdate="onUpdata" :enable-progress-gesture="false" :enable-play-gesture="false" :muted="mutedType" objectFit="contain" :poster="thumbnailUrl" @loadedmetadata="loadeFn" @error="videoError" :custom-cache="false" ></video>
<!-- #endif -->
<!-- #ifdef H5 -->
<!-- cover -->
<video class="video" :id="`video${videoId}`" :src="videoUrl" :controls="controlsType" :loop="true" :show-center-play-btn="false" :show-play-btn="false" @timeupdate="onUpdata" :enable-progress-gesture="false" :enable-play-gesture="false" :muted="mutedType" :objectFit="videoProportion > 1 ? 'contain' : 'cover'" :poster="thumbnailUrl" @error="videoError" x5-video-player-type="h5-page" @loadedmetadata="loadeFn" :webkit-playsinline="true" preload="auto"></video>
<!-- #endif -->
</view>
<view class="tiem-line" :style="{width:newWidthLin}"></view>
</view>
</template>
<script>
export default {
props:{
userId:{ // 用户id
type:Number,
default:0
},
userName:{ // 用户名称
type:String,
default:'xxxx'
},
userUrl:{ // 用户头像路径
type:String,
default:'xxxx'
},
title:{ // 视频标题
type:String,
default:'xxxx'
},
videoUrl:{ // 视频路径
type:String,
default:''
},
thumbnailUrl:{ // 视频封面路径
type:String,
default:'xxxx'
},
videoId:{ // 视频id
type:Number,
default:0
},
distAnce:{ // 距离
type:Number,
default:0
},
loveNum:{ // 点赞数量
type:Number,
default:0
},
shareNum:{ // 转发数量
type:Number,
default:0
},
commentNum:{ // 评论数量
type:Number,
default:0
},
playType:{ // 控制播放状态
type:Boolean,
default:false
},
videoShow:{ // 监听时候跳转页面了
type:Boolean,
default:false
},
homeInx:{ // 监听home的轮播图是否切换
type:Number,
default:0
},
controlsType:{ // 是否暂时原生控制条
type:Boolean,
default:false
},
videoInx:{ // 视频列表索引
type:Number
},
presentInx:{ // spewr目前索引
type:Number
},
phoneType:{ // 判断小程序手机类型是否为安卓手机
type:Boolean
},
mutedType:{ // 控制音量的
type:Boolean
}
},
data() {
return {
baseImgUrl:'基准路径',
time:0,
duration:0,
PlatFormType:false,
videoWidth:0,
videoHeight:0
}
},
computed:{
newWidthLin(){
let newWidth = (this.time / this.duration).toFixed(2) * 100
return `${newWidth}%`
},
videoUrlStr(){
return this.videoUrl
},
videoProportion(){
let newTion = this.videoWidth / this.videoHeight
return newTion
}
},
methods: {
onUpdata(e){ // 计算播放进度条
this.time = e.detail.currentTime
this.duration = e.detail.duration
},
videoError(e){
},
loadeFn(e){ // 真机才会显示出来 --- 后面需要处理
// uni.showToast({
// title: '高度' + e.detail.height + ',宽度:' + e.detail.width,
// duration: 3000
// });
this.videoWidth = e.detail.width
this.videoHeight = e.detail.height
}
},
mounted() {
// #ifdef H5
this.videoContext = uni.createVideoContext(`video${this.videoId}`,this)
// #endif
// #ifdef MP-WEIXIN
if(this.phoneType){
this.videoContext = uni.createVideoContext('videoWatch',this)
}else{
this.videoContext = uni.createVideoContext(`video${this.videoId}`,this)
}
// #endif
},
watch:{
videoId:{
immediate: true,
handler(newVal,oldVal){
if(this.playType && this.phoneType){
this.videoContext = uni.createVideoContext('videoWatch',this)
}
}
},
videoShow(newval,oldval){
if(this.homeInx === 0){ // 判断是不是在看视频的时候跳转的---这里可能到时还需要做其他处理
if(newval){
if(this.videoInx === this.presentInx){
this.videoContext.play()
this.$emit('play',true)
}
}else{
if(this.videoContext != undefined){
this.videoContext.pause()
}
this.$emit('pause',false)
}
}
},
playType:{
immediate: true,
handler(newVal,oldVal){
if(newVal){
this.videoContext.play()
}else{
if(this.videoContext != undefined){
this.videoContext.pause()
}
}
}
},
homeInx(newval,oldval){
if(newval === 1){
if(this.playType){
this.$emit('tabPause',false)
}
}else{
if(!this.playType){
this.$emit('tabPlay',false)
}
}
}
}
}
</script>
<style lang="scss">
.video{
height: 100%;
}
.video-fix-box{
position: relative;
.video{
z-index: -1;
width: 100%;
}
.tiem-line{
position: absolute;
z-index: 888;
bottom: 0;
left: 0;
height: 4rpx;
background-color: #fff;
}
}
</style>
2.使用封装好的video播放器
<swiper :vertical="true" :current="currentInx" @change="swiPerFn" style="height: 100%;">
<swiper-item v-for="(item, inx) in videoList" :key="inx" :duration="200">
<!-- #ifdef H5 -->
// 去绝对值==1的,当前视频上下的视频都会显示
<view v-if="Math.abs(inx - currentInx) <= 1" style="height: 100%;">
<public-video :src="视频路径" ...></public-video>
<view v-else></view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN-->
// PlatFormType用来判断进行机型,app入口文件可以获取存入本地等其他
// 微信小程序中ios系统
<view v-if="!PlatFormType">
// 去绝对值==1的,当前视频上下的视频都会显示(取多后性能会很卡)
<view v-if="Math.abs(inx - currentInx) <= 1" style="height: 100%;">
<public-video :src="视频路径" ...></public-video>
</view>
<view v-else></view>
</view>
// 微信小程序中安卓系统
<view v-else>
// 只显示当前索引的视频,当前视频上下的用封面图或者骨架图(避免部分安卓机再看视频的时候跳去其他页面不能调用video中的pause暂停视频)
<view v-if="inx === currentInx" style="height: 100%;">
<public-video :src="视频路径" ...></public-video>
</view>
<view v-else-if="Math.abs(inx - currentInx) === 1" style="height: 100%;">
<image src="骨架图路径" mode="" class="video-img"></image>
</view>
<view v-else></view>
</view>
<!-- #endif -->
</swiper-item>
<swiper
更多推荐
已为社区贡献6条内容
所有评论(0)