<template>
|
<view class="wrap">
|
<view class="top_head pr">
|
<view class="t-head-l"></view>
|
<view style="text-align: center">课程</view>
|
<view class="t-head-r" @click="goBack">返回</view>
|
</view>
|
|
<view class="videoWrap">
|
<view class="videoBox">
|
<!-- <template v-if="!videoPause">-->
|
<!-- <view class="masterPic">-->
|
<!-- <image class="img" :src="videoCover" mode="scaleToFill"></image>-->
|
<!-- </view>-->
|
<!-- <image class="startIcon" src="/static/image/bofang.png" mode="scaleToFill" @click="startFirstVideo"></image>-->
|
<!-- </template>-->
|
<!-- <template v-else>-->
|
<view class="video-js" ref="video" style="width: 100%;height: 100%;"></view>
|
<!-- </template>-->
|
</view>
|
<view class="viden-info" v-if="showDetail">
|
<view class="viden-info-t">{{detail.name}}</view>
|
<view class="viden-info-i">创建时间:{{detail.createTime}}</view>
|
</view>
|
</view>
|
<view class="d-e-c p-0-20">
|
<view class="chapterList">
|
<view class="chapterItem" v-for="(item,index) in courseList" :key="index">
|
<view class="chapterName">{{item.chapterName }}</view>
|
<view class="courseList">
|
<view class="courseItem" :class="{ selected: i.periodId === selectedPeriodId }" v-for="(i,idx) in item.studentStudyPeriodVOList" :key="idx" @click="getCourseDetail(i.periodId)">
|
<view>
|
<up-icon name="play-circle" :color="i.periodId == selectedPeriodId?'#fff':'#007aff'" size="24" style="margin-left: 0"></up-icon>
|
<view>{{i.periodName}}</view>
|
</view>
|
<span>{{secondsToHms(i.period)}}</span>
|
</view>
|
</view>
|
</view>
|
</view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
import utils from '@/common/utils.js';
|
import Videojs from 'video.js'
|
import 'video.js/dist/video-js.min.css'
|
import cover from '../../../static/image/index/swiperPic.png'
|
export default {
|
components: {
|
},
|
data() {
|
return {
|
videoCover: cover,
|
showDetail: false,
|
section_id: null,
|
course_id: null,
|
phaseId: null,
|
selectedPeriodId: null,
|
courseList: [],
|
course: {},
|
detail: {},
|
videoBaseUrl: 'http://192.168.2.16:9000/trainexam/',
|
status: false,
|
beforeAudio: true,
|
duration: 0,
|
progress: 0,
|
xpjAudio: null,
|
videoPause: false,
|
removeArea:{
|
x: 0,
|
y: 0,
|
}
|
};
|
},
|
onReady(){
|
|
},
|
onLoad(e) {
|
this.phaseId = e.phase_id
|
this.getSystemInfo();
|
|
},
|
onShow(){
|
|
},
|
mounted() {
|
// this.getData();
|
},
|
computed: {
|
|
},
|
beforeUnmount() {
|
if (this.player) {
|
this.player.dispose()
|
}
|
},
|
|
beforeDestroy() {
|
if (this.player) {
|
this.player.dispose()
|
}
|
},
|
|
methods: {
|
getSystemInfo(){
|
let self = this;
|
uni.getSystemInfo({
|
success(res) {
|
self.removeArea.x = res.windowWidth - 70;
|
self.removeArea.y = res.windowHeight - 120;
|
}
|
});
|
},
|
|
/*获取数据*/
|
getData() {
|
let self = this;
|
uni.showLoading({
|
title: '加载中'
|
});
|
self._get(
|
'/api/app/phase-student/getPhaseStudentById', {
|
phaseStudentId: self.phaseId,
|
},
|
function (res) {
|
self.courseList = res.data
|
let id = self.courseList[0].studentStudyPeriodVOList[0].periodId
|
if(id){
|
self.getCourseDetail(id)
|
}
|
uni.hideLoading();
|
},
|
function (err) {
|
|
}
|
);
|
},
|
|
getCourseDetail(id){
|
let self = this;
|
self.selectedPeriodId = id;
|
self.showDetail = true
|
uni.showLoading({
|
title: '加载中'
|
});
|
self._get(
|
'/api/app/resource/getResourceByPeriod', {
|
periodId: id,
|
},
|
function (res) {
|
self.detail = res.data
|
let videoElement = document.getElementById('video');
|
if (videoElement) {
|
videoElement.parentNode.removeChild(videoElement);
|
}
|
self.initVideo(self.videoBaseUrl + self.detail.resourcePath)
|
// self.startVideo(self.videoBaseUrl + self.detail.resourcePath)
|
uni.hideLoading();
|
},
|
function (err) {
|
|
}
|
);
|
},
|
|
goBack(){
|
uni.navigateBack({
|
delta: 1
|
});
|
},
|
|
initVideo(path){
|
let video = document.createElement('video');
|
video.id = 'video';
|
video.style = 'width: 100%; height: 100%;';
|
video.controls = true;
|
video.preload="auto"
|
video.setAttribute('playsinline', true) //IOS微信浏览器支持小窗内播放
|
video.setAttribute('webkit-playsinline', true) //这个bai属性是ios 10中设置可以让视频在小du窗内播放,也就是不是全zhi屏播放的video标签的一个属性
|
video.setAttribute('x5-video-player-type', 'h5') //安卓 声明启用同层H5播放器 可以在video上面加东西
|
let source = document.createElement('source');
|
source.src = path
|
// source.type = 'application/x-mpegURL';
|
video.appendChild(source);
|
this.$refs.video.$el.appendChild(video);
|
let that = this;
|
that.player = Videojs('video', {
|
poster: '', // 视频封面图地址
|
title:'4564564',
|
playbackRates: [0.7, 1.0, 1.5, 2.0], //播放速度
|
autoDisable: true,
|
preload: 'none', //auto - 当页面加载后载入整个视频 meta - 当页面加载后只载入元数据 none - 当页面加载后不载入视频
|
language: 'zh-CN',
|
fluid: true, // 自适应宽高
|
muted: false, // 是否静音
|
aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")
|
controls: true, //是否拥有控制条 【默认true】,如果设为false ,那么只能通过api进行控制了。也就是说界面上不会出现任何控制按钮
|
autoplay: "muted", //如果true,浏览器准备好时开始回放。 autoplay: "muted", // //自动播放属性,muted:静音播放
|
loop: true, // 导致视频一结束就重新开始。 视频播放结束后,是否循环播放
|
screenshot:true,
|
controlBar: {
|
volumePanel: { //声音样式
|
inline: false // 不使用水平方式
|
},
|
timeDivider: true, // 时间分割线
|
durationDisplay: true, // 总时间
|
progressControl: true, // 进度条
|
remainingTimeDisplay: true, //当前以播放时间
|
fullscreenToggle: true, //全屏按钮
|
pictureInPictureToggle: true, //画中画
|
}
|
}, function() {
|
this.on('error', function(err) { //请求数据时遇到错误
|
console.log("请求数据时遇到错误",err)
|
});
|
this.on('stalled', function(stalled) { //网速失速
|
console.log("网速失速",stalled)
|
});
|
this.on('play', function() { //开始播放
|
console.log("开始播放")
|
});
|
this.on('pause', function() { //暂停
|
console.log("暂停")
|
});
|
this.on('timeupdate', function(timeupdate) {
|
// console.log(timeupdate)
|
})
|
});
|
},
|
|
startVideo(videoPath){
|
console.log(videoPath,'path')
|
this.player.src({
|
src: videoPath,
|
type: 'application/x-mpegURL'
|
})
|
// this.player.load()
|
},
|
|
startFirstVideo(){
|
let id = this.courseList[0].studentStudyPeriodVOList[0].periodId
|
if(id){
|
this.getCourseDetail(id)
|
}else{
|
uni.$u.toast('暂无可播放视频内容')
|
}
|
},
|
|
secondsToHms(seconds) {
|
seconds = Number(seconds);
|
const h = Math.floor(seconds / 3600);
|
const m = Math.floor(seconds % 3600 / 60);
|
const s = Math.floor(seconds % 3600 % 60);
|
|
const hDisplay = h > 0 ? String(h).padStart(2, '0') : '00';
|
const mDisplay = m > 0 ? String(m).padStart(2, '0') : '00';
|
const sDisplay = s > 0 ? String(s).padStart(2, '0') : '00';
|
return `${hDisplay}:${mDisplay}:${sDisplay}`;
|
},
|
|
changeSwiper() {
|
this.isVideoPlay = false;
|
},
|
formatTime(num) {
|
num = Math.floor(num)
|
let second = num % 60;
|
if (second < 10) second = '0' + second;
|
let min = Math.floor(num / 60);
|
if (min < 10) min = '0' + min;
|
return min + ":" + second;
|
},
|
}
|
};
|
</script>
|
|
<style lang="scss" scoped>
|
.top_head {
|
height: 40px;
|
line-height: 40px;
|
position: sticky;
|
top: 0;
|
left: 0;
|
z-index: 100;
|
background: #fff;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
.t-head-l{
|
width: 100px;
|
}
|
.t-head-r{
|
width: 100px;
|
text-align: center;
|
height: 40px;
|
line-height: 40px;
|
color: #666;
|
margin: 0;
|
}
|
}
|
|
.videoWrap {
|
background: #fff;
|
|
.videoBox {
|
width: 100%;
|
height: 260px;
|
position: relative;
|
|
.masterPic {
|
width: 100%;
|
height: 100%;
|
|
&::before {
|
content: "";
|
position: absolute;
|
top: 0;
|
left: 0;
|
background: rgb(0, 0, 0, 0.45);
|
width: 100%;
|
height: 100%;
|
z-index: 1;
|
}
|
|
.img {
|
width: 100%;
|
height: 100%;
|
}
|
}
|
|
.startIcon {
|
position: absolute;
|
left: 50%;
|
top: 50%;
|
transform: translate(-50%, -50%);
|
width: 92rpx;
|
height: 92rpx;
|
z-index: 10;
|
}
|
.videoPlayer-dimensions.vjs-fluid:not(.vjs-audio-only-mode){
|
padding: 0;
|
}
|
}
|
|
.viden-info{
|
padding: 15px;
|
box-sizing: border-box;
|
|
.viden-info-t{
|
font-size: 28rpx;
|
font-weight: bold;
|
color: #007aff;
|
margin-bottom: 10px;
|
}
|
|
.viden-info-i{
|
color: #999;
|
}
|
}
|
}
|
|
.chapterList{
|
width: 100%;
|
background: #fff;
|
border-radius: 8px;
|
margin: 20px 0;
|
padding: 15px;
|
box-sizing: border-box;
|
|
.chapterItem{
|
padding-bottom: 15px;
|
margin-bottom: 15px;
|
border-bottom: 1px solid #f0f0f0;
|
box-sizing: border-box;
|
&:last-of-type{
|
margin-bottom: 0;
|
padding-bottom: 0;
|
border-bottom: none;
|
}
|
|
.chapterName{
|
font-size: 32rpx;
|
font-weight: bolder;
|
margin-bottom: 30rpx;
|
}
|
|
.courseList{
|
|
.courseItem{
|
height: 44rpx;
|
padding: 10px;
|
background: #f5f5f5;
|
border-radius: 4rpx;
|
margin-bottom: 10px;
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
|
&>view{
|
display: flex;
|
align-items: center;
|
view{
|
font-size: 28rpx;
|
line-height: 44rpx;
|
margin-left: 10px;
|
}
|
}
|
|
}
|
.selected{
|
background: #007aff;
|
color: #fff;
|
}
|
}
|
}
|
}
|
</style>
|