基于video.js使用问题
这些问题都是我项目遇到的,我项目是视频设置问题点, 用户观看时不能点击进度条快进,看过的可快进,遇到问题点会暂停弹出问题,回答正确才能继续观看,回答错误返回上一个问题的位置重新观看,并且要记录用户观看位置,下次进来提示 是否 要跳转到上次观看的位置,包括pc端和手机web端, 目前遇到最大问题就是测试移动端兼容问题,花了很多时间,稍作总结,总体可以。就是对于浏览器兼容效果还是不能全部兼容,因为video标签实在无解,后面也尝试换插件试试,比如西瓜播放器, 但是经过测试,也没有解决层级问题,我放弃了,下面总结少的,如有问题,多多交流。
下面问题是基于 video.js开发遇到的
1.禁用进度条
要求: 用户没看过的不许 点击或拖动 进度条快进, 已看过的部分 可以进行拖动或快进
pc端:
正常页面: 定时器 + 鼠标点击事件(多一个事件是为了防止用户一直点击有问题的那个点)
模拟器:只 用定时器 (监听窗口判断,模拟器就解绑鼠标事件,pc就再绑定)
移动端:
只用定时器就可以
// 1.绑定事件的处理
// 点击进度条事件--绑定事件
// 初始化时就绑定
window.owner.isBind = true;
document
.getElementsByClassName("vjs-progress-control")[0]
.addEventListener("mousedown", window.owner.dot);
document
.getElementsByClassName("vjs-progress-holder")[0]
.addEventListener("mousedown", window.owner.dot);
dot() {
window.owner.isSeek = true;// 标志跳转了
window.owner.oldTime = this.player.getCache().currentTime; // 获得上一次点击 的时间(默认会缓存点击跳转前那个位置时间)
},
// 点击事件对应得监听 跳转 ,这个事件大约250ms执行一次
that.on("timeupdate", function() {
// 如果是点击进度条方式跳转到问题点的并且不是移动端模拟器的,这样禁止
if (
(that.currentTime() > window.owner.maxTime) &&
window.owner.isSeek &&
!window.owner.isMobile
) {
that.currentTime(window.owner.oldTime); // 回到上一点
} else {
}
});
// 2.定时器
// 开启时刻 --在播放事件开启
that.on("play", function() {
window.owner.isSeek = false;
// 开启进度条禁用定时器: 先清除再开启。保证每次只开一个
clearInterval(window.owner.timeId1);
window.owner.timeId1 = setInterval(window.owner.timer, 300);
});
// 定时器,判断用户是否快进或者拖动进度条
timer() {
let curTime = this.player.currentTime(); // 当前时间
var apartTime = curTime - window.owner.oldTime; // 当前时间和 上次保存的时间差 ,两者差大于2代表是用户点击了 进度条 快进
// 如果大于最长纪录时间并且不是教师预览,跳回原先学习的位置
if (
apartTime > 2 &&
curTime > window.owner.maxTime &&
!window.owner.isTeacherPreview
) {
this.player.currentTime(window.owner.oldTime); // 重置回点击前位置
} else {
window.owner.oldTime = curTime; // 记录时间
if (curTime > window.owner.maxTime) {
window.owner.maxTime = curTime; // 记录最长时间
}
}
},
// mounted 添加 监听窗口变化
window.onresize = function() {
window.owner.isMobiles(); // 监听窗口变化,判断用户是否在pc端使用 调试模拟器打开页面
};
// 判断是否用户切换了浏览器的模拟器运行,是的话解绑事件,只用定时器
isMobiles() {
if (
window.navigator.userAgent.match(
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
)
) {
window.owner.isMobile = true;
if (window.owner.vData.isStudyDown != 1) {
window.owner.isBind = false;
document
.getElementsByClassName("vjs-progress-control")[0]
.removeEventListener("mousedown", window.owner.dot);
document
.getElementsByClassName("vjs-progress-holder")[0]
.removeEventListener("mousedown", window.owner.dot);
}
console.log("移动端模拟器");
return true; // 移动端
} else {
window.owner.isMobile = false;
if (window.owner.vData.isStudyDown != 1 && !window.owner.isBind) {
document
.getElementsByClassName("vjs-progress-control")[0]
.addEventListener("mousedown", window.owner.dot);
document
.getElementsByClassName("vjs-progress-holder")[0]
.addEventListener("mousedown", window.owner.dot);
}
console.log("pc端");
return false; // PC端
}
}
2.跳转播放问题
pc端:
这样就可以
this.player.currentTime(time); // 跳转
移动端:
移动端上面方法直接跳在 移动端浏览器支持不一致,qq、微信可以,但是 uc/qq浏览器就不行,我们需要先播放,初始化了视频再跳就没问题
解决:
设置一个标志位,在 timeupdate 监听跳转, 跳转前先播放视频
// 跳转播放
handleSkip() {
clearInterval(window.owner.timeId1); // 先清除定时器
window.owner.oldTime = Number.parseInt(this.vData.midVideoStudyLength);
// this.player.currentTime(
// Number.parseInt(this.vData.midVideoStudyLength)
//); // 直接跳转,有些移动端浏览器跳转不了,比如qq浏览器...
this.player.play(); // 播放
this.skipFlag = true; // 设置可跳转
this.showSkipToast = false;
// setTimeout(()=> { // 不建议使用定时器了,跳转会卡顿
// player.currentTime(ctime)
// }, 500)
},
// 监听跳转和记录保存
that.on("timeupdate", function() {
let time = window.owner.getCurrentTime();
localforage.setItem("videoLearnerTime", {
midTime: time,
maxTime: window.owner.maxTime
}); // 保存记录
// 跳转
if (window.owner.skipFlag) {
that.currentTime(
Number.parseInt(window.owner.vData.midVideoStudyLength)
);
window.owner.skipFlag = false;// 跳转了设置false
}
});
对于跳转时间不准确问题,比如跳到2.5s会直接跳到3s,这里涉及到帧间距问题,大家可以百度一下这方面知识。
3.视频记录保存问题
pc和单页面移动端:
在组件销毁时调用保存api即可,不过还有一种情况,就是刷新和关掉页面时保存,这时候我采用的方法是监听页面卸载事件
1.页面销毁
beforeDestroy() {
window.onbeforeunload = null;
// 清除定时器
this.showSkipToast = false;
this.studyAll = false;
clearTimeout(window.owner.timeId);
clearInterval(window.owner.timeId1);
let time = this.getCurrentTime();
if (time > 0) {
// 保存记录 保存当前时间和最大观看时间maxTime
this.markVideoStudyLength(parseInt(time));
}
if (this.player) {
this.player.dispose(); // //销毁video实例,避免出现节点不存在 但是flash一直在执行,也避免重新进入页面video未重新声明
}
},
2.
// 页面卸载保存记录--针对pc端,移动端这样体验感不好
window.onbeforeunload = function(e) {
e = e || window.event;
// 兼容IE8和Firefox 4之前的版本
if (e) {
e.returnValue = "关闭提示";
}
window.owner.isClose = true;
let time = window.owner.getCurrentTime();
if (time > 0) {
window.owner.markVideoStudyLength(parseInt(time));
}
// Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
return "关闭提示";
};
多页面移动端:
多页面形式,组件没有调用到destory函数, 所以不能在销毁时保存, 并且多页面跳到某个页面会重刷新页面,所以可以使用localstorage保存记录, 在timeupdate 中保存,然后再通过父组件生命周期函数中读取 localstorage的值进行保存(根据具体情况定在哪保存,这里只是提供思路,因为有的人组件调用方式不太一样)
4.video层级问题
video标签在某些浏览器中会被劫持,层级最高层,无法被覆盖,qq,微信,edge,safari没有这个问题,uc/qq浏览器(全屏时会有)等部分会有
这种情况就会影响到在视频播放过程弹出的 问题 弹框,被盖住了
解决思路:这个思路也只能大致解决了,因为只适配了qq,微信,edge,safari 这几个,其他真没办法
-
添加属性,设置支持x-h5内核的浏览器 同层,行内播放视频
-
通过隐藏元素标签,在遇到弹框时就设置 video标签的父标签 display:none, 弹框取消再设置回来block
1. <div class="video-player-container" ref="videoContainer" v-show="videoShow" > <video ref="videoPlayer" id="video_palyer" class="video-js vjs-default-skin vjs-big-play-centered " x5-video-player-type="h5" // 同层播放 webkit-playsinline="true" playsinline="true" // 行内,不脱离文档流 x-webkit-airplay="allow" x5-video-orientation="portrait" // 竖屏展示 x5-video-player-fullscreen="true" ></video> </div> 2.
4.css一些样式设置
样式设置
// 暂停显示大按钮
::v-deep .vjs-paused .vjs-big-play-button,
::v-deep .vjs-paused.vjs-has-started .vjs-big-play-button {
display: block;
font-size: 3.5em;
}
// 正向播放,显示已播放时长
::v-deep .video-js .vjs-time-control {
display: block;
}
::v-deep .video-js .vjs-remaining-time {
display: none;
}
::v-deep .vjs-control-bar {
font-size: 14px;
}
//5.暂停会出现黑边
给video标签加style=" outline:none"
5.一些事件执行顺序
一些事件触发顺序:
timeupdate这个只要视频播放,有改变播放时间都会触发,大概205ms执行一次
1.正常播放
play - timeupdate - pause
2.正常播放时点击进度条快进到另一个位置 (快退也一样过程)
播放时间改变–
暂停–pause
寻找中 --seeking
播放时间改变–timeupdate
寻找完毕–seeked
播放时间改变–timeupdate
播放时间改变–timeupdate
开始播放:–play
console.log打印过程:
播放时间改变:36.856077
v2.vue?9818:48 暂停 36.856077
v2.vue?9818:55 寻找中:36.856077
v2.vue?9818:63 播放时间改变:36.856077
v2.vue?9818:59 寻找完毕:36.856077
v2.vue?9818:63 播放时间改变:36.856077
v2.vue?9818:63 播放时间改变:36.856077
v2.vue?9818:51 开始播放:play :36.856077
3.暂停时点击进度条快进(少了开头暂停和结尾播放)
寻找中
播放时间改变
寻找完毕
播放时间改变
播放时间改变
4. 拖动进度条(差不多,只是寻址过程会被多次触发)
暂停–pause
寻找中 --seeking (这3个会多次触发)
播放时间改变–timeupdate
寻找完毕–seeked
播放时间改变–timeupdate
播放时间改变–timeupdate
开始播放:–play
end:
大概稍微总结这么多,笔记可以做的不是很好,有问题可以交流哈