优化倍数播放
This commit is contained in:
parent
689d2017d4
commit
480225f049
|
|
@ -50,7 +50,7 @@
|
||||||
</div>
|
</div>
|
||||||
<view class="no-task" v-show="!taskList || taskList.length === 0">
|
<view class="no-task" v-show="!taskList || taskList.length === 0">
|
||||||
<view class="no-task-img">
|
<view class="no-task-img">
|
||||||
<image src="/static/eduImg/no-task.png"></image>
|
<image src="/static/eduImg/no-task.png" style="width: 179px; height: 94px;"></image>
|
||||||
<span>可联系管理员发布</span>
|
<span>可联系管理员发布</span>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
|
||||||
|
|
@ -1,97 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<div class="video">
|
|
||||||
<video
|
|
||||||
id="myVideo"
|
|
||||||
:src="videoUrl"
|
|
||||||
:initial-time="videoInitialTime"
|
|
||||||
:show-progress="false"
|
|
||||||
:enable-progress-gesture="false"
|
|
||||||
@error="videoErrorCallback"
|
|
||||||
@timeupdate="videoTimeUpdate"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<u-modal :show="showModal" title="提示" :content='content' showCancelButton @cancel="showModal = false" @confirm="handleEnd" />
|
|
||||||
|
|
||||||
<div class="btn">
|
|
||||||
<u-button type="primary" shape="circle" text="结束学习" size="small" @click="openModal" />
|
|
||||||
</div>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
states: {
|
|
||||||
type: Object,
|
|
||||||
default: () => {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
videoInitialTime: 0, // 初始播放时间
|
|
||||||
// 当前播放时间
|
|
||||||
currentTime: 0,
|
|
||||||
videoUrl: '',
|
|
||||||
content: '是否确认结束学习?',
|
|
||||||
showModal: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
console.log('🚀 ~ mounted ~ this.states:', this.states)
|
|
||||||
this.videoInitialTime = this.states.initialTime
|
|
||||||
this.videoUrl = this.states.url
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
videoErrorCallback(e) {
|
|
||||||
console.log('视频错误信息:', e)
|
|
||||||
},
|
|
||||||
// 视频播放时间更新
|
|
||||||
videoTimeUpdate(e) {
|
|
||||||
console.log('视频播放时间:', e.detail.currentTime)
|
|
||||||
this.currentTime = Math.floor(e.detail.currentTime)
|
|
||||||
},
|
|
||||||
openModal() {
|
|
||||||
this.showModal = true
|
|
||||||
},
|
|
||||||
// 结束学习
|
|
||||||
handleEnd() {
|
|
||||||
this.$verificationToken()
|
|
||||||
this.showModal = false
|
|
||||||
// 手动暂停视频
|
|
||||||
const video = uni.createVideoContext('myVideo')
|
|
||||||
video.pause()
|
|
||||||
// 获取当前播放时间 - 用于记录学习时长
|
|
||||||
console.log('当前播放时间:', this.currentTime)
|
|
||||||
this.$emit('handleVideo', this.currentTime)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
// 隐藏 video 默认控制条
|
|
||||||
::v-deep .uni-video-controls {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.video {
|
|
||||||
width: 100%;
|
|
||||||
height: 260px;
|
|
||||||
uni-video {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
margin: 60px auto;
|
|
||||||
width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .u-modal__content {
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
<template>
|
|
||||||
<view>
|
|
||||||
<VideoStudy :states="states" @handleVideo="handleVideo" />
|
|
||||||
<!-- <div class="content">
|
|
||||||
<div v-for="(item, index) in studyList" :key="index" @click="handleStudyItem(item)">
|
|
||||||
<ListItem :states="item" />
|
|
||||||
</div>
|
|
||||||
</div> -->
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import VideoStudy from './components/VideoStudy'
|
|
||||||
import ListItem from './components/ListItem'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { VideoStudy, ListItem },
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
showVideo: false,
|
|
||||||
states: {
|
|
||||||
initialTime: 70, // 初始播放时间
|
|
||||||
url: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4'
|
|
||||||
},
|
|
||||||
// 学习列表
|
|
||||||
studyList: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
// 学习标题
|
|
||||||
studyTitle: '送配电线路架设(初级)',
|
|
||||||
// 学习进度
|
|
||||||
progress: 30,
|
|
||||||
// 学习时长
|
|
||||||
duration: '00:12:00',
|
|
||||||
initialTime: 12,
|
|
||||||
url: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
studyTitle: '送配电线路架设(中级)',
|
|
||||||
progress: 50,
|
|
||||||
duration: '00:12:00',
|
|
||||||
initialTime: 12,
|
|
||||||
url: 'http://qp118.bmwae.cn/preview/file?pageCount=4&file_type=pdf&id=1117542&url=https%3A%2F%2Fbmwfileres.bmwax.cn%2Fmqrcode%2Fmqrfile%2F586413%2F1723517907_3080034644_%E6%B5%8B%E8%AF%95.pdf&preview_url=convert%2Fmqrcode%2Fmqrfile%2F586413%2F1723517907_3080034644_%E6%B5%8B%E8%AF%95&short=xmQqgA&domain=w.afbcs.cn&sign=&d=true&t=%E6%B5%8B%E8%AF%95&tips='
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
studyTitle: '送配电线路架设(高级)',
|
|
||||||
progress: 70,
|
|
||||||
duration: '00:12:00',
|
|
||||||
initialTime: 12,
|
|
||||||
url: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/2minute-demo.mp4'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
handleVideo(val) {
|
|
||||||
console.log('🚀 ~ handleVideo ~ val:', val)
|
|
||||||
this.showVideo = false
|
|
||||||
},
|
|
||||||
handleStudyItem(item) {
|
|
||||||
console.log('🚀 ~ handleStudyItem ~ item:', item, item.url.includes('.pdf'))
|
|
||||||
if (item.url.includes('.pdf')) {
|
|
||||||
uni.navigateTo({
|
|
||||||
url: '/pages/YNEduApp/learn/pdfStudy',
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.states = item
|
|
||||||
this.showVideo = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.content {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -5,10 +5,28 @@
|
||||||
id="myVideo"
|
id="myVideo"
|
||||||
:src="path"
|
:src="path"
|
||||||
:initial-time="studyDuration"
|
:initial-time="studyDuration"
|
||||||
|
:show-progress="true"
|
||||||
|
:enable-progress-gesture="false"
|
||||||
@error="videoErrorCallback"
|
@error="videoErrorCallback"
|
||||||
@timeupdate="videoTimeUpdate"
|
@timeupdate="videoTimeUpdate"
|
||||||
controls
|
controls
|
||||||
/>
|
>
|
||||||
|
<cover-view v-if="showCoverView" style="position: absolute; top: 28px; right: 20px; color: #fff; z-index: 999">
|
||||||
|
<cover-view @tap="showSwitchRate">x {{ currentRate }}</cover-view>
|
||||||
|
</cover-view>
|
||||||
|
<cover-view v-if="rateShow" class="multi-list rate" :class="{ active: rateShow }">
|
||||||
|
<cover-view
|
||||||
|
v-for="(item, index) in ['0.5', '0.8', '1.0', '1.25', '1.5']"
|
||||||
|
:key="index"
|
||||||
|
class="multi-item rate"
|
||||||
|
:data-rate="item"
|
||||||
|
@tap="switchRate"
|
||||||
|
:class="{ active: item == currentRate }"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</cover-view>
|
||||||
|
</cover-view>
|
||||||
|
</video>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<u-modal
|
<u-modal
|
||||||
|
|
@ -60,7 +78,10 @@ export default {
|
||||||
isHide: false,
|
isHide: false,
|
||||||
oldTime: 0,
|
oldTime: 0,
|
||||||
// 失败次数
|
// 失败次数
|
||||||
failCount: 3
|
failCount: 3,
|
||||||
|
rateShow: false, // 倍速浮层
|
||||||
|
currentRate: 1.0, // 默认倍速
|
||||||
|
showCoverView: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad(opt) {
|
onLoad(opt) {
|
||||||
|
|
@ -80,6 +101,9 @@ export default {
|
||||||
if (opt.isEnd) {
|
if (opt.isEnd) {
|
||||||
this.studyDuration = 0
|
this.studyDuration = 0
|
||||||
}
|
}
|
||||||
|
if (opt.isSpeed == '0') {
|
||||||
|
this.showCoverView = false
|
||||||
|
}
|
||||||
this.video = uni.createVideoContext('myVideo')
|
this.video = uni.createVideoContext('myVideo')
|
||||||
this.$verificationToken()
|
this.$verificationToken()
|
||||||
},
|
},
|
||||||
|
|
@ -98,12 +122,37 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
onFullScreenChange(e) {
|
||||||
|
console.log('🚀 ~ 全屏了 ~ e:', e)
|
||||||
|
},
|
||||||
|
// 显示倍速浮层
|
||||||
|
showSwitchRate(rate) {
|
||||||
|
let that = this
|
||||||
|
console.log('rateShow', rate)
|
||||||
|
this.$nextTick(() => {
|
||||||
|
that.rateShow = true
|
||||||
|
})
|
||||||
|
console.log('rateShow', that.rateShow)
|
||||||
|
},
|
||||||
|
// 切换倍速
|
||||||
|
switchRate(e) {
|
||||||
|
let that = this
|
||||||
|
let rate = Number(e.currentTarget.dataset.rate)
|
||||||
|
that.currentRate = rate
|
||||||
|
that.rateShow = false
|
||||||
|
this.video.playbackRate(rate)
|
||||||
|
},
|
||||||
videoErrorCallback(e) {
|
videoErrorCallback(e) {
|
||||||
console.log('视频错误信息:', e)
|
console.log('视频错误信息:', e)
|
||||||
},
|
},
|
||||||
// 视频播放时间更新
|
// 视频播放时间更新
|
||||||
videoTimeUpdate(e) {
|
videoTimeUpdate(e) {
|
||||||
let newTime = Math.ceil(e.detail.currentTime)
|
let newTime = Math.ceil(e.detail.currentTime)
|
||||||
|
if (Math.abs(newTime - this.currentTime) > 1.5) {
|
||||||
|
console.log('手动拖动了进度条,重置时间到上传播放时间')
|
||||||
|
this.video.seek(this.currentTime)
|
||||||
|
return
|
||||||
|
}
|
||||||
if (this.currentTime != newTime) {
|
if (this.currentTime != newTime) {
|
||||||
this.currentTime = newTime
|
this.currentTime = newTime
|
||||||
console.log('🚀 ~ 视频播放时间: ~ this.currentTime:', this.currentTime)
|
console.log('🚀 ~ 视频播放时间: ~ this.currentTime:', this.currentTime)
|
||||||
|
|
@ -235,10 +284,10 @@ export default {
|
||||||
} */
|
} */
|
||||||
|
|
||||||
.video {
|
.video {
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
height: 260px;
|
height: 260px;
|
||||||
uni-video {
|
uni-video {
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -248,8 +297,68 @@ export default {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep .u-modal__content {
|
/* ::v-deep .u-modal__content {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
} */
|
||||||
|
|
||||||
|
/* 以下为视频CSS */
|
||||||
|
.multi-list.full-screen.vertical {
|
||||||
|
height: 100vh !important;
|
||||||
|
padding: 8vh 0;
|
||||||
}
|
}
|
||||||
|
.multi-list.full-screen.horizontal {
|
||||||
|
height: 100vw !important;
|
||||||
|
padding: 8vw 0;
|
||||||
|
}
|
||||||
|
.multi {
|
||||||
|
position: absolute;
|
||||||
|
right: 30rpx;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
z-index: 999998;
|
||||||
|
width: 100rpx;
|
||||||
|
color: #fff;
|
||||||
|
padding: 10rpx 0;
|
||||||
|
text-align: center;
|
||||||
|
transition: color ease 0.3s;
|
||||||
|
}
|
||||||
|
.multi.rate {
|
||||||
|
right: 30rpx;
|
||||||
|
}
|
||||||
|
.multi-list {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.65);
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
transition: width 0.3s ease;
|
||||||
|
z-index: 999999;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 50rpx 0;
|
||||||
|
}
|
||||||
|
.multi-list.rate {
|
||||||
|
padding: 25rpx 0;
|
||||||
|
}
|
||||||
|
.multi-list.active {
|
||||||
|
width: 300rpx;
|
||||||
|
}
|
||||||
|
.multi-item {
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
line-height: 80rpx;
|
||||||
|
transition: color ease 0.3s;
|
||||||
|
}
|
||||||
|
.multi-item.rate {
|
||||||
|
line-height: 70rpx;
|
||||||
|
}
|
||||||
|
.multi-item:hover,
|
||||||
|
.multi:hover {
|
||||||
|
color: #00d8ff;
|
||||||
|
}
|
||||||
|
.multi-item.active {
|
||||||
|
color: #00d8ff;
|
||||||
|
}
|
||||||
|
/* 视频CSS结束 */
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -9,16 +9,6 @@
|
||||||
<div :class="{ 'tab-line': activeIndex === index }"></div>
|
<div :class="{ 'tab-line': activeIndex === index }"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <view class="status-secs">
|
|
||||||
<view
|
|
||||||
v-for="(item, index) in statusList"
|
|
||||||
:key="item.id"
|
|
||||||
:class="[{ active: totalStatus.statusCount === item.id }]"
|
|
||||||
@click="chooseStatus(item.id)"
|
|
||||||
>
|
|
||||||
{{ item.text }}
|
|
||||||
</view>
|
|
||||||
</view> -->
|
|
||||||
<uni-easyinput
|
<uni-easyinput
|
||||||
suffixIcon="search"
|
suffixIcon="search"
|
||||||
v-model="totalStatus.keyword"
|
v-model="totalStatus.keyword"
|
||||||
|
|
@ -30,7 +20,7 @@
|
||||||
<view class="project-cont">
|
<view class="project-cont">
|
||||||
<view v-for="(item, index) in projList" :key="item.id" class="single-proj" @click="toggleDetail(item.id)">
|
<view v-for="(item, index) in projList" :key="item.id" class="single-proj" @click="toggleDetail(item.id)">
|
||||||
<h4 class="img">
|
<h4 class="img">
|
||||||
<image src="/static/images/studyPro.png"></image>
|
<image src="../../../static/images/studyPro.png"></image>
|
||||||
</h4>
|
</h4>
|
||||||
<view class="proj-detail">
|
<view class="proj-detail">
|
||||||
<view class="detail-upper">
|
<view class="detail-upper">
|
||||||
|
|
@ -110,71 +100,6 @@ export default {
|
||||||
],
|
],
|
||||||
// 项目列表
|
// 项目列表
|
||||||
projList: []
|
projList: []
|
||||||
// projList: [
|
|
||||||
// {
|
|
||||||
// id: 1,
|
|
||||||
// img: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
|
|
||||||
// title: '应急抢险',
|
|
||||||
// star: 5,
|
|
||||||
// avatar: '/static/eduImg/avatar.jpg',
|
|
||||||
// user: '管理员',
|
|
||||||
// percent: 71
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 2,
|
|
||||||
// img: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
|
|
||||||
// title: '应急抢险',
|
|
||||||
// star: 3,
|
|
||||||
// avatar: '/static/eduImg/avatar.jpg',
|
|
||||||
// user: '管理员',
|
|
||||||
// percent: 33
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 3,
|
|
||||||
// img: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
|
|
||||||
// title: '应急抢险',
|
|
||||||
// star: 2,
|
|
||||||
// avatar: '/static/eduImg/avatar.jpg',
|
|
||||||
// user: '管理员',
|
|
||||||
// percent: 94
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 4,
|
|
||||||
// img: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
|
|
||||||
// title: '应急抢险',
|
|
||||||
// star: 4,
|
|
||||||
// avatar: '/static/eduImg/avatar.jpg',
|
|
||||||
// user: '管理员',
|
|
||||||
// percent: 76
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 5,
|
|
||||||
// img: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
|
|
||||||
// title: '应急抢险',
|
|
||||||
// star: 1,
|
|
||||||
// avatar: '/static/eduImg/avatar.jpg',
|
|
||||||
// user: '管理员',
|
|
||||||
// percent: 63
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 6,
|
|
||||||
// img: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
|
|
||||||
// title: '应急抢险',
|
|
||||||
// star: 5,
|
|
||||||
// avatar: '/static/eduImg/avatar.jpg',
|
|
||||||
// user: '管理员',
|
|
||||||
// percent: 52
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// id: 7,
|
|
||||||
// img: 'https://cdn.uviewui.com/uview/swiper/1.jpg',
|
|
||||||
// title: '应急抢险',
|
|
||||||
// star: 4,
|
|
||||||
// avatar: '/static/eduImg/avatar.jpg',
|
|
||||||
// user: '管理员',
|
|
||||||
// percent: 18
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,8 @@ export default {
|
||||||
eligibility: 0,
|
eligibility: 0,
|
||||||
learnIconObj: { color: '#1A63AC', size: '18', type: 'calendar' },
|
learnIconObj: { color: '#1A63AC', size: '18', type: 'calendar' },
|
||||||
pracIconObj: { color: '#38B022', size: '18', type: 'compose' },
|
pracIconObj: { color: '#38B022', size: '18', type: 'compose' },
|
||||||
listStage: []
|
listStage: [],
|
||||||
|
isSpeed: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLoad(params) {
|
onLoad(params) {
|
||||||
|
|
@ -188,6 +189,7 @@ export default {
|
||||||
this.listStageContentNum = res.data.listStageContentNum
|
this.listStageContentNum = res.data.listStageContentNum
|
||||||
this.eligibility = res.data.eligibility
|
this.eligibility = res.data.eligibility
|
||||||
this.listStage = res.data.listStage
|
this.listStage = res.data.listStage
|
||||||
|
this.isSpeed = res.data.isSpeed
|
||||||
if (this.listStage.length > 0) {
|
if (this.listStage.length > 0) {
|
||||||
this.listStage.forEach((item, index) => {
|
this.listStage.forEach((item, index) => {
|
||||||
this.$set(item, 'isShow', true)
|
this.$set(item, 'isShow', true)
|
||||||
|
|
@ -210,7 +212,8 @@ export default {
|
||||||
path: item.path, // 视频路径
|
path: item.path, // 视频路径
|
||||||
studyDuration: item.studyDuration || 0, // 学习时长
|
studyDuration: item.studyDuration || 0, // 学习时长
|
||||||
allStudyDuration: item.allStudyDuration, // 总时长
|
allStudyDuration: item.allStudyDuration, // 总时长
|
||||||
isEnd: item.studyPercentage >= 100 ? true : false
|
isEnd: item.studyPercentage >= 100 ? true : false,
|
||||||
|
isSpeed: this.isSpeed
|
||||||
}
|
}
|
||||||
console.log('🚀 ~ toggleTheoryLearn ~ params:', params)
|
console.log('🚀 ~ toggleTheoryLearn ~ params:', params)
|
||||||
console.log('🚀 ~ toggleTheoryLearn ~ item:', item.path)
|
console.log('🚀 ~ toggleTheoryLearn ~ item:', item.path)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue