问题:
1.ios的小程序测试没问题,看完视频再次点击视频就在上一次看到的位置
2.但是安卓第一次进去会在上一次位置,返回上一页再点击视频进去就从头开始
原因:
找了好久是 videoId的问题 ,我写的videoId = 'myVideo'
,因为我把创建并返回 video 上下文 videoContext 对象里的videoId,与seek的存本地的时候要用到唯一id写的是同一个,导致我看第一个视频是五秒,第二个视频也是五秒,我以为是videoId 不是唯一,导致每个视频播放都是同一位置,我就把videoId =id + mainIdGenerator
来确保唯一性,这个时候看ios,确实没啥毛病了,问题都解决了,当我打开安卓端的小程序就出现问题了,就是如上问题【第一次进去会在上一次位置,返回上一页再点击视频进去就从头开始】,其实是data return设置videoId =“”
,在onload拿到id赋值给videoId导致就是视频都播放后videoId 才赋值成功,自然就从0开始播放【我自己的项目写的是这样,如有理解错误可以告诉我,都是小白~~】
解决:
其实视频上下videoId 可以不唯一,但是seek到具体位置,这里存本地的时候要用到唯一id
但uni.createVideoContext(this.myVideo, this);this.myVideo
只要 在当前页面唯一就可以了,你返回之后页面会被卸载的
this.myVideo = "myVideo"
this.videoId = id + mainIdGenerator;
uni.getStorageSync(`play-duration-${this.videoId}`)
this.videoContext = uni.createVideoContext(this.myVideo, this);
this.myVideo用于uni.createVideoContext
this.videoId用于存储播放时间 uni.getStorageSync(play-duration-${this.videoId}
)
<template>
<view class="courseVideo">
<view class="videoimage">
<video
:id="videoId"
:src="videoUrl"
:controls="true"
loop
preload
direction="90"
objectFit="fill"
:fullscreen="false"
show-mute-btn
vslide-gesture-in-fullscreen
:enable-progress-gesture="true"
:enable-play-gesture="true"
:show-center-play-btn="true"
:show-loading="true"
@timeupdate="onTimeUpdate"
@play="beginPlay"
@ended="onVideoPlayEnd"
@canplay="oncanplay"
@pause="onPause"
>
<cover-view class="speed" v-if="fullscreen">
<cover-view @click="speedNum = true" class="doubleSpeed"
>倍速</cover-view
>
</cover-view>
<cover-view
v-if="speedNum"
class="speedModal"
:style="{ height: videoWidth + 16 + 'px' }"
@click.stop="speedNum = false"
>
<cover-view
@click="speedNum = true"
class="doubleSpeed"
:style="{ height: videoWidth + 16 + 'px' }"
>1.0x</cover-view
>
<cover-view class="speedNumBox">
<cover-view
@click.stop="handleSetSpeedRate(0.5)"
:class="[0.5 == speedRate ? activeClass : errorClass, 'number']"
>0.5x</cover-view
>
<cover-view
@click.stop="handleSetSpeedRate(1)"
:class="[1 == speedRate ? activeClass : errorClass, 'number']"
>1.0x</cover-view
>
<cover-view
@click.stop="handleSetSpeedRate(1.25)"
:class="[1.25 == speedRate ? activeClass : errorClass, 'number']"
>1.25x</cover-view
>
<cover-view
@click.stop="handleSetSpeedRate(1.5)"
:class="[1.5 == speedRate ? activeClass : errorClass, 'number']"
>1.5x</cover-view
>
<!-- <cover-view
@click.stop="handleSetSpeedRate(2.0)"
:class="[2.0 == speedRate ? activeClass : errorClass, 'number']"
>2.0x</cover-view
> -->
</cover-view>
</cover-view>
</video>
</view>
</view>
</template>
<script>
export default {
data() {
return {
tabs: [
{
name: "11",
id: 1,
value: "comment",
},
],
currentTab: 0,
videoUrl:'',
videoContext: null,
videoCurrentTime: 0,
currentTime: 0,
duration: 0,
playStatus: false,
videoId: '',
myVideo:"myVideo"
};
},
onLoad(e) {
let {
id,
hrefcourse,
mainIdGenerator,
} = e;
this.$nextTick(() => {
this.myVideo = "myVideo"
this.videoId = id + mainIdGenerator;
this.videoUrl = hrefcourse
this.videoContext = uni.createVideoContext(this.videoId, this);
console.log(this.videoContext, 'videoContext');
const playbackTimes = uni.getStorageSync(`play-duration-${this.videoId}`);
console.log(playbackTimes, 'playbackTimes');
// 在视频加载时从本地存储中读取已保存的播放时间
if (playbackTimes) {
if (this.status == "false" && this.isExist == "false") {
//说明第一次播放初始化,或者就是重修视频初始化
this.videoContext.seek(0);
} else {
this.videoCurrentTime = Math.round(playbackTimes);
this.videoContext.seek(Math.round(playbackTimes));
}
}
});
},
methods: {
onTimeUpdate(event) {
console.log('播放中', event.target.currentTime);
this.currentTime = event.target.currentTime; // 视频观看的长度
this.duration = event.target.duration; // 视频总时长
uni.setStorageSync(`play-duration-${this.videoId}`, this.currentTime);
if (!this.playStatus) {
const number = Math.abs(this.currentTime - this.videoCurrentTime);
if (number.toFixed(3) > 2) {
const nowtime = this.videoCurrentTime.toFixed(0);
this.videoContext.seek(Number(nowtime));
} else {
this.videoCurrentTime = this.currentTime;
}
console.log('第一个播放一次了yin');
}
},
//防作弊功能:就是播放中每五分钟弹框提醒一次,当退出页面,暂停页面,满五分钟等都会重新计时
startReminderTimer() {
//防作弊功能,每五分钟提醒一次
// console.log(this.status, this.status);
if (this.status == "false" && this.isCheat) {
this.timerValue = setTimeout(() => {
this.videoContext.pause();
showConfirmVideo(
this.$t(
"pages.course.You_have_watched_for_5_minutes_Click_OK_to_continue_playing"
),
this.$t("pages.course.note"),
this.$t("common.button.cancel"),
this.$t("common.button.confirm")
).then((res) => {
if (res.confirm) {
if (this.timerValue) {
clearTimeout(this.timerValue); // 清除计时器
this.videoContext.play();
}
} else {
this.videoContext.pause();
}
});
}, 5 * 60 * 1000); //5* 60 *1000
}
},
// 清除定时器
clearReminderTimer() {
if (this.timerValue) {
clearTimeout(this.timerValue); // 清除计时器
}
},
//监听播放结束
onVideoPlayEnd() {
this.isSeekable = true; // 播放结束后恢复滑动状态
this.loadingStatus = false; //就是没有播放只是初始化完返回不调用接口
this.playStatus = true; //记录播放的状态 || 播放完毕的状态让进度条重置为0
this.endTime = Date.now(); // 记录视频播放结束的时间
uni.setStorageSync(`${this.endTimeKey}-${this.id}`, this.endTime);
console.log("结束了", this.endTime);
//播放结束掉视频插入接口
// this.VideoProgress(this.playStatus);
this.clearReminderTimer();
},
//监听播放状态
beginPlay() {
this.loadingStatus = false;
this.startTime = Date.now(); // 记录视频开始播放的时间
uni.setStorageSync(`${this.startTimeKey}-${this.id}`, this.startTime);
// console.log("playStatus开始了", this.startTime);
this.startReminderTimer();
},
oncanplay() {
console.log("暂停了等待中load");
this.clearReminderTimer();
},
onPause() {
//暂停了
console.log("暂停了");
this.clearReminderTimer();
},
//掉后端插入接口告诉后端看了多少秒
VideoProgress(){
},
//设置倍速速度
handleSetSpeedRate(rate) {
// const videoContext = uni.createVideoContext("videoId");
const videoContext = uni.createVideoContext(this.videoId);
// console.log(videoContext, "console.log(videoContext);");
videoContext.playbackRate(rate);
this.speedRate = rate;
this.speedNum = false;
},
swichMenu(id) {
this.currentTab = id;
this.tabCurrent = "tabNum" + id;
},
},
onUnload() {
this.videoContext = null;
this.videoId = null;
},
};
</script>