Uniapp viedo timeupdate计时器代替@ended提交视频进度与视频拖动限制
:由于uniapp 在Hbuilder打包后可能导致viedo组件@ended无法触发的问题,不能完成视频。
:除此之外,还有可能需要的视频未完整播放不可拖动功能,但是已经播放过的视频可以随意拖动
Template:
<template>
<view>
<view class="uni-padding-wrap uni-common-mt">
<view>
<video id="myVideo" src=""
@error="videoErrorCallback"
:danmu-list="danmuList"
enable-danmu
danmu-btn
controls
enable-progress-gesture
show-progress
@timeupdate="timeupdate"
@ended="onfinish"
>
</video>
</view>
</view>
</view>
</template>
JS
<script>
export default {
data() {
return {
initialTime: 0, //用户视频播放的位置、
videoTime: 0, // 视频时间长度
watchTime: 0, // 实际观看时间
videoRealTime: 0, // 实时播放进度
isFinishedVideo: false, //该值在视频播放完成时由你的接口保存,并在视频切换时拿取这个值判断是否限制拖动
video_timer_flag: true, //控制节流器
}
},
onLoad() {
this.videoContext = uni.createVideoContext('myVideo', this);
/**
这里需要获取视频播放信息,其中需要视频播放进度状态 完成/未完成 字段来改变this.isFinishedVideo是否做限制
**/
},
//当播放到末尾时或用户手动拖到末尾时触发
onfinish(e) {
//console.log("观看时长", this.watchTime);
//console.log("视频时长", this.videoTime);
/* 不限制拖动 已播放视频可以拖动进度*/
if (this.isFinishedVideo) {
//不限制拖动时的操作
} else {
console.log("不可拖动进度完成");
}
/* ios触发条件 ios没有出现@ended无法触发的情况 根据自己需求调整 */
// if (uni.getSystemInfoSync().platform == "ios" && this.videoTime != 0 && this.watchTime != 0) {
// if (this.videoTime - this.watchTime <= 1) { //差值的大小由你的业务需要调整
// this.finshiThisVideo();//调用完成视频进度
// this.watchTime = 0;//重置观看时间
// } else {
// console.log("ios不满足完成条件");
// this.videoContext.play()
// }
// }
/* 安卓触发条件 这里是阻止拖动完成,实际使用timeupdate()(安卓不依赖@ended,有几率不触发) */
if (uni.getSystemInfoSync().platform == "android" && this.videoTime != 0 && this.watchTime != 0) {
let a = this.videoTime;
let b = this.watchTime;
let c = a - b;
if (c < 1) {
//这里不依赖@ended完成视频进度的提交
} else {
console.log("安卓不满足完成条件");
this.videoContext.play()//重新播放或seek到最后播放的位置
}
}
},
//计时器
timeupdate(e) {
//当前进度
let currentTime = parseInt(e.detail.currentTime);
//总进度
let duration = parseInt(e.detail.duration);
// console.log('当前进度:',currentTime,'总进度:', duration);
/* 这里是记录播放时长以判定用户拖动 */
//前置判断 若限制拖动
if (this.isShowProgress == false) {
this.videoTime = parseInt(duration)
// 记录当前视频进度
var skipTime = parseInt(e.detail.currentTime)
if (skipTime - this.watchTime > 3) {
//跳过进度大于3则跳回实际观看时间点
this.videoContext.seek(this.watchTime)
if (this.watchTime != 0) {
//首次观看不提醒
uni.showToast({
title: '未完整观看视频,不可跳过',
icon: 'none',
duration: 2000
})
}
} else {
//没有跳过行为保存观看时长
this.videoRealTime = parseInt(e.detail.currentTime)
if (this.videoRealTime > this.watchTime) {
this.watchTime = this.videoRealTime
}
}
} else {
// console.log("可拖动进度条");
}
/* 安卓提交进度 */
if (uni.getSystemInfoSync().platform == "android") {
//实际观看不为0
if (this.watchTime != 0 && this.videoTime != 0) {
//播放到末尾
if (this.videoTime - this.watchTime <= 1) {
this.video_ended();//调用节流器
this.videoContext.pause()//暂停当前视频播放
this.watchTime = 0;//重置时长
console.log("安卓完成播放");
}
}
}
},
/* 完成视频播放进度 节流是由于 timeupdate在2秒内可触发4次 */
video_ended() {
let self = this;
if (!this.video_timer_flag) {
return
}
this.video_timer_flag = false
setTimeout(function() {
console.log("安卓触发节流器");
self.finshiThisVideo();//这里是完成视频播放后的业务
self.video_timer_flag = true;
}, 1000 * 2.5);//这里大于2s即可
},
}
</script>
以上是计时器替代@ended,及如何限制用户提前完成视频的方法。 没有最完美的代码,欢迎提出改进意见。