|
@@ -4,8 +4,22 @@
|
|
|
* @Date:2024-04-03 17:31:41
|
|
|
-->
|
|
|
<template>
|
|
|
- <div class="coursewarePlay">
|
|
|
- <videoPlay ref="videoPlayDom" @ended="handleChangeCourseware(1)" :disableEvents="true" />
|
|
|
+ <div class="coursewarePlay" :class="{ hideController: !isShowController }">
|
|
|
+ <div class="coursewarePlayCon" @mousemove="handleMousemove" @click="handleClick">
|
|
|
+ <videoPlay
|
|
|
+ v-show="fileType === 'VIDEO'"
|
|
|
+ ref="videoPlayDom"
|
|
|
+ @ended="handleChangeCourseware(1)"
|
|
|
+ :disableEvents="true"
|
|
|
+ :isShowController="isShowController"
|
|
|
+ />
|
|
|
+ <div class="imgPlayBox" v-if="fileType === 'IMG'">
|
|
|
+ <ElImage :hide-on-click-modal="true" fit="contain" :src="activeCourseware?.content" class="imgPlay" />
|
|
|
+ </div>
|
|
|
+ <div class="songPlayBox" v-if="fileType === 'SONG'">
|
|
|
+ <iframe class="songIframe" @mousemove="handleMousemove" :src="songPlaySrc" frameborder="0"></iframe>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
<div class="leftTools posTools">
|
|
|
<div v-if="activeCoursewareIndex > 0" class="posBtn" @click="handleChangeCourseware(-1)">
|
|
|
<img src="@/img/coursewarePlay/shang.png" />
|
|
@@ -21,7 +35,7 @@
|
|
|
class="posBtn"
|
|
|
@click="
|
|
|
() => {
|
|
|
- videoPlayDom?.pauseVideo()
|
|
|
+ handleVideoPause()
|
|
|
whitePenShow = true
|
|
|
}
|
|
|
"
|
|
@@ -33,7 +47,7 @@
|
|
|
class="posBtn"
|
|
|
@click="
|
|
|
() => {
|
|
|
- videoPlayDom?.pauseVideo()
|
|
|
+ handleVideoPause()
|
|
|
penShow = true
|
|
|
}
|
|
|
"
|
|
@@ -99,13 +113,15 @@ import { checkWebCourse_gyt } from "@/api/coursewarePlay.api"
|
|
|
import { httpAjaxErrMsg, httpAjaxLoadingErrMsg } from "@/plugin/httpAjax"
|
|
|
import userStore from "@/store/modules/user"
|
|
|
import { useRoute } from "vue-router"
|
|
|
-import { shallowRef, ref, computed, onUnmounted, onMounted, watch } from "vue"
|
|
|
+import { shallowRef, ref, computed, onUnmounted, onMounted, watch, nextTick } from "vue"
|
|
|
import { ElMessageBox } from "element-plus"
|
|
|
import courseCollapse from "./components/courseCollapse"
|
|
|
import pen from "./components/pen"
|
|
|
import playRecordTime from "./components/playRecordTime"
|
|
|
import useDialogConfirm from "@/hooks/useDialogConfirm"
|
|
|
import { getRecentCourseSchedule_gym } from "@/api/homePage.api"
|
|
|
+import { getToken } from "@/libs/auth"
|
|
|
+import { URL_TEACH_GYT, URL_TEACH_GYM } from "@/config"
|
|
|
|
|
|
const route = useRoute()
|
|
|
const userStoreHook = userStore()
|
|
@@ -121,16 +137,33 @@ const flattenCoursewareList = shallowRef<any[]>([]) // 扁平化coursewareList
|
|
|
const activeCourseware = computed<undefined | Record<string, any>>(() => {
|
|
|
return flattenCoursewareList.value[activeCoursewareIndex.value]
|
|
|
})
|
|
|
+// 文件类型
|
|
|
+const fileType = computed<"VIDEO" | "IMG" | "SONG">(() => {
|
|
|
+ return activeCourseware.value?.type || activeCourseware.value?.typeCode
|
|
|
+})
|
|
|
+const songPlaySrc = computed<string>(() => {
|
|
|
+ if (fileType.value !== "SONG") {
|
|
|
+ return ""
|
|
|
+ }
|
|
|
+ return userStoreHook.roles === "GYM"
|
|
|
+ ? `${URL_TEACH_GYM}?Authorization=${getToken()}&platform=web&isOpenMetronome=0#/detail/${activeCourseware.value?.content}?part-index=0`
|
|
|
+ : `${URL_TEACH_GYT}?id=${activeCourseware.value?.content}&modelType=practice&modeType=json&Authorization=${getToken()}`
|
|
|
+})
|
|
|
const activeCoursewareIndex = ref(0)
|
|
|
const drawerShow = ref(false)
|
|
|
// 课程总时间
|
|
|
const coursewareTotalTime = ref(0)
|
|
|
+// 监控播放
|
|
|
watch(activeCourseware, () => {
|
|
|
- activeCourseware.value &&
|
|
|
- videoPlayDom.value?.playVideo({
|
|
|
- src: activeCourseware.value.content,
|
|
|
- name: activeCourseware.value.name
|
|
|
+ handleVideoPause()
|
|
|
+ fileType.value === "VIDEO" &&
|
|
|
+ nextTick(() => {
|
|
|
+ handlePlayVideo({
|
|
|
+ src: activeCourseware.value?.content,
|
|
|
+ name: activeCourseware.value?.name
|
|
|
+ })
|
|
|
})
|
|
|
+ showController()
|
|
|
})
|
|
|
getCoursewareList()
|
|
|
function getCoursewareList() {
|
|
@@ -214,23 +247,76 @@ function handleCourseClick(value: any) {
|
|
|
return value.id === item.id
|
|
|
})
|
|
|
}
|
|
|
-
|
|
|
+/* 播放器相关 */
|
|
|
+// 视频播放或者暂停
|
|
|
+function handleVideoPlay() {
|
|
|
+ videoPlayDom.value?.handlePlay()
|
|
|
+ showController()
|
|
|
+}
|
|
|
+// 视频快进快退
|
|
|
+function handleVideoSpeedCurrentTime(type: "fast" | "slow") {
|
|
|
+ videoPlayDom.value?.speedCurrentTime(type)
|
|
|
+ showController()
|
|
|
+}
|
|
|
+// 视频暂停
|
|
|
+function handleVideoPause() {
|
|
|
+ videoPlayDom.value?.pauseVideo()
|
|
|
+ showController()
|
|
|
+}
|
|
|
+// 播放视频
|
|
|
+function handlePlayVideo({ src, name }: { src: string; name: string }) {
|
|
|
+ videoPlayDom.value?.playVideo({
|
|
|
+ src,
|
|
|
+ name
|
|
|
+ })
|
|
|
+ showController()
|
|
|
+}
|
|
|
/* 按键事件相关 */
|
|
|
onMounted(() => {
|
|
|
- document.addEventListener("keydown", handleVideoKeydown)
|
|
|
+ document.addEventListener("keydown", handleKeydown)
|
|
|
+ showController()
|
|
|
})
|
|
|
onUnmounted(() => {
|
|
|
- document.removeEventListener("keydown", handleVideoKeydown)
|
|
|
+ document.removeEventListener("keydown", handleKeydown)
|
|
|
})
|
|
|
-function handleVideoKeydown(e: KeyboardEvent) {
|
|
|
+function handleKeydown(e: KeyboardEvent) {
|
|
|
const key = e.key
|
|
|
- if (key === "ArrowDown") {
|
|
|
+ if (key === " ") {
|
|
|
+ // 视频类型的时候才触发
|
|
|
+ fileType.value === "VIDEO" && handleVideoPlay()
|
|
|
+ } else if (key === "ArrowLeft") {
|
|
|
+ // 视频类型的时候才触发
|
|
|
+ fileType.value === "VIDEO" && handleVideoSpeedCurrentTime("slow")
|
|
|
+ } else if (key === "ArrowRight") {
|
|
|
+ // 视频类型的时候才触发
|
|
|
+ fileType.value === "VIDEO" && handleVideoSpeedCurrentTime("fast")
|
|
|
+ } else if (key === "ArrowDown") {
|
|
|
handleChangeCourseware(1)
|
|
|
} else if (key === "ArrowUp") {
|
|
|
handleChangeCourseware(-1)
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+function handleMousemove() {
|
|
|
+ showController()
|
|
|
+}
|
|
|
+function handleClick() {
|
|
|
+ fileType.value === "VIDEO" && isShowController.value && handleVideoPlay()
|
|
|
+ showController()
|
|
|
+}
|
|
|
+// 是否显示控制器
|
|
|
+const isShowController = ref(true)
|
|
|
+let _showTimer: any
|
|
|
+function showController() {
|
|
|
+ isShowController.value = true
|
|
|
+ _showTimer && clearTimeout(_showTimer)
|
|
|
+ _showTimer = setTimeout(hideController, 3000)
|
|
|
+}
|
|
|
+function hideController() {
|
|
|
+ if (fileType.value === "VIDEO" && videoPlayDom.value?.playType === "pause") {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ isShowController.value = false
|
|
|
+}
|
|
|
/* 结束课程 */
|
|
|
function handleGoBack() {
|
|
|
window.open("about:blank", "_self")
|
|
@@ -284,6 +370,46 @@ function handleCoursewareEnd() {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ &.hideController {
|
|
|
+ .leftTools {
|
|
|
+ opacity: 0;
|
|
|
+ transform: translate(-100%, -50%);
|
|
|
+ }
|
|
|
+ .rightTools {
|
|
|
+ opacity: 0;
|
|
|
+ transform: translate(100%, -50%);
|
|
|
+ }
|
|
|
+ .topTools {
|
|
|
+ opacity: 0;
|
|
|
+ transform: translateY(-100%);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .coursewarePlayCon {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ overflow: hidden;
|
|
|
+ .imgPlayBox {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ .imgPlay {
|
|
|
+ width: 84%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .songPlayBox {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ .songIframe {
|
|
|
+ display: block;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
.topTools {
|
|
|
position: absolute;
|
|
|
top: 0;
|
|
@@ -348,20 +474,6 @@ function handleCoursewareEnd() {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- &:deep(.videoPlay.isHideController) {
|
|
|
- .leftTools {
|
|
|
- opacity: 0;
|
|
|
- transform: translate(-100%, -50%);
|
|
|
- }
|
|
|
- .rightTools {
|
|
|
- opacity: 0;
|
|
|
- transform: translate(100%, -50%);
|
|
|
- }
|
|
|
- .topTools {
|
|
|
- opacity: 0;
|
|
|
- transform: translateY(-100%);
|
|
|
- }
|
|
|
- }
|
|
|
&:deep(.elDrawer.el-drawer) {
|
|
|
width: 346px !important;
|
|
|
.el-drawer__header {
|