358 lines
13 KiB
Plaintext
358 lines
13 KiB
Plaintext
<template>
|
||
<view class="container">
|
||
<view :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;z-inde:-1;'">
|
||
<!--
|
||
1.这里的 swiper 不是用来控制视频滑动的,而是用来控制左右滑动的,如果不需要的可以改成 view
|
||
2.为了 视频无限加载,已经把 21 行的 appear 去掉了,加上了 loadmore 方法(第10行)
|
||
3.由于方法比较多,可以采取下面的方式查看代码:
|
||
(1)Mac:按住 option 键,然后点击方法名,即可跳转到方法
|
||
(2)windows:按住 Alt 键,然后鼠标左击,即可跳转到方法
|
||
-->
|
||
<list @loadmore="getData" @scroll="scrolls" :loadmoreoffset="wHeight*1" :show-scrollbar="false"
|
||
ref="listBox" :pagingEnabled="true" :scrollable="true">
|
||
<!-- 循环数据 -->
|
||
<cell v-for="(item,i) in dataList" :key="i">
|
||
<!-- 用div把视频模组套起来 -->
|
||
<div :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;'">
|
||
<!-- <view v-if="Math.abs(k-i)<=1"> -->
|
||
<view v-if="Math.abs(k-i)<=1">
|
||
<view class="root">
|
||
<video :ref="'item'+i" :id="item.id" :loop="true" :autoplay="i == k"
|
||
:src="item.pull_url" :muted="item.isplay" :enable-progress-gesture="false"
|
||
:page-gesture="false" :controls="false" :show-loading="true" :is-live='true'
|
||
@error='vedioerr' :show-fullscreen-btn="false" :show-center-play-btn="false"
|
||
:style="boxStyle" :object-fit="object_fit" @timeupdate="timeupdate($event,i)">
|
||
|
||
</video>
|
||
<!-- {{item}} {{i}} -->
|
||
|
||
</view>
|
||
<sd-float-page :room='room' :msgList='msgList'
|
||
:style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;position: absolute;' "></sd-float-page>
|
||
</view>
|
||
|
||
</div>
|
||
</cell>
|
||
</list>
|
||
</view>
|
||
|
||
|
||
</view>
|
||
</template>
|
||
<script>
|
||
import list from '@/uni_modules/uview-ui/libs/config/props/list';
|
||
import sdFloatPage from '@/components/sd-live-page/livepage.nvue';
|
||
import {
|
||
VUE_APP_WS_URL
|
||
} from '@/config/app';
|
||
|
||
import json from '../../static/js/json';
|
||
export default {
|
||
components: {
|
||
sdFloatPage
|
||
},
|
||
data() {
|
||
return {
|
||
imgHost: '',
|
||
//下面打🌟号的是必须要的基础字段
|
||
//下面打💗号的是拥有滑动条的必须字段
|
||
dataList: [], //用于数据循环的列表🌟💗
|
||
wHeight: 0, //获取的屏幕高度🌟💗
|
||
boxStyle: { //视频,图片封面样式🌟💗
|
||
'height': 0,
|
||
'width': 0,
|
||
},
|
||
k: 0, //默认为0🌟💗
|
||
max: 2,
|
||
playIngIds: [], //正在播放的视频id列队,列队用于处理滑动过快导致的跳频问题🌟💗
|
||
ready: false, //可忽略
|
||
isDragging: false, //false代表停止滑动🌟💗
|
||
refreshing: true, //用于下拉刷新🌟💗
|
||
windowWidth: 0, //获取屏幕宽度🌟💗
|
||
windowHeight: 0,
|
||
dex: [0, 0], //用于判断是上滑还是下滑,第一个存旧值,第二个存新值【目前在1.0.7已经废弃】
|
||
currents: 0, //用于左右滑动,0代表视频界面,1代表右滑界面🌟💗
|
||
platform: '', //用于获取操作系统:ios、android🌟💗
|
||
playIng: false, //用于视频初始化时是否播放,默认不播放🌟💗
|
||
videoTime: '', //视频总时长,这个主要用来截取时间数值💗
|
||
videoTimes: '', //视频时长,用这个来获取时间值,例如:00:30这个时间值💗
|
||
changeTime: '', //显示滑动进度条时变化的时间💗
|
||
isShowimage: false, //是否显示封面【1.0.4已废弃,但是意思需要记住】
|
||
currenttimes: 0, //当前时间💗
|
||
isShowProgressBarTime: false, //是否拖动进度条,如果拖动(true)则显示进度条时间,否则不显示(false)【1.0.4已废弃,但是意思需要记住】
|
||
ProgressBarOpacity: 0.7, //进度条不拖动时的默认值,就是透明的💗
|
||
dotWidth: 0, //播放的小圆点,默认没有💗
|
||
deleteHeight: 0, //测试高度🌟💗
|
||
percent: 0, //百分小数💗
|
||
currentPosition: 0, //滑块当前位置💗//2.0已弃用,现已用于后端参数
|
||
currentPositions: 0, //滑块当前位置的副本💗//2.0已弃用,现已用于后端参数
|
||
newTime: 0, //跟手滑动后的最新时间💗
|
||
timeNumber: 0, //🌟💗
|
||
ProgressBarBottom: 20, //进度条离底部的距离💗
|
||
object_fit: 'cover', //视频样式默认包含🌟💗
|
||
mode: 'aspectFit', //图片封面样式🌟💗
|
||
timeout: "", //🌟用来阻止 setTimeout()方法
|
||
voice: "", //🌟用来阻止 setTimeout()方法
|
||
oldVideo: "",
|
||
isAutoplay: false, //是否开启自动播放(默认不开启)
|
||
autoplayText: "开启自动播放",
|
||
msgList: [],
|
||
room: {},
|
||
socketTask: null,
|
||
userName: '',
|
||
|
||
|
||
}
|
||
},
|
||
|
||
watch: {
|
||
async k(new_k, old_k) { //监听 k 值的变化,可以控制视频的播放与暂停
|
||
const max = new_k + 2;
|
||
if (this.max < max) {
|
||
this.max = max;
|
||
}
|
||
// if (this.oldCurrent != this.currentNav) {
|
||
// this.oldCurrent = this.currentNav
|
||
// return false
|
||
// }
|
||
this.dataList[old_k].playIng = false //如果视频暂停,就加载封面
|
||
this.dataList[old_k].isplay = true
|
||
this.dataList[old_k].state = 'pause'
|
||
// console.log('预留第' + (old_k) + '个视频:' + this.dataList[old_k].community_id)
|
||
// 2.0版本已经去掉了下面这一句,视频不用暂停,只需要把声音禁止就行
|
||
uni.createVideoContext(this.dataList[old_k].community_id, this)
|
||
.pause() //如果视频暂停,那么旧视频停止,这里的this.dataList[old_k].id + '' + old_k,后面加 old_k 是为了每一个视频的 id 值不同,这样就可以大程度的避免串音问题
|
||
// console.log('已经暂停 --> 第' + (old_k) + '个视频~') //提示
|
||
this.dataList[new_k].state = 'play'
|
||
this.dataList[new_k].isplay = false
|
||
this.dataList[new_k].playIng = true
|
||
uni.createVideoContext(this.dataList[new_k].community_id, this).play()
|
||
}
|
||
},
|
||
onShow() {
|
||
uni.hideLoading();
|
||
// console.log('回到前台' + this.dataList.length);
|
||
if (this.dataList.length !== 0) {
|
||
this.dataList[this.k].state = 'play';
|
||
setTimeout(() => {
|
||
uni.createVideoContext(this.dataList[this.k].id, this).play()
|
||
}, 250)
|
||
}
|
||
},
|
||
onHide() {
|
||
this.dataList[this.k].state = 'pause'; //界面隐藏也要停止播放视频
|
||
setTimeout(() => {
|
||
uni.createVideoContext(this.dataList[this.k].community_id, this).pause(); //暂停以后继续播放
|
||
}, 250)
|
||
// console.log('到后台');
|
||
},
|
||
onLoad(options) {
|
||
this.platform = uni.getSystemInfoSync().platform
|
||
this.windowWidth = uni.getSystemInfoSync().screenWidth //获取屏幕宽度
|
||
this.boxStyle.width = this.windowWidth + 'px' //给宽度加px
|
||
this.wHeight = uni.getSystemInfoSync().screenHeight; //获取屏幕高度
|
||
this.boxStyle.height = this.wHeight; //改变视频高度
|
||
console.log(this.boxStyle.height)
|
||
this.room = JSON.parse(decodeURIComponent(options.data));
|
||
|
||
this.get()
|
||
|
||
},
|
||
mounted() {
|
||
|
||
},
|
||
Ready() {},
|
||
methods: {
|
||
|
||
|
||
|
||
autoPlay() {
|
||
this.isAutoplay = !this.isAutoplay;
|
||
if (!this.isAutoplay) {
|
||
this.autoplayText = "开启自动播放"
|
||
uni.showToast({
|
||
title: "关闭自动播放",
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
} else {
|
||
this.autoplayText = "关闭自动播放"
|
||
uni.showToast({
|
||
title: "开启自动播放",
|
||
icon: 'none',
|
||
duration: 3000
|
||
})
|
||
}
|
||
},
|
||
getData() {
|
||
// 这里就是数据加载完以后再向后端发送数据的地方,
|
||
|
||
|
||
},
|
||
vedioerr(e) {
|
||
let timer = null
|
||
if (e.tye = 'error') {
|
||
timer = setInterval((res) => {
|
||
uni.createVideoContext('myVideo', this).play()
|
||
console.log('重新连接', '1111111111')
|
||
}, 600000)
|
||
} else {
|
||
timer = null
|
||
}
|
||
|
||
},
|
||
|
||
touchstart(event) {
|
||
this.dataList[this.k].isShowimage = true //刚触摸的时候就要显示预览视频图片了
|
||
this.dataList[this.k].isShowProgressBarTime = true //显示时间线
|
||
this.ProgressBarOpacity = 1 //让滑块显示起来更明显一点
|
||
this.dotWidth = 10 //让点显示起来更明显一点
|
||
},
|
||
touchend() { //当手松开后,跳到最新时间
|
||
uni.createVideoContext(this.dataList[this.k].community_id, this).seek(this.newTime)
|
||
if (this.dataList[this.k].state == 'pause') {
|
||
this.dataList[this.k].state = 'play'
|
||
uni.createVideoContext(this.dataList[this.k].community_id, this).play()
|
||
}
|
||
this.dataList[this.k].isShowProgressBarTime = false //触摸结束后,隐藏时间线
|
||
this.dataList[this.k].isShowimage = false //触摸结束后,隐藏时间预览
|
||
this.ProgressBarOpacity = 0.5 //隐藏起来进度条,不那么明显了
|
||
this.dotWidth = 0 //隐藏起来进度条,不那么明显了
|
||
},
|
||
touchmove(event) { //当手移动滑块时,计算位置、百分小数、新的时间
|
||
var msg = []
|
||
if (this.videoTime !== '') {
|
||
msg = this.videoTime.split(':')
|
||
}
|
||
var timeNumber = Number(msg[0]) * 60 + Number(msg[1])
|
||
this.currentPositions = event.changedTouches[0].screenX
|
||
this.percent = this.currentPositions / this.windowWidth
|
||
this.newTime = this.percent * timeNumber
|
||
this.currenttimes = parseInt(this.newTime)
|
||
let theTime = this.newTime
|
||
let middle = 0; // 分
|
||
if (theTime > 60) {
|
||
middle = parseInt(theTime / 60);
|
||
theTime = parseInt(theTime % 60);
|
||
}
|
||
this.changeTime =
|
||
`${Math.round(middle)>9?Math.round(middle):'0'+Math.round(middle)}:${Math.round(theTime)>9?Math.round(theTime):'0'+Math.round(theTime)}`
|
||
},
|
||
timeupdate(event, index) { //计算滑块当前位置,计算当前百分小数
|
||
if (index == this.k) {
|
||
var currenttime = event.detail.currentTime
|
||
this.timeNumber = Math.round(event.detail.duration)
|
||
this.getTime()
|
||
this.percent = currenttime / this.timeNumber
|
||
this.currentPosition = this.windowWidth * this.percent
|
||
let theTime = currenttime
|
||
let middle = 0; // 分
|
||
if (theTime > 60) {
|
||
middle = parseInt(theTime / 60);
|
||
theTime = parseInt(theTime % 60);
|
||
}
|
||
this.changeTime =
|
||
`${Math.round(middle)>9?Math.round(middle):'0'+Math.round(middle)}:${Math.round(theTime)>9?Math.round(theTime):'0'+Math.round(theTime)}`
|
||
//自动切换视频
|
||
if (this.isAutoplay) { //true,代表自动播放
|
||
if (Math.round(currenttime) == this.timeNumber - 1) {
|
||
const dom = uni.requireNativePlugin('dom')
|
||
let doms = 'item' + (this.k + 1)
|
||
setTimeout(() => {
|
||
let el = this.$refs[doms][0]
|
||
dom.scrollToElement(el, {
|
||
offset: 0,
|
||
animated: true
|
||
})
|
||
}, 500)
|
||
}
|
||
}
|
||
}
|
||
},
|
||
getTime() { //得到时间函数
|
||
this.videoTime = this.formatSeconds(this.timeNumber);
|
||
var msg = []
|
||
if (this.videoTime !== '') {
|
||
msg = this.videoTime.split(':')
|
||
}
|
||
this.videoTimes = `${msg[0]>9?msg[0]:'0'+msg[0]}:${msg[1]>9?msg[1]:'0'+msg[1]}`;
|
||
},
|
||
formatSeconds(value) { //获取时间函数
|
||
let theTime = parseInt(value); // 秒
|
||
let middle = 0; // 分
|
||
if (theTime > 60) {
|
||
middle = parseInt(theTime / 60);
|
||
theTime = parseInt(theTime % 60);
|
||
}
|
||
return `${middle>9?middle:middle}:${theTime>9?theTime:theTime}`;
|
||
},
|
||
moreVideo(index) {
|
||
|
||
},
|
||
toVideo(index) {
|
||
|
||
},
|
||
scrolls(event) {
|
||
|
||
this.showManage = false;
|
||
this.isDragging = event.isDragging;
|
||
if (!event.isDragging) { //isDragging:判断用户是不是在滑动,滑动:true,停止滑动:false。我们要用户停止滑动时才给 k 赋值,这样就可以避免很多麻烦
|
||
var i = Math.round(Math.abs(event.contentOffset.y) / (this.wHeight - this.deleteHeight +
|
||
1)) //先用绝对值取出滑动的距离,然后除以屏幕高度,取一个整,就知道你现在滑动到哪一个视频了
|
||
if (i !== this.k) { //这里加判断是因为这个方法会执行很多次,会造成重复请求,所以这里写一个限制
|
||
if (uni.getSystemInfoSync().platform == 'ios') {
|
||
this.k = i //判断了用户没有滑动,确认了用户的确是在看这个视频,然后就赋值啦
|
||
this.dataList[this.k].state = 'play'
|
||
// console.log('正在播放 --> 第' + (this.k + 1) + '个视频~')
|
||
} else {
|
||
clearTimeout(this.timers);
|
||
this.timers = setTimeout(() => {
|
||
this.k = i //判断了用户没有滑动,确认了用户的确是在看这个视频,然后就赋值啦
|
||
this.dataList[this.k].state = 'play'
|
||
// console.log('正在播放 --> 第' + (this.k + 1) + '个视频~')
|
||
}, 80)
|
||
}
|
||
}
|
||
}
|
||
},
|
||
get() {
|
||
let that = this
|
||
var msg = [this.room];
|
||
console.log(this.room)
|
||
for (let i = 0; i < msg.length; i++) {
|
||
msg[i]['isMore'] = false
|
||
msg[i]['playIng'] = false
|
||
msg[i]['state'] = false
|
||
msg[i]['isplay'] = false
|
||
msg[i]['loading'] = false
|
||
msg[i]['id'] = msg[i]['live_stream_id']
|
||
}
|
||
this.dataList = msg;
|
||
|
||
if (this.dataList.length !== 0) {
|
||
|
||
this.dataList[this.k].state = 'play';
|
||
uni.createVideoContext(this.dataList[this.k].id, this).play()
|
||
this.page = that.page + 1
|
||
}
|
||
|
||
console.log(this.dataList, this.dataList[this.k].id, 222222)
|
||
},
|
||
onpullingdown() {
|
||
this.refreshing = true
|
||
},
|
||
onrefresh() {
|
||
setTimeout(() => {
|
||
this.refreshing = false
|
||
}, 1000)
|
||
},
|
||
|
||
},
|
||
onReachBottom() {
|
||
uni.$emit('onReachBottom');
|
||
},
|
||
}
|
||
</script>
|
||
<style lang="scss" scoped>
|
||
|
||
</style> |