Merge branch 'pingcode-20240615' into master-0726

# Conflicts:
#	pages/study/courseStudy.vue
This commit is contained in:
nisen
2024-08-01 14:50:11 +08:00
6 changed files with 612 additions and 33 deletions

View File

@@ -26,9 +26,13 @@ const userTaskList = function(data){
const userDeleteStudy = function(data){ const userDeleteStudy = function(data){
return ajax.postJson(baseURL,'/stu/project/stuCancelEnrollment',data); return ajax.postJson(baseURL,'/stu/project/stuCancelEnrollment',data);
} }
// 移动端视频播放器设置开关
const getDictCode = function(code){
return ajax.get(baseURL+'/dict?code=' + code);
}
export default { export default {
getTaskNum, getTaskNum,
userTaskList, userTaskList,
userDeleteStudy userDeleteStudy,
getDictCode
} }

View File

@@ -78,7 +78,6 @@ const studyInfo = function(courseId) {
* @param {Object} contentId * @param {Object} contentId
*/ */
const getStudyContentItem = function(studyId,contentId) { const getStudyContentItem = function(studyId,contentId) {
console.log(1111)
return ajax.post('/xboe/school/study/course/study-course-content',{studyId,contentId}); return ajax.post('/xboe/school/study/course/study-course-content',{studyId,contentId});
} }

View File

@@ -0,0 +1,241 @@
/**
$emit: updateProgress, -> 调整进度条后触发的事件传递参数currentProgress
getMouseDownStatus, -> 获取是否鼠标按下的状态传递参数true/false
props: width, height,
currentProgress, -> 当前进度范围0-1
*/
<template>
<div
class="progress-bar"
:style="{width: width}"
@touchstart.left="start"
@touchmove="move"
@touchend="up"
>
<div class="progress-full" :style="{height: height}">
<div class="progress-current" :style="{width: currentProgress + '%'}"></div>
</div>
</div>
</template>
<script>
export default {
name: "progress-bar",
props: {
width: {
type: String,
default: "100%",
},
height: {
type: String,
default: "4px",
},
fullScreenFlag:{
type: Boolean,
default: false,
},
// 当前进度范围0-1
currentProgress: {
type: Number,
default: 0,
},
isDrag:{
type: Boolean,
default: true,
},
blobId:{
type: String,
}
},
data() {
return {
is_mousedown_progress: false, //是否点击了进度条并保持点击状态
current_width_px: 0, // 当前竖屏进度条的像素长度
current_height_px: 0, // 当前全屏进度条的像素长度
init_clientX: 0, //竖屏初始进度的偏移量,相对于视口
init_clientY: 0, //全屏初始进度的偏移量,相对于视口
dom_full: null, //完整进度条的dom即进度条背景
};
},
mounted() {
//console.log(this.isDrag,'isDrag');
//初始化一些固定数据
let dom_full = this.$el.getElementsByClassName("progress-full")[0];
this.dom_full = dom_full;
// window.addEventListener("touchstart", (e) => {
// console.log("touchstart::",this.is_mousedown_progress)
// //if (this.is_mousedown_progress) {
// this.down(e);
// //}
// });
//绑定全局监听器
window.addEventListener("touchmove", (e) => {
//console.log("touchmove::",this.is_mousedown_progress)
if (this.is_mousedown_progress) {
this.move(e);
e.preventDefault();
}
},{ passive: false });
window.addEventListener("touchend", (e) => {
//console.log("touchend::",this.is_mousedown_progress)
this.up(e);
// e.preventDefault();
});
},
beforeDestroy() {
//
},
methods: {
start(e) {
this.$emit("getMouseDownStatus", true);
this.is_mousedown_progress = true;
if(this.fullScreenFlag){
// 全屏
// 获取完整进度条的clientYdom左上角
let init_clientY = this.dom_full.getBoundingClientRect().top;
// 计算调整后的当前进度条的长度
this.current_height_px = e.touches[0].clientY - init_clientY;
// 设置当前的播放进度(同时作用于当前进度条的样式)
let current = (e.touches[0].clientY - init_clientY) / this.dom_full.clientWidth;
if(current>1) current = 1;
if(current<0) current = 0;
var time = localStorage.getItem('videoProgressData');
var arr = time&&JSON.parse(time) || {}
//console.log('start::',e,this.isDrag,this.fullScreenFlag,time,arr[this.blobId] ,current,e.touches[0].clientY,init_clientY,this.dom_full.clientHeight,this.current_height_px,this.dom_full)
// 禁止拖动
if(!this.isDrag && time && arr[this.blobId] < current) return;
this.$emit("updateProgress",'start', current);
}else{
// 横屏
// 获取完整进度条的clientXdom左上角
let init_clientX = this.dom_full.getBoundingClientRect().left;
// 计算调整后的当前进度条的长度
this.current_width_px = e.touches[0].clientX - init_clientX;
// 设置当前的播放进度同时作用于当前进度条的样式
let current = (e.touches[0].clientX - init_clientX) / this.dom_full.clientWidth;
if(current>1) current = 1;
if(current<0) current = 0;
var time = localStorage.getItem('videoProgressData');
var arr = time&&JSON.parse(time) || {}
//console.log('start::',e,this.isDrag,this.fullScreenFlag,time,arr[this.blobId] ,current,e.touches[0].clientX,init_clientX,this.dom_full.clientWidth)
// 禁止拖动
if(!this.isDrag && time && arr[this.blobId] < current) return;
this.$emit("updateProgress",'start', current);
}
},
move(e) {
if (this.is_mousedown_progress) {
if(this.fullScreenFlag){
// 全屏
let init_clientY = this.dom_full.getBoundingClientRect().top;
this.current_height_px = e.touches[0].clientY - init_clientY;
let current = (e.touches[0].clientY - init_clientY) / this.dom_full.clientWidth;
if(current>1) current = 1;
if(current<0) current = 0;
var time = localStorage.getItem('videoProgressData');
var arr = time&&JSON.parse(time) || {}
//console.log('move::',e,this.isDrag,this.fullScreenFlag,time,arr[this.blobId] ,current,this.dom_full)
// 禁止拖动
if(!this.isDrag && time && arr[this.blobId] < current) return;
this.$emit("updateProgress",'move', current);
}else{
// 横屏
let init_clientX = this.dom_full.getBoundingClientRect().left;
this.current_width_px = e.touches[0].clientX - init_clientX;
let current = (e.touches[0].clientX - init_clientX) / this.dom_full.clientWidth;
if(current>1) current = 1;
if(current<0) current = 0;
var time = localStorage.getItem('videoProgressData');
var arr = time&&JSON.parse(time) || {}
//console.log('move::',e,this.isDrag,this.fullScreenFlag,time,arr[this.blobId] ,current)
// 禁止拖动
if(!this.isDrag && time && arr[this.blobId] < current) return;
this.$emit("updateProgress",'move', current);
}
}
},
up() {
if (this.is_mousedown_progress) {
// 标记鼠标不处于按下的状态了
this.is_mousedown_progress = false;
this.$emit("getMouseDownStatus", false);
if(this.fullScreenFlag){
// 全屏
// 松开鼠标后即调整进度条后此时的进度0-1
let current = this.current_height_px / this.dom_full.clientWidth;
if(current>1) current = 1;
if(current<0) current = 0;
var time = localStorage.getItem('videoProgressData');
var arr = time&&JSON.parse(time) || {}
//console.log('up::',this.isDrag,this.fullScreenFlag,time,arr[this.blobId] ,current,this.dom_full)
// 禁止拖动
if(!this.isDrag && time && arr[this.blobId] < current) return;
this.$emit("updateProgress",'end', current);
}else{
// 横屏
// 松开鼠标后即调整进度条后此时的进度0-1
let current = this.current_width_px / this.dom_full.clientWidth;
if(current>1) current = 1;
if(current<0) current = 0;
var time = localStorage.getItem('videoProgressData');
var arr = time&&JSON.parse(time) || {}
//console.log('up::',this.isDrag,this.fullScreenFlag,time,arr[this.blobId] ,current)
// 禁止拖动
if(!this.isDrag && time && arr[this.blobId] < current) return;
this.$emit("updateProgress",'end', current);
}
}
},
},
};
</script>
<style scoped>
.progress-bar {
position: relative;
cursor: pointer;
padding: 2px 0;
margin: 0;
transition: height 0.2s;
/*overflow: hidden;*/
}
.progress-bar:hover .progress-full {
height: 2px !important;
}
.progress-full {
position: relative;
display: inline-block;
width: 100%;
background: rgb(201, 201, 201);
transition: height 0.3s;
}
.progress-current {
position: absolute;
left: 0;
top: 0;
height: inherit;
width: 0%;
display: inline-block;
background-color: var(--primaryColor);
}
.progress-current::after {
content: "";
position: absolute;
display: inline-block;
right: 0;
top: 50%;
bottom: 50%;
width: 12px;
height: 12px;
border-radius: 100%;
background: #fff;
transform: translate(50%, -50%);
opacity: 1;
transition: opacity 0.3s;
}
.progress-bar:hover .progress-current::after {
opacity: 1;
}
</style>

View File

@@ -1,9 +1,14 @@
<template> <template>
<view id="xvideoPlayer-box" class="video-box"> <view>
<video id="xvideoPlayer" style="width: 100%;" <view v-if="!xvideoBool || xvideoBool&&drag" id="xvideoPlayer-box" :class="fullScreenFlag?'video-box video-full-screen':'video-box'">
<div style="color:#ffffff">{{currtimeText}}</div>
<!--webkit-playsinline playsinline x5-video-player-type="h5-page-->
<!-- :src="url" <video id="xvideoPlayer" :class="fullScreenFlag?'video-scree-rotate':''" :style="{width: fullScreenFlag?videoPageHeight+'px':'100%',height: fullScreenFlag?videoPageWidth+'px': '','margin-left':fullScreenFlag?-1*(videoPageWidth/videoPageHeight*256)+'px':'','top':fullScreenFlag?videoPageHeight/2+'px':''}" -->
<video id="xvideoPlayer" :class="fullScreenFlag?'video-scree-rotate':''" :style="{width: fullScreenFlag?videoPageHeight+'px':'100%',height: fullScreenFlag?videoPageWidth+'px': '','margin-left':fullScreenFlag?-1*(videoPageHeight-videoPageWidth)/2+'px':''}"
:src="url" :src="url"
:controls="false" :controls="false"
:enable-play-gesture="false" :enable-play-gesture="false"
:enable-progress-gesture="false"
:initial-time="initPlayingTime" :initial-time="initPlayingTime"
@error="error" @error="error"
@touchend="onTouchend" @touchend="onTouchend"
@@ -15,16 +20,33 @@
@loadeddata="onLoad" @loadeddata="onLoad"
@loadedmetadata="onMetaLoad" @loadedmetadata="onMetaLoad"
@controlstoggle="onControlsToggle" @controlstoggle="onControlsToggle"
></video> >
<view id="xplayer-control" > </video>
<view class="process-container" v-if="contrlShow"> <view id="xplayer-control">
<!-- <view class="process-container" v-if="contrlShow" :class="fullScreenFlag?'video-scree-rotate':''" :style="{width: fullScreenFlag?videoPageHeight+'px':'100%','margin-left':fullScreenFlag?'-320px':'','top':fullScreenFlag?'300px':videoFullHeight + 'px'}"> -->
<view class="process-container" v-if="contrlShow" :class="fullScreenFlag?'video-scree-rotate':''" :style="{width: fullScreenFlag?videoPageHeight*0.98+'px':'96%','margin-top':-1*videoPageHeight*0.02+'px','margin-left':fullScreenFlag?-1*(videoPageHeight-videoPageWidth)/2-174 - (videoPageWidth-375)/2+'px':'','bottom':fullScreenFlag?'auto':'0px'}">
<view class="controller-play"> <view class="controller-play">
<image :src="require(playing? './images/pause.png':'./images/play.png')" @click.stop='videoOpreation'/> <image :src="require(playing? './images/pause.png':'./images/play.png')" @click.stop='videoOpreation'/>
</view> </view>
<view class="currtime">{{currtime}}</view> <view class="currtime">{{currtime}}</view>
<view class='slider-container'> <!-- <cover-view v-if="drag" class='slider-container'>
<slider :disabled="!drag" @change.stop="sliderChange" @changing="sliderChanging" step="1" :value="sliderValue" backgroundColor="#9f9587" activeColor="#d6d2cc" block-color="#FFFFFF" block-size="12"/> <slider @change.stop="sliderChange" @changing="sliderChanging" step="1" :value="sliderValue" backgroundColor="#9f9587" activeColor="#d6d2cc" block-color="#FFFFFF" block-size="12"/>
-->
<!-- <slider v-if="!drag" disabled="true" step="1" :value="sliderValue" backgroundColor="#9f9587" activeColor="#d6d2cc" block-color="#FFFFFF" block-size="12"/> -->
<!-- </cover-view> -->
<view class='slider-container new-bar'>
<progressBar
:currentProgress="sliderValue"
:blobId="blobId"
:fullScreenFlag="fullScreenFlag"
v-on:updateProgress="updateProgressByClickBar"
v-on:getMouseDownStatus="getMouseDownStatusOfProgressBar"
:isDrag="drag"
width="100%"
></progressBar>
</view> </view>
<view class="druationTime">{{druationTime}}</view> <view class="druationTime">{{druationTime}}</view>
<view class="druationTime"> <view class="druationTime">
<view id="myVideoSpeed" class="player-speed btn-speed"> <view id="myVideoSpeed" class="player-speed btn-speed">
@@ -46,19 +68,45 @@
<view class="controller-screen"> <view class="controller-screen">
<image :src="require(fullScreenFlag? './images/back.png':'./images/full.png')" @click.stop='fullScreen'/> <image :src="require(fullScreenFlag? './images/back.png':'./images/full.png')" @click.stop='fullScreen'/>
</view> </view>
<!-- <view v-if="fullScreenFlag" @click.stop='horizontalScreen' class="controller-screen">
<text>{{horizontalScreenFlag? '竖屏':'横屏'}}</text>
</view> -->
</view> </view>
</view> </view>
</view> </view>
<view v-if="xvideoBool && !drag" class="video-box-error">
<view style="color: #ffffff;padding: 0px 50px 0px;font-size: 16px;">{{mobileVideoDragText}}</view>
<button style="display: inline-block;font-size: 14px;padding: 0px 10px;line-height: 28px;" v-if="mobileVideoDragSwitch == 'true'" @click="xvideoBoolFun">仍要使用此浏览器观看</button>
</view>
</view>
</template> </template>
<script> <script>
import progressBar from "@/components/video-player/progress-bar.vue";
import {mapGetters} from 'vuex' import {mapGetters} from 'vuex'
import studyUtil from '@/utils/study.js'; import studyUtil from '@/utils/study.js';
import apiManage from '@/api/manage/manage.js';
// getDictCode
function agentFullScreen(){
let bool = false
let agent = navigator.userAgent
if(agent.indexOf('XiaoMi')!=-1){
bool = true
}
return bool
}
//alert(navigator.userAgent +'----'+ agentFullScreen())
export default { export default {
components: { progressBar },
props: { props: {
url:{ url:{
type: String, type: String,
require: true require: true
}, },
// 视频链接对应的content Id
blobId: {
type: String,
default: null,
},
watermark:{ watermark:{
type: Boolean, type: Boolean,
default: true default: true
@@ -78,6 +126,7 @@
}, },
data() { data() {
return { return {
xvideoBool: agentFullScreen(), // 是否显示视频
contrlShow:false,//是否显示控制条 contrlShow:false,//是否显示控制条
contrlShowTimeout:null,//显示控制条句柄 contrlShowTimeout:null,//显示控制条句柄
videoContext:null,//播放器 videoContext:null,//播放器
@@ -89,12 +138,25 @@
updateState: true, //防止视频播放过程中导致的拖拽失效 updateState: true, //防止视频播放过程中导致的拖拽失效
playing:false,//是否在播放中 playing:false,//是否在播放中
curVideo:{ curVideo:{
duration:0 duration:0,
currentTime: 0
}, },
touchNum:0, touchNum:0,
speedListShow:false, speedListShow:false,
speedList:["2.0", "1.5", "1.25", "1.0", "0.75", "0.5"], speedList:["2.0", "1.5", "1.25", "1.0", "0.75", "0.5"],
videoSpeed: 1.0, // 当前倍速: videoSpeed: 1.0, // 当前倍速:
isMousedownProgress: false, // 鼠标是否按下了进度条(并未松开)
historyTime: 0, // 当前视频
videoFullHeight: 190, // 控制条的高度
videoPageWidth: 0, // 当前页面窗口宽度
videoPageHeight: 0, // 当前页面窗口高度
// horizontalScreenFlag: true // 默认竖屏
mobileVideoDragSwitch: '', // 视频播放器扔要使用此浏览器观看
mobileVideoDragText: '', // 视频播放器妆容提示文本内容
currtimeText: 0,
currentTimeFormat: "00:00", // 当前播放进度的文字
fullTimeFormat: "00:00", // 视频总长度的文字
iosCurrentTime: 0, // ios里视频播放毫秒
}; };
}, },
computed: { computed: {
@@ -102,28 +164,163 @@
}, },
watch:{ watch:{
url(newVal,oldVal){ url(newVal,oldVal){
//console.log( 'watch url:',newVal,oldVal,this.videoContext)
//document.getElementById('xvideoPlayer').style.display = 'none'
this.videoContext.stop(); this.videoContext.stop();
this.playing=false; this.playing=false;
this.curVideo.currentTime = 0;
this.iosCurrentTime = 0;
this.sliderValue = 0;
this.videoSpeed = 1.0;
this.currtime = "00:00";
document.getElementsByTagName('video')[0].load()
setTimeout(()=>{
document.getElementsByTagName('video')[0].play()
},100)
//this.videoContext.load();
//document.getElementById('xvideoPlayer').style.display = 'block'
//this.videoContext=uni.createVideoContext("xvideoPlayer", this);
}, },
inittime(newVal,oldVal){ inittime(newVal,oldVal){
this.initPlayingTime=newVal; this.initPlayingTime=newVal;
//console.log('inittime::',newVal,oldVal)
} }
}, },
mounted() { mounted() {
var _this = this
this.initPlayingTime=this.inittime; this.initPlayingTime=this.inittime;
this.videoContext=uni.createVideoContext("xvideoPlayer", this); this.videoContext=uni.createVideoContext("xvideoPlayer", this);
document.getElementsByTagName('video')[0].load()
uni.getSystemInfo({
success: function (info) {
//alert(info.windowWidth)
_this.videoPageWidth=info.windowWidth;
_this.videoPageHeight=info.windowHeight;
// 你可以在这里根据窗口高度进行后续操作
}
});
if(this.xvideoBool) this.dictCode();
// 每一秒更新进度条
setInterval(() => {
// 定时更新进度条
// if (this.isPlaying && !this.isMousedownProgress) {
// this.currentProgress = this.videoContext.currentTime / this.videoContext.duration;
// }
if (this.playing && !this.isMousedownProgress) {
this.iosCurrentTime = this.iosCurrentTime + 1
// this.sliderValue = this.iosCurrentTime/this.curVideo.duration * 100
}
// 定时更新进度的文字显示
this.updateProgressText();
}, 1000);
//绑定全局监听器
window.addEventListener("touchstart", (e) => {
if(this.speedListShow && !e.target.closest('.speed-control')){
this.speedListShow = false
}
},{ passive: false });
}, },
methods: { methods: {
xvideoBoolFun(){
this.xvideoBool = false
},
// 获取视频播放器设置开关字典
dictCode(){
var _this = this
apiManage.getDictCode('mobile_video_switch').then(res=>{
if(res.code==200 && res.data[0]){
_this.mobileVideoDragText = res.data[0].name
_this.mobileVideoDragSwitch = res.data[0].value
}
})
},
/* 点击进度条更新视频播放进度
*/
updateProgressByClickBar(type,value) {
let duration = this.curVideo.duration;
let second = Math.round(value * duration);
this.curVideo.currentTime = second;
this.sliderValue= value * 100,
this.druationTime = this.formatSeconds(duration);
this.currtime = this.formatSeconds(second);
this.iosCurrentTime = second;
//alert('1---this.currtime='+this.currtime)
// var duration=this.curVideo.duration;
// var second= value * duration;
if (duration) { //完成拖动后,计算对应时间并跳转到指定位置
if(type === 'start'){
this.updateState= false;
}
if( type === 'end'){
this.videoContext.seek(second);
this.curVideo.currentTime = second;
this.updateState= true //完成拖动后允许更新滚动条
//alert('value000------:'+value+'---'+this.curVideo.duration)
}
}
},
/* 获取鼠标是否按下了进度条
*/
getMouseDownStatusOfProgressBar(value) {
this.isMousedownProgress = value;
},
// 全屏+退出全屏 // 全屏+退出全屏
fullScreen(){ fullScreen(){
var _this = this
if(this.fullScreenFlag){ if(this.fullScreenFlag){
this.videoContext.exitFullScreen(); //this.videoContext.exitFullScreen();
this.fullScreenFlag=false; this.fullScreenFlag=false;
// this.horizontalScreenFlag = true
this.videoFullHeight=190
if(document && document.exitFullscreen){
document.body.scrollTop = 0; // 对Safari
document.documentElement.scrollTop = 0; // 对Chrome, Firefox, IE 和 Opera
document.exitFullscreen();
}
}else{ }else{
this.videoContext.requestFullScreen(); //this.videoContext.requestFullScreen();
this.fullScreenFlag=true; this.fullScreenFlag=true;
if(document.documentElement.requestFullscreen){
// document.documentElement.requestFullscreen();
}else{
window.screenTop(0)
}
uni.getSystemInfo({
success: function (info) {
_this.videoFullHeight=info.windowHeight/2 + 130;
// 你可以在这里根据窗口高度进行后续操作
}
});
} }
}, },
// // 全屏模式下,横屏+竖屏
// horizontalScreen(){
// var _this = this
// if(this.horizontalScreenFlag){
// //this.videoContext.exitFullScreen();
// this.horizontalScreenFlag=false;
// // this.videoFullHeight=190
// }else{
// //this.videoContext.requestFullScreen();
// this.horizontalScreenFlag=true;
// // uni.getSystemInfo({
// // success: function (info) {
// // _this.videoFullHeight=info.windowHeight/2 + 130;
// // // 你可以在这里根据窗口高度进行后续操作
// // }
// // });
// }
// },
// 根据秒获取时间 // 根据秒获取时间
formatSeconds(a) { formatSeconds(a) {
var hh = parseInt(a/3600); var hh = parseInt(a/3600);
@@ -161,18 +358,51 @@
}, },
// 播放进度变化时触发event.detail = {currentTime, duration} 。触发频率 250ms 一次 // 播放进度变化时触发event.detail = {currentTime, duration} 。触发频率 250ms 一次
videoUpdate(e) { videoUpdate(e) {
this.historyTime = e.detail.currentTime
let duration=this.curVideo.duration; let duration=this.curVideo.duration;
let sliderValue = e.detail.currentTime / duration * 100; let sliderValue = e.detail.currentTime / duration * 100;
let second=sliderValue / 100 * duration; let second=sliderValue / 100 * duration;
// console.log('onTimeUpdate11111::',this.drag,second)
// if(!this.drag){
// this.videoContext.seek(second);
// return;
// }
if (this.updateState) { //判断拖拽完成后才触发更新,避免拖拽失效 if (this.updateState) { //判断拖拽完成后才触发更新,避免拖拽失效
this.sliderValue=sliderValue; this.sliderValue=sliderValue;
this.$emit('progress',this.sliderValue);
}else{ }else{
} }
// alert(this.sliderValue)
this.druationTime = this.formatSeconds(duration); this.druationTime = this.formatSeconds(duration);
//console.log(this.druationTime,'this.druationTime'); //console.log(this.druationTime,'this.druationTime');
this.currtime = this.formatSeconds(second); this.currtime = this.formatSeconds(second);
this.iosCurrentTime = second;
// alert('2---this.currtime='+this.currtime)
// var time = localStorage.getItem('videoProgressData')
// //alert(1)
// if(time && !this.drag || !this.drag && !time ){
// var arr = time&&JSON.parse(time) || {}
// if(arr[this.url] < this.sliderValue/100 || !arr[this.url]){
// arr[this.url] = this.sliderValue/100
// localStorage.setItem('videoProgressData',JSON.stringify(arr))
// }
// }
// 视频播放时本地记录视频实时播放时长,视频设置了禁止拖动时执行
if(!this.drag){
var time = localStorage.getItem('videoProgressData')
var arr = time&&JSON.parse(time) || {}
if(arr[this.blobId] < this.sliderValue/100 || !arr[this.blobId]){
arr[this.blobId] = parseFloat((this.sliderValue/100).toFixed(8))
if(arr[this.blobId]) localStorage.setItem('videoProgressData',JSON.stringify(arr))
}
}
}, },
//拖动过程中触发的事件 //拖动过程中触发的事件
sliderChanging(e) { sliderChanging(e) {
@@ -183,12 +413,14 @@
sliderChange(e) { sliderChange(e) {
var duration=this.curVideo.duration; var duration=this.curVideo.duration;
var second=e.detail.value / 100 * duration; var second=e.detail.value / 100 * duration;
// alert(e.detail.value + '--slider--'+duration + '--' +second)
if (duration) { //完成拖动后,计算对应时间并跳转到指定位置 if (duration) { //完成拖动后,计算对应时间并跳转到指定位置
this.videoContext.seek(second); this.videoContext.seek(second);
this.sliderValue= e.detail.value, this.sliderValue= e.detail.value,
this.updateState= true //完成拖动后允许更新滚动条 this.updateState= true //完成拖动后允许更新滚动条
this.druationTime = this.formatSeconds(duration); this.druationTime = this.formatSeconds(duration);
this.currtime = this.formatSeconds(second); this.currtime = this.formatSeconds(second);
//alert('3---this.currtime='+this.currtime)
} }
}, },
onFullScreen(e) { onFullScreen(e) {
@@ -249,7 +481,7 @@
this.contrlShow=!this.contrlShow; this.contrlShow=!this.contrlShow;
}else{ }else{
if(!this.contrlShow){ if(!this.contrlShow){
this.contrlShow=show; this.contrlShow=true;
} }
} }
// this.onPlayerPause() // this.onPlayerPause()
@@ -294,15 +526,46 @@
this.$emit('play') this.$emit('play')
}, },
onTimeUpdate(e){ onTimeUpdate(e){
this.currtimeText = this.currtimeText + 1
this.videoUpdate(e); this.videoUpdate(e);
this.$emit('timeupdate',e) this.$emit('timeupdate',e)
}, },
/* 更新视频进度的文字显示
*/
updateProgressText() {
// console.log('updateProgressText this.videoContext::',this.videoContext,this.iosCurrentTime)
this.currentTimeFormat = this.secondTimeFormat(this.iosCurrentTime);
this.fullTimeFormat = this.secondTimeFormat(this.curVideo.duration);
},
/* 时间格式化秒格式化成xx:xx:xx
*/
secondTimeFormat(second) {
if(second<0) second = 0;
let result = parseInt(second);
let h =
Math.floor(result / 3600) < 10
? "0" + Math.floor(result / 3600)
: Math.floor(result / 3600);
let m =
Math.floor((result / 60) % 60) < 10
? "0" + Math.floor((result / 60) % 60)
: Math.floor((result / 60) % 60);
let s =
Math.floor(result % 60) < 10
? "0" + Math.floor(result % 60)
: Math.floor(result % 60);
result = `${m}:${s}`; // ${h}:
return result;
},
onPause() { onPause() {
this.playing=false; this.playing=false;
this.$emit('pause') this.$emit('pause')
}, },
onEnded(){ onEnded(){
this.playing=false; this.playing=false;
if(this.fullScreenFlag){
this.fullScreen()
}
this.$emit('ended') this.$emit('ended')
} }
} }
@@ -315,6 +578,31 @@
height: 100%; height: 100%;
position: relative; position: relative;
} }
.video-box-error{
width: 100%;
height: 110px;
padding: 55px 0;
background: #000000;
text-align: center;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.video-full-screen{
position: fixed;
width: 100vw;
height: 100vh;
background: #000000;
z-index: 9999999;
display: flex;
align-items: center;
}
.video-scree-rotate{
transform: rotate(90deg);
// width: 100vw;
// height: 100vh;
position: fixed;
}
.screen{ .screen{
position: relative; position: relative;
} }
@@ -348,11 +636,14 @@
flex:6; flex:6;
max-width:50%; max-width:50%;
} }
.slider-container.new-bar{
margin: 7px 10px 10px 10px;
}
.controller-play{ .controller-play{
width: 8%; width: 8%;
} }
.controller-screen{ .controller-screen{
width: 10%; // width: 10%;
} }
.currtime{ .currtime{
color: #ffffff; color: #ffffff;

View File

@@ -3,6 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<!-- <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" /> --> <!-- <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" /> -->
<title><%= htmlWebpackPlugin.options.title %></title> <title><%= htmlWebpackPlugin.options.title %></title>
<style type="text/css"> <style type="text/css">

View File

@@ -11,6 +11,7 @@
<view style="position: relative;"> <view style="position: relative;">
<video-player <video-player
:url="blobUrl" :url="blobUrl"
:blobId="blobId"
controls controls
:enable-play-gesture="true" :enable-play-gesture="true"
:inittime="curContent.lastStudyTime" :inittime="curContent.lastStudyTime"
@@ -20,7 +21,6 @@
@timeupdate="onPlayerPlaying" @timeupdate="onPlayerPlaying"
@fullscreenchange="onFullScreen" @fullscreenchange="onFullScreen"
:drag="curriculumData.isDrag" :drag="curriculumData.isDrag"
@progress="progress"
style="width: 100%; object-fit: fill"> style="width: 100%; object-fit: fill">
></video-player> ></video-player>
<view class="player-box" v-if="playerBoxShow"> <view class="player-box" v-if="playerBoxShow">
@@ -488,6 +488,7 @@
appentInterval:15,//追加学习时间的间隔 3秒加一次 appentInterval:15,//追加学习时间的间隔 3秒加一次
preTime:-1, preTime:-1,
blobUrl:'',//音视频的播放地址 blobUrl:'',//音视频的播放地址
blobId: '',
localTimeKey:'boeu-study-time' ,//本地存储的学习时长的key json格式 localTimeKey:'boeu-study-time' ,//本地存储的学习时长的key json格式
localTimeValue:0,//计算的时间 localTimeValue:0,//计算的时间
appendStudyOtherHandle:null, appendStudyOtherHandle:null,
@@ -495,7 +496,7 @@
scormUrl:'', scormUrl:'',
maxDuration:0, //非音频最大时长 maxDuration:0, //非音频最大时长
cumulativeDuration:0, //非音频累计时长 cumulativeDuration:0, //非音频累计时长
defaultMaxTime:1800, //非音频默认最大时间 defaultMaxTime:1800 //非音频默认最大时间
} }
}, },
computed: { computed: {
@@ -559,6 +560,7 @@
}, },
onShow(){ onShow(){
uni.setNavigationBarTitle({ title:'\u200E' }) uni.setNavigationBarTitle({ title:'\u200E' })
//实时渲染当前的播放状态 //实时渲染当前的播放状态
}, },
onReady() { onReady() {
@@ -579,6 +581,7 @@
getSysTypeTree:'sysType/getSysTypeTree', getSysTypeTree:'sysType/getSysTypeTree',
loadSysTypes:'sysType/loadSysTypes' loadSysTypes:'sysType/loadSysTypes'
}), }),
// 没有写播放时间 // 没有写播放时间
onPlayerPlay() { onPlayerPlay() {
this.playerBoxShow = false; this.playerBoxShow = false;
@@ -632,7 +635,6 @@
let $this=this; let $this=this;
uni.showLoading({title:'加载中...'}) uni.showLoading({title:'加载中...'})
apiCourseStudy.studyIndex(this.courseId).then(rs=>{ apiCourseStudy.studyIndex(this.courseId).then(rs=>{
// this.courseType = rs.result.course.type
if(rs.status != 200) { if(rs.status != 200) {
uni.hideLoading(); uni.hideLoading();
uni.showToast({title:rs.message,type:'fail'}); uni.showToast({title:rs.message,type:'fail'});
@@ -780,6 +782,26 @@
}, },
playContent(con,conIndex,catIndex){ playContent(con,conIndex,catIndex){
this.isShowPdt = true this.isShowPdt = true
// 视频设置禁用处理逻辑,如果用户已全部观看完该视频则设置为能全部拖动的逻辑把isDrag设置为true即可,同时删除本地存储的数据
if(con.progressVideo ===1){
var obj = JSON.parse(con.content)
obj.isDrag = true
con.content = JSON.stringify(obj)
var time = localStorage.getItem('videoProgressData')
var arr = time&&JSON.parse(time) || {}
//alert(con.progressVideo+'--'+con.id + '--'+JSON.stringify(arr))
delete arr[con.id];
localStorage.setItem('videoProgressData',JSON.stringify(arr))
}
if(con.progressVideo>0 && con.progressVideo !==1){
var time = localStorage.getItem('videoProgressData')
var arr = time&&JSON.parse(time) || {}
arr[con.id] = con.progressVideo
localStorage.setItem('videoProgressData',JSON.stringify(arr))
}
console.log('更换播放内容 playContent::',con,conIndex,catIndex)
//对于需要控制学习顺序的 //对于需要控制学习顺序的
if(conIndex!=undefined && catIndex!=undefined) { if(conIndex!=undefined && catIndex!=undefined) {
if(this.courseInfo.orderStudy) { if(this.courseInfo.orderStudy) {
@@ -801,6 +823,7 @@
} }
} }
} }
//切换播放内容 //切换播放内容
this.changePlayRes(con); this.changePlayRes(con);
}, },
@@ -887,7 +910,6 @@
//this.curContent=0; //this.curContent=0;
// console.log(con,'con'); // console.log(con,'con');
this.playerBoxShow=false; this.playerBoxShow=false;
this.contentTypeV = con.contentType
if(con.contentType==40){ if(con.contentType==40){
//如果是文档需要再次加载pdf //如果是文档需要再次加载pdf
if(con.content!='' && con.content.indexOf('.pdf')==-1){ if(con.content!='' && con.content.indexOf('.pdf')==-1){
@@ -939,14 +961,17 @@
location.href=this.conLink.url location.href=this.conLink.url
} }
} else if(con.contentType==10 || con.contentType==20) { } else if(con.contentType==10 || con.contentType==20) {
if(con.content.startsWith('\{')){ if(con.content.startsWith('\{')){
this.curriculumData=JSON.parse(con.content); var d = JSON.parse(con.content)
// if(d.url=="/course/2024/4/1224670812274712576.mp4") d.isDrag = false
this.curriculumData=d;
}else{ }else{
this.curriculumData.url=con.content; this.curriculumData.url=con.content;
} }
console.log('this.curriculumData:::',this.curriculumData)
this.blobUrl=this.fileBaseUrl+this.curriculumData.url; this.blobUrl=this.fileBaseUrl+this.curriculumData.url;
//console.log(this.blobUrl,'this.blobUrl'); this.blobId = con.id;
} }
//console.log(con.contentType,'con.contentType'); //console.log(con.contentType,'con.contentType');
this.curContent=con; this.curContent=con;
@@ -1309,9 +1334,6 @@
//console.log(e); //console.log(e);
this.scrollInfo = e.detail; this.scrollInfo = e.detail;
}, },
progress(val) {
this.progressData = (val).toFixed(2);
},
//以下是播放相关的处理 //以下是播放相关的处理
saveStudyDuration(duration) { //保存本地存储的学习时长 saveStudyDuration(duration) { //保存本地存储的学习时长
if (duration > 0) { if (duration > 0) {
@@ -1328,12 +1350,8 @@
"objInfo": ""+this.courseInfo.name, "objInfo": ""+this.courseInfo.name,
"aid":this.userInfo.aid, //当前登录人的id "aid":this.userInfo.aid, //当前登录人的id
"aname":this.userInfo.name,//当前人的姓名 "aname":this.userInfo.name,//当前人的姓名
"status": 1, //状态 "status": 1 //状态
"contentId": this.curContent.id,
} }
if(this.contentTypeV == 10) {
postData.progress = this.progressData
}
//静默处理 //静默处理
apiStat.sendEvent(postData).then(rs=>{ apiStat.sendEvent(postData).then(rs=>{
if(rs.status == 200) { if(rs.status == 200) {
@@ -1566,8 +1584,7 @@
let intTime=parseInt(e.detail.currentTime); let intTime=parseInt(e.detail.currentTime);
if(intTime>this.videoPlayingTime){ if(intTime>this.videoPlayingTime){
this.videoPlayingTime=intTime; this.videoPlayingTime=intTime;
//判断是否完成
//判断是否完成
let completeType=this.curriculumData.completeSetup; let completeType=this.curriculumData.completeSetup;
let completeSecond=this.curriculumData.second; let completeSecond=this.curriculumData.second;
if(!completeSecond){ if(!completeSecond){
@@ -1591,6 +1608,7 @@
//以下是每隔10秒存储一下进度 //以下是每隔10秒存储一下进度
let saveTime=Math.floor(intTime%10); let saveTime=Math.floor(intTime%10);
//console.log(intTime,saveTime,'aa',this.curContent.studyItemId) //console.log(intTime,saveTime,'aa',this.curContent.studyItemId)
console.log('3333:',this.preTime,intTime , saveTime,this.curContent.studyItemId)
if(this.preTime!=intTime && saveTime==0 && this.curContent.studyItemId!=''){ if(this.preTime!=intTime && saveTime==0 && this.curContent.studyItemId!=''){
this.preTime=intTime; this.preTime=intTime;
this.curContent.lastStudyTime=intTime; this.curContent.lastStudyTime=intTime;
@@ -1600,6 +1618,19 @@
itemId:this.curContent.studyItemId, itemId:this.curContent.studyItemId,
videoTime:intTime videoTime:intTime
} }
//alert(3+'--'+this.curriculumData.isDrag +'---'+this.curContent.progressVideo)
if(!this.curriculumData.isDrag && this.curContent.progressVideo !=1){
var time = localStorage.getItem('videoProgressData')
var arr = time&&JSON.parse(time) || {}
console.log('this.curContent.progressVideo::',arr[this.blobId],this.curContent.progressVideo,arr[this.blobId])
if(arr[this.blobId] && this.curContent.progressVideo<arr[this.blobId]) {
postData.progressVideo = arr[this.blobId]
postData.contentId = this.curContent.id
postData.courseId = this.curContent.courseId
}
}
//alert(intTime+'----'+this.videoPlayingTime)
apiCourseStudy.studyVideoTime(postData).then(rs=>{ apiCourseStudy.studyVideoTime(postData).then(rs=>{
if(rs.status!=200){ if(rs.status!=200){
console.log('记录播放时间错误'); console.log('记录播放时间错误');
@@ -1662,7 +1693,9 @@
//以下是每隔10秒存储一下进度 //以下是每隔10秒存储一下进度
let saveTime=Math.floor(intTime%10); let saveTime=Math.floor(intTime%10);
//console.log(intTime,saveTime,'aa',this.curContent.studyItemId) //console.log(intTime,saveTime,'aa',this.curContent.studyItemId)
if(this.preTime!=intTime && saveTime==0 && this.curContent.studyItemId!=''){ if(this.preTime!=intTime && saveTime==0 && this.curContent.studyItemId!=''){
this.preTime=intTime; this.preTime=intTime;
this.curContent.lastStudyTime=intTime; this.curContent.lastStudyTime=intTime;
//记录播放时间 //记录播放时间
@@ -1671,6 +1704,16 @@
itemId:this.curContent.studyItemId, itemId:this.curContent.studyItemId,
videoTime:intTime videoTime:intTime
} }
if(!this.curriculumData.isDrag && this.curContent.progressVideo !=1){
var time = localStorage.getItem('videoProgressData')
var arr = time&&JSON.parse(time) || {}
if(arr[this.blobId] && this.curContent.progressVideo<arr[this.blobId]) {
postData.progressVideo = arr[this.blobId]
postData.contentId = this.curContent.id
postData.courseId = this.curContent.courseId
}
}
//alert(this.preTime!=intTime +'---'+ saveTime +'---'+ this.curContent.studyItemId)
apiCourseStudy.studyVideoTime(postData).then(rs=>{ apiCourseStudy.studyVideoTime(postData).then(rs=>{
if(rs.status!=200){ if(rs.status!=200){
console.log('记录播放时间错误'); console.log('记录播放时间错误');