442 lines
18 KiB
HTML
442 lines
18 KiB
HTML
<!--#
|
|
layout("/layouts/platform.html"){
|
|
#-->
|
|
|
|
<script src="https://cdn-go.cn/cdn/vod-js-sdk-v6/latest/vod-js-sdk-v6.js"></script>
|
|
<link href="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/tcplayer.min.css" rel="stylesheet"/>
|
|
<!--如果需要在 Chrome 和 Firefox 等现代浏览器中通过 H5 播放 HLS 格式的视频,需要在 tcplayer.vx.x.x.min.js 之前引入 hls.min.x.xx.xm.js。-->
|
|
<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/libs/hls.min.0.13.2m.js"></script>
|
|
<!--播放器脚本文件-->
|
|
<script src="https://web.sdk.qcloud.com/player/tcplayer/release/v4.3.0/tcplayer.v4.3.0.min.js"></script>
|
|
|
|
<style>
|
|
|
|
.el-tag {
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.el-image {
|
|
display: inherit;
|
|
border-radius: 10px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.hitv_horizontal-txtbox {
|
|
height: 52px;
|
|
padding-top: 4px;
|
|
cursor: pointer;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.hitv_horizontal-title {
|
|
line-height: 20px;
|
|
height: auto;
|
|
display: -webkit-box;
|
|
overflow: hidden;
|
|
-o-text-overflow: ellipsis;
|
|
text-overflow: ellipsis;
|
|
-webkit-line-clamp: 1;
|
|
-webkit-box-orient: vertical;
|
|
width: 200px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.hitv_horizontal-desc {
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
overflow: hidden;
|
|
zoom: 1;
|
|
color: #999;
|
|
width: 200px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
p {
|
|
margin: 0;
|
|
}
|
|
|
|
div img {
|
|
width: 100%;
|
|
height: 100%;
|
|
transition: all 0.6s;
|
|
cursor: pointer;
|
|
}
|
|
|
|
div img:hover {
|
|
transform: scale(1.3);
|
|
}
|
|
|
|
.title {
|
|
color: #222;
|
|
}
|
|
|
|
.select-video {
|
|
color: #1867b0 !important;
|
|
}
|
|
|
|
|
|
.info:hover .title {
|
|
color: #236eb4;
|
|
}
|
|
|
|
.video {
|
|
height: calc(100vh - 50px - 20px - 54px - 40px);
|
|
width: 100%;
|
|
}
|
|
|
|
.video_list {
|
|
height: calc(100vh - 50px - 20px - 54px - 40px);
|
|
overflow: auto;
|
|
}
|
|
|
|
.name {
|
|
font-size: 13px;
|
|
color: grey;
|
|
}
|
|
|
|
.video_div {
|
|
height: calc(100vh - 20px - 85px - 20px - 60px - 40px - 32px - 15px);
|
|
overflow: auto;
|
|
}
|
|
|
|
</style>
|
|
|
|
<div id="app" v-cloak>
|
|
|
|
<guava ref="guava" v-model="guavaIndex">
|
|
|
|
<el-card shadow="never">
|
|
<div class="btn-group tool-button mt5">
|
|
<el-input @keyup.enter.native="doSearch" clearable placeholder="请输入内容"
|
|
v-model="pageForm.searchKeyword"></el-input>
|
|
</div>
|
|
|
|
<div class="btn-group tool-button mt5">
|
|
<el-button type="primary" icon="el-icon-search" @click="doSearch">搜索</el-button>
|
|
</div>
|
|
</el-card>
|
|
|
|
<el-card shadow="never" class="mt20">
|
|
<div>
|
|
<el-tag :effect="pageForm.typeId === item.id ? 'dark':'light'" @click="typeClick(item)"
|
|
v-for="item in typeList">{{item.typeName}}
|
|
</el-tag>
|
|
</div>
|
|
<div class="demo-image__placeholder mt20 video_div"
|
|
:infinite-scroll-disabled="scrollDisabled"
|
|
v-infinite-scroll="load">
|
|
<div @click="goPlayPage(item.id)" class="info mr25 mb10" style="display: inline-block"
|
|
v-for="item in albumList">
|
|
<el-image style="width: 200px; height: 130px"
|
|
:src="APP_DOMAIN+FILE_STREAM_PREVIEW_ADDRESS+'?id='+item.cover"
|
|
lazy>
|
|
</el-image>
|
|
<div class="hitv_horizontal-txtbox">
|
|
<p class="hitv_horizontal-title">
|
|
<a class="title">{{item.title}}</a>
|
|
</p>
|
|
<p class="hitv_horizontal-desc" v-html="item.description">
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-card>
|
|
|
|
<template #view>
|
|
<el-row :gutter="20">
|
|
<el-col :span="18">
|
|
<div id="el-col-video">
|
|
<video :id="'player-container-id'+albumId" class="video" height="600" playsinline preload="auto"
|
|
webkit-playsinline>
|
|
</video>
|
|
</div>
|
|
|
|
<div>
|
|
title
|
|
description
|
|
</div>
|
|
</el-col>
|
|
<el-col :span="6" class="video_list">
|
|
<div @click="playVideo(item)" style="margin-bottom: 20px; display: flex;"
|
|
v-for="item in videoList">
|
|
<div>
|
|
<el-image style="width: 160px; height: 100px; margin-right: 10px"
|
|
:src="item.coverUrl"
|
|
lazy>
|
|
</el-image>
|
|
</div>
|
|
|
|
<div>
|
|
<a :class="currentPlayVideo.id === item.id ? 'select-video':''"
|
|
class="title">{{item.title}}</a>
|
|
<div class="upname">
|
|
<div>
|
|
<svg height="16" style="position: relative; top: 3px" viewBox="0 0 18 16" width="18"
|
|
xmlns="http://www.w3.org/2000/svg">
|
|
<path clip-rule="evenodd"
|
|
d="M9 2.0625C6.85812 2.0625 4.98983 2.1725 3.67735 2.2798C2.77861 2.35327 2.08174 3.04067 2.00119 3.93221C1.90388 5.00924 1.8125 6.43727 1.8125 8C1.8125 9.56273 1.90388 10.9908 2.00119 12.0678C2.08174 12.9593 2.77861 13.6467 3.67735 13.7202C4.98983 13.8275 6.85812 13.9375 9 13.9375C11.1421 13.9375 13.0105 13.8275 14.323 13.7202C15.2216 13.6467 15.9184 12.9595 15.9989 12.0682C16.0962 10.9916 16.1875 9.56386 16.1875 8C16.1875 6.43614 16.0962 5.00837 15.9989 3.9318C15.9184 3.04049 15.2216 2.3533 14.323 2.27983C13.0105 2.17252 11.1421 2.0625 9 2.0625ZM3.5755 1.03395C4.9136 0.924562 6.81674 0.8125 9 0.8125C11.1835 0.8125 13.0868 0.924583 14.4249 1.03398C15.9228 1.15645 17.108 2.31588 17.2438 3.81931C17.3435 4.92296 17.4375 6.38948 17.4375 8C17.4375 9.61052 17.3435 11.077 17.2438 12.1807C17.108 13.6841 15.9228 14.8436 14.4249 14.966C13.0868 15.0754 11.1835 15.1875 9 15.1875C6.81674 15.1875 4.9136 15.0754 3.5755 14.966C2.07738 14.8436 0.892104 13.6838 0.756256 12.1803C0.656505 11.0762 0.5625 9.60942 0.5625 8C0.5625 6.39058 0.656505 4.92379 0.756257 3.81973C0.892104 2.31616 2.07738 1.15643 3.5755 1.03395ZM4.41663 4.93726C4.72729 4.93726 4.97913 5.1891 4.97913 5.49976V8.62476C4.97913 9.34963 5.56675 9.93726 6.29163 9.93726C7.0165 9.93726 7.60413 9.34963 7.60413 8.62476V5.49976C7.60413 5.1891 7.85597 4.93726 8.16663 4.93726C8.47729 4.93726 8.72913 5.1891 8.72913 5.49976V8.62476C8.72913 9.97095 7.63782 11.0623 6.29163 11.0623C4.94543 11.0623 3.85413 9.97095 3.85413 8.62476V5.49976C3.85413 5.1891 4.10597 4.93726 4.41663 4.93726ZM10.2501 4.93726C9.9394 4.93726 9.68756 5.1891 9.68756 5.49976V10.4998C9.68756 10.8104 9.9394 11.0623 10.2501 11.0623C10.5607 11.0623 10.8126 10.8104 10.8126 10.4998V9.60392H12.2292C13.5179 9.60392 14.5626 8.55925 14.5626 7.27059C14.5626 5.98193 13.5179 4.93726 12.2292 4.93726H10.2501ZM12.2292 8.47892H10.8126V6.06226H12.2292C12.8966 6.06226 13.4376 6.60325 13.4376 7.27059C13.4376 7.93793 12.8966 8.47892 12.2292 8.47892Z"
|
|
fill-rule="evenodd"></path>
|
|
</svg>
|
|
<span :class="currentPlayVideo.id === item.id ? 'select-video':''" class="name">{{item.title}}</span>
|
|
</div>
|
|
<div>
|
|
<svg class="icon" height="16" p-id="2411" style="position: relative; top: 3px"
|
|
t="1660188268757" version="1.1" viewBox="0 0 1024 1024"
|
|
width="18" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M511.913993 63.989249c-247.012263 0-447.924744 200.912481-447.924744 447.924744s200.912481 447.924744 447.924744 447.924744 447.924744-200.912481 447.924744-447.924744S758.926256 63.989249 511.913993 63.989249zM511.913993 895.677474c-211.577356 0-383.763481-172.186125-383.763481-383.763481 0-211.577356 172.014111-383.763481 383.763481-383.763481s383.763481 172.014111 383.763481 383.763481S723.491349 895.677474 511.913993 895.677474z"
|
|
p-id="2412"></path>
|
|
<path d="M672.05913 511.913993l-159.973123 0L512.086007 288.123635c0-17.717453-14.277171-32.166639-31.994625-32.166639-17.717453 0-31.994625 14.449185-31.994625 32.166639l0 255.956996c0 17.717453 14.277171 31.994625 31.994625 31.994625l191.967747 0c17.717453 0 32.166639-14.277171 32.166639-31.994625C704.053754 526.191164 689.604569 511.913993 672.05913 511.913993z"
|
|
p-id="2413"></path>
|
|
</svg>
|
|
<span :class="currentPlayVideo.id === item.id ? 'select-video':''" class="name">{{formatSeconds(item.fileDuration)}}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</el-col>
|
|
</el-row>
|
|
</template>
|
|
|
|
</guava>
|
|
|
|
</div>
|
|
|
|
|
|
<script>
|
|
let player = null
|
|
|
|
var vue = new Vue({
|
|
el: '#app',
|
|
mixins: [initTableMixins],
|
|
data() {
|
|
return {
|
|
typeList: [],
|
|
albumList: [],
|
|
videoList: [],
|
|
pageForm: {
|
|
typeId: null,
|
|
pageSize: 30
|
|
},
|
|
currentPlayVideo: {},
|
|
watchRecordList: [],
|
|
guavaIndex: null,
|
|
albumId: null,
|
|
scrollDisabled: false,
|
|
}
|
|
},
|
|
computed: {
|
|
scrollDisabled() {
|
|
return this.pageForm.totalCount === this.albumList.length
|
|
}
|
|
},
|
|
watch: {
|
|
async guavaIndex(val) {
|
|
if (val === 'index' && player) {
|
|
console.log('xxx')
|
|
player.dispose()
|
|
player = null
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
doSearch() {
|
|
this.albumList = []
|
|
this.pageForm.pageNumber = 1
|
|
this.load()
|
|
},
|
|
async typeClick(item) {
|
|
if (this.pageForm.typeId === item.id) return
|
|
this.pageForm.typeId = item.id
|
|
this.pageForm.pageNumber = 1
|
|
this.albumList = []
|
|
await this.getAlbum()
|
|
},
|
|
//获取专辑
|
|
async load() {
|
|
this.scrollDisabled = true
|
|
await this.getAlbum()
|
|
},
|
|
async getAlbum() {
|
|
const resp = await $.get('/platform/trainEdu/album/getAlbumByTypeId', this.pageForm)
|
|
if (resp.code === 0) {
|
|
if (resp.data.list.length > 0) {
|
|
if (this.scrollDisabled === false) {
|
|
this.albumList = this.albumList.concat(resp.data.list)
|
|
} else {
|
|
this.albumList = resp.data.list
|
|
}
|
|
this.pageForm.totalCount = resp.data.totalCount
|
|
this.pageForm.pageNumber = this.pageForm.pageNumber + 1
|
|
} else {
|
|
this.noMore = true
|
|
}
|
|
}
|
|
},
|
|
async goPlayPage(albumId) {
|
|
this.$refs.guava.view()
|
|
this.albumId = albumId
|
|
this.$nextTick(() => {
|
|
if (!player) {
|
|
const videoTag = document.getElementById('player-container-id' + albumId)
|
|
if (!videoTag) {
|
|
const videoStr = "<video class='video' id='player-container-id" + albumId + "'" + "height='600' preload='auto' playsinline webkit-playsinline></video>"
|
|
document.getElementById('el-col-video').insertAdjacentHTML('beforeend', videoStr)
|
|
}
|
|
player = TCPlayer('player-container-id' + albumId, {})
|
|
}
|
|
})
|
|
const resp = await $.get('/platform/trainEdu/video/getVideoList', {albumId})
|
|
if (resp.code === 0) {
|
|
this.videoList = resp.data
|
|
const currentVideo = this.videoList[0]
|
|
|
|
this.currentPlayVideo = currentVideo
|
|
if (currentVideo) {
|
|
player.src(currentVideo.mediaUrl)
|
|
const v = this.watchRecordList.find(v => v.videoId === currentVideo.id)
|
|
if (v) {
|
|
player.currentTime(v.watchDuration)
|
|
}
|
|
this.playTimeUpdate()
|
|
}
|
|
} else {
|
|
this.notifyWarning(resp.msg)
|
|
}
|
|
},
|
|
async playVideo(item) {
|
|
|
|
this.currentPlayVideo = item
|
|
player.src(item.mediaUrl)
|
|
await this.getMyWatchRecord()
|
|
|
|
//接着上次继续看
|
|
const v = this.watchRecordList.find(v => v.videoId === item.id)
|
|
if (v) {
|
|
this.lastTime = v.watchDuration
|
|
setTimeout(() => {
|
|
player.currentTime(v.watchDuration)
|
|
})
|
|
} else {
|
|
player.currentTime(0)
|
|
await this.addWatchRecord()
|
|
await this.getMyWatchRecord()
|
|
}
|
|
|
|
// player.play()
|
|
this.playPause()
|
|
this.playEnd()
|
|
this.playTimeUpdate()
|
|
this.playSeeked()
|
|
},
|
|
|
|
playPlay() {
|
|
player.on('play', () => {
|
|
this.lastTime = player.currentTime()
|
|
this.addWatchRecord()
|
|
})
|
|
},
|
|
|
|
//快进 快退
|
|
playSeeked() {
|
|
player.on('seeked', () => {
|
|
this.lastTime = player.currentTime()
|
|
this.addWatchRecord()
|
|
})
|
|
},
|
|
playTimeUpdate() {
|
|
this.lastTime = player.currentTime()
|
|
player.on('timeupdate', () => {
|
|
const nowTime = player.currentTime()
|
|
if (nowTime - this.lastTime > 5) {
|
|
this.lastTime = nowTime
|
|
this.addWatchRecord()
|
|
}
|
|
})
|
|
},
|
|
playPause() {
|
|
player.on('pause', () => {
|
|
this.addWatchRecord()
|
|
})
|
|
},
|
|
|
|
playEnd() {
|
|
player.on('ended', () => {
|
|
this.addWatchRecord()
|
|
this.getMyWatchRecord()
|
|
const currentIndex = this.videoList.findIndex(v => v.id === this.currentVideo.id)
|
|
const nextVideo = this.videoList[currentIndex + 1]
|
|
if (nextVideo) {
|
|
this.playVideo(nextVideo)
|
|
}
|
|
})
|
|
},
|
|
|
|
async getVideoType() {
|
|
const resp = await $.get('/platform/trainEdu/type/pageData', {pageForm: 1, pageSize: 10000})
|
|
if (resp.code === 0) {
|
|
this.typeList = resp.data.list
|
|
}
|
|
},
|
|
formatSeconds(value) {
|
|
let secondTime = parseInt(value);// 秒
|
|
let minuteTime = 0;// 分
|
|
let hourTime = 0;// 小时
|
|
if (secondTime > 60) {//如果秒数大于60,将秒数转换成整数
|
|
//获取分钟,除以60取整数,得到整数分钟
|
|
minuteTime = parseInt(secondTime / 60);
|
|
//获取秒数,秒数取佘,得到整数秒数
|
|
secondTime = parseInt(secondTime % 60);
|
|
//如果分钟大于60,将分钟转换成小时
|
|
if (minuteTime > 60) {
|
|
//获取小时,获取分钟除以60,得到整数小时
|
|
hourTime = parseInt(minuteTime / 60);
|
|
//获取小时后取佘的分,获取分钟除以60取佘的分
|
|
minuteTime = parseInt(minuteTime % 60);
|
|
}
|
|
}
|
|
let result = "" + parseInt(secondTime) + "秒";
|
|
|
|
if (minuteTime > 0) {
|
|
result = "" + parseInt(minuteTime) + "分" + result;
|
|
}
|
|
if (hourTime > 0) {
|
|
result = "" + parseInt(hourTime) + "小时" + result;
|
|
}
|
|
return result;
|
|
},
|
|
|
|
//监听页面关闭 隐藏
|
|
watchPage() {
|
|
document.addEventListener('visibilitychange', () => {
|
|
if (document.visibilityState === 'hidden') {
|
|
if (player && this.currentPlayVideo) {
|
|
this.addWatchRecord()
|
|
}
|
|
}
|
|
})
|
|
},
|
|
async addWatchRecord() {
|
|
const params = {
|
|
videoId: this.currentPlayVideo.id,
|
|
currentTime: parseInt(player.currentTime()),
|
|
albumId: this.currentPlayVideo.albumId
|
|
}
|
|
await $.post('/mobile/trainEducation/addWatchRecord', params)
|
|
},
|
|
async getMyWatchRecord() {
|
|
const {data} = await $.get('/mobile/trainEducation/getMyWatchRecord')
|
|
this.watchRecordList = data
|
|
},
|
|
|
|
|
|
},
|
|
async created() {
|
|
await this.getVideoType()
|
|
await this.getMyWatchRecord()
|
|
}
|
|
})
|
|
</script>
|
|
|
|
<!--#
|
|
}
|
|
#--> |