|
@@ -7,7 +7,7 @@ import {
|
|
Slider,
|
|
Slider,
|
|
Swipe,
|
|
Swipe,
|
|
SwipeInstance,
|
|
SwipeInstance,
|
|
- SwipeItem,
|
|
|
|
|
|
+ SwipeItem
|
|
} from 'vant'
|
|
} from 'vant'
|
|
import {
|
|
import {
|
|
defineComponent,
|
|
defineComponent,
|
|
@@ -17,7 +17,7 @@ import {
|
|
onUnmounted,
|
|
onUnmounted,
|
|
ref,
|
|
ref,
|
|
watch,
|
|
watch,
|
|
- Transition,
|
|
|
|
|
|
+ Transition
|
|
} from 'vue'
|
|
} from 'vue'
|
|
import iconBack from './image/back.svg'
|
|
import iconBack from './image/back.svg'
|
|
import styles from './index.module.less'
|
|
import styles from './index.module.less'
|
|
@@ -25,7 +25,7 @@ import 'plyr/dist/plyr.css'
|
|
import request from '@/helpers/request'
|
|
import request from '@/helpers/request'
|
|
import { state } from '@/state'
|
|
import { state } from '@/state'
|
|
import { useRoute } from 'vue-router'
|
|
import { useRoute } from 'vue-router'
|
|
-import { postMessage, promisefiyPostMessage } from '@/helpers/native-message'
|
|
|
|
|
|
+import { listenerMessage, postMessage, promisefiyPostMessage } from '@/helpers/native-message'
|
|
import MusicScore from './component/musicScore'
|
|
import MusicScore from './component/musicScore'
|
|
import iconMenu from './image/icon-menu.svg'
|
|
import iconMenu from './image/icon-menu.svg'
|
|
import iconDian from './image/icon-dian.svg'
|
|
import iconDian from './image/icon-dian.svg'
|
|
@@ -40,10 +40,25 @@ import Points from './component/points'
|
|
import { browser, getSecondRPM } from '@/helpers/utils'
|
|
import { browser, getSecondRPM } from '@/helpers/utils'
|
|
import { Vue3Lottie } from 'vue3-lottie'
|
|
import { Vue3Lottie } from 'vue3-lottie'
|
|
import playLoadData from './datas/data.json'
|
|
import playLoadData from './datas/data.json'
|
|
|
|
+import { usePageVisibility } from '@vant/use'
|
|
|
|
|
|
export default defineComponent({
|
|
export default defineComponent({
|
|
name: 'CoursewarePlay',
|
|
name: 'CoursewarePlay',
|
|
setup() {
|
|
setup() {
|
|
|
|
+ const pageVisibility = usePageVisibility()
|
|
|
|
+ const isPlay = ref(false)
|
|
|
|
+ /** 页面显示和隐藏 */
|
|
|
|
+ watch(pageVisibility, (value) => {
|
|
|
|
+ const activeItem = data.itemList[popupData.activeIndex]
|
|
|
|
+ if (activeItem.type != 'VIDEO') return
|
|
|
|
+ if (value == 'hidden') {
|
|
|
|
+ isPlay.value = !activeItem.paused
|
|
|
|
+ handlePaused(activeItem)
|
|
|
|
+ } else {
|
|
|
|
+ // 页面显示,并且
|
|
|
|
+ if (isPlay.value) handlePlay(activeItem)
|
|
|
|
+ }
|
|
|
|
+ })
|
|
/** 设置播放容器 16:9 */
|
|
/** 设置播放容器 16:9 */
|
|
const parentContainer = reactive({
|
|
const parentContainer = reactive({
|
|
width: '100vw'
|
|
width: '100vw'
|
|
@@ -198,7 +213,7 @@ export default defineComponent({
|
|
item.autoPlay = true
|
|
item.autoPlay = true
|
|
item.muted = true
|
|
item.muted = true
|
|
}
|
|
}
|
|
- console.log('🚀 ~ list', list)
|
|
|
|
|
|
+ // console.log('🚀 ~ list', list)
|
|
data.itemList = list
|
|
data.itemList = list
|
|
}
|
|
}
|
|
const getDetail = async () => {
|
|
const getDetail = async () => {
|
|
@@ -235,6 +250,7 @@ export default defineComponent({
|
|
activeData.model = !activeData.model
|
|
activeData.model = !activeData.model
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
getDetail()
|
|
getDetail()
|
|
getCourseSchedule()
|
|
getCourseSchedule()
|
|
@@ -257,26 +273,32 @@ export default defineComponent({
|
|
})
|
|
})
|
|
// 设置当前的激活状态
|
|
// 设置当前的激活状态
|
|
const setActiveData = (val: any, oldVal: any) => {
|
|
const setActiveData = (val: any, oldVal: any) => {
|
|
- handleStopVideo()
|
|
|
|
- handleStopMusicScore()
|
|
|
|
|
|
+ handleStop()
|
|
}
|
|
}
|
|
watch(() => popupData.activeIndex, setActiveData)
|
|
watch(() => popupData.activeIndex, setActiveData)
|
|
|
|
|
|
- // 停止所有的播放
|
|
|
|
- const handleStopVideo = () => {
|
|
|
|
- data.itemList.forEach((m: any) => {
|
|
|
|
- const item = data.itemList[popupData.activeIndex]
|
|
|
|
- if (item?.id != m.id) {
|
|
|
|
- m.autoPlay = false
|
|
|
|
- m.videoEle?.pause()
|
|
|
|
|
|
+ /**停止所有的播放 */
|
|
|
|
+ const handleStop = () => {
|
|
|
|
+ const activeItem = data.itemList[popupData.activeIndex]
|
|
|
|
+ for (let i = 0; i < data.itemList.length; i++) {
|
|
|
|
+ const item = data.itemList[i]
|
|
|
|
+ // 停止视频播放
|
|
|
|
+ if (item.type === 'VIDEO') {
|
|
|
|
+ // console.log("🚀 ~ item", item)
|
|
|
|
+ if (item?.id != activeItem.id) {
|
|
|
|
+ item.currentTime = 0
|
|
|
|
+ item.progress = 0
|
|
|
|
+ if (item.videoEle) {
|
|
|
|
+ item.videoEle.currentTime = 0
|
|
|
|
+ item.videoEle.pause()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- })
|
|
|
|
- }
|
|
|
|
- // 停止曲谱的播放
|
|
|
|
- const handleStopMusicScore = () => {
|
|
|
|
- data.itemList.forEach((m: any) => {
|
|
|
|
- m.iframeRef?.contentWindow?.postMessage({ api: 'setPlayState' }, '*')
|
|
|
|
- })
|
|
|
|
|
|
+ // 停止曲谱的播放
|
|
|
|
+ if (item.type === 'SONG') {
|
|
|
|
+ item.iframeRef?.contentWindow?.postMessage({ api: 'setPlayState' }, '*')
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
// 切换素材
|
|
// 切换素材
|
|
const toggleMaterial = () => {
|
|
const toggleMaterial = () => {
|
|
@@ -363,12 +385,12 @@ export default defineComponent({
|
|
}
|
|
}
|
|
|
|
|
|
// 暂停播放
|
|
// 暂停播放
|
|
- const handlePaused = (e: Event, m: any) => {
|
|
|
|
|
|
+ const handlePaused = (m: any) => {
|
|
m.videoEle?.pause()
|
|
m.videoEle?.pause()
|
|
m.paused = true
|
|
m.paused = true
|
|
}
|
|
}
|
|
// 开始播放
|
|
// 开始播放
|
|
- const handlePlay = (e: Event, m: any) => {
|
|
|
|
|
|
+ const handlePlay = (m: any) => {
|
|
closeToast()
|
|
closeToast()
|
|
m.videoEle?.play()
|
|
m.videoEle?.play()
|
|
}
|
|
}
|
|
@@ -446,16 +468,18 @@ export default defineComponent({
|
|
if (!m.isprepare) return
|
|
if (!m.isprepare) return
|
|
const videoEle = e.target as unknown as HTMLVideoElement
|
|
const videoEle = e.target as unknown as HTMLVideoElement
|
|
m.currentTime = videoEle.currentTime
|
|
m.currentTime = videoEle.currentTime
|
|
- m.progress = Number(
|
|
|
|
- ((videoEle.currentTime / m.duration) * 100).toFixed(1)
|
|
|
|
- )
|
|
|
|
|
|
+ m.progress = Number((videoEle.currentTime / m.duration) * 100)
|
|
}}
|
|
}}
|
|
onPlay={() => {
|
|
onPlay={() => {
|
|
// 播放
|
|
// 播放
|
|
m.paused = false
|
|
m.paused = false
|
|
console.log('播放')
|
|
console.log('播放')
|
|
setModelOpen()
|
|
setModelOpen()
|
|
- m.muted = false
|
|
|
|
|
|
+ // 第一次播放
|
|
|
|
+ if (m.muted) {
|
|
|
|
+ m.muted = false
|
|
|
|
+ m.autoPlay = false
|
|
|
|
+ }
|
|
}}
|
|
}}
|
|
onPause={() => {
|
|
onPause={() => {
|
|
//暂停
|
|
//暂停
|
|
@@ -471,86 +495,86 @@ export default defineComponent({
|
|
<Vue3Lottie animationData={playLoadData}></Vue3Lottie>
|
|
<Vue3Lottie animationData={playLoadData}></Vue3Lottie>
|
|
</div>
|
|
</div>
|
|
)}
|
|
)}
|
|
- <Transition name="bottom">
|
|
|
|
- {activeData.model && (
|
|
|
|
- <div
|
|
|
|
- class={[styles.bottomFixedContainer]}
|
|
|
|
- onClick={(e: Event) => {
|
|
|
|
- e.stopPropagation()
|
|
|
|
- setModelOpen()
|
|
|
|
- }}
|
|
|
|
- >
|
|
|
|
- <div style={{ opacity: m.isprepare ? '1' : '0' }}>
|
|
|
|
- <div class={styles.time}>
|
|
|
|
- <span>{getSecondRPM(m.currentTime)}</span>
|
|
|
|
- <span>{getSecondRPM(m.duration)}</span>
|
|
|
|
- </div>
|
|
|
|
- <div class={styles.slider}>
|
|
|
|
- <Slider
|
|
|
|
- onClick={() => setModelOpen()}
|
|
|
|
- buttonSize={16}
|
|
|
|
- step={0.1}
|
|
|
|
- modelValue={m.progress}
|
|
|
|
- onUpdate:modelValue={(val: any) => {
|
|
|
|
- m.progress = val
|
|
|
|
- handleChangeSlider(m)
|
|
|
|
- }}
|
|
|
|
- onDragStart={(e: Event) => {
|
|
|
|
- // 开始拖动,暂停播放
|
|
|
|
- console.log('开始拖动')
|
|
|
|
- // 如果拖动之前,视频是播放状态,拖动完毕后继续播放
|
|
|
|
- if (!m.paused) {
|
|
|
|
- m.isDrage = true
|
|
|
|
- }
|
|
|
|
- handlePaused(e, m)
|
|
|
|
- }}
|
|
|
|
- onDragEnd={(e: Event) => {
|
|
|
|
- console.log('结束拖动')
|
|
|
|
- if (m.isDrage) {
|
|
|
|
- m.isDrage = false
|
|
|
|
- handlePlay(e, m)
|
|
|
|
- }
|
|
|
|
- }}
|
|
|
|
- min={0}
|
|
|
|
- max={100}
|
|
|
|
- />
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
|
|
+ <div
|
|
|
|
+ style={{ transform: activeData.model ? '' : 'translateY(100%)' }}
|
|
|
|
+ class={styles.bottomFixedContainer}
|
|
|
|
+ onClick={(e: Event) => {
|
|
|
|
+ e.stopPropagation()
|
|
|
|
+ setModelOpen()
|
|
|
|
+ }}
|
|
|
|
+ >
|
|
|
|
+ <div style={{ opacity: m.isprepare ? '1' : '0' }}>
|
|
|
|
+ <div class={styles.time}>
|
|
|
|
+ <span>{getSecondRPM(m.currentTime)}</span>
|
|
|
|
+ <span>{getSecondRPM(m.duration)}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class={styles.slider}>
|
|
|
|
+ <Slider
|
|
|
|
+ onClick={() => setModelOpen()}
|
|
|
|
+ buttonSize={16}
|
|
|
|
+ step={1}
|
|
|
|
+ modelValue={m.progress}
|
|
|
|
+ onUpdate:modelValue={(val: any) => {
|
|
|
|
+ console.log('val', val)
|
|
|
|
+ m.progress = val
|
|
|
|
+ handleChangeSlider(m)
|
|
|
|
+ }}
|
|
|
|
+ onDragStart={(e: Event) => {
|
|
|
|
+ // 开始拖动,暂停播放
|
|
|
|
+ console.log('开始拖动')
|
|
|
|
+ // 如果拖动之前,视频是播放状态,拖动完毕后继续播放
|
|
|
|
+ if (!m.paused) {
|
|
|
|
+ m.isDrage = true
|
|
|
|
+ }
|
|
|
|
+ handlePaused(m)
|
|
|
|
+ }}
|
|
|
|
+ onDragEnd={(e: Event) => {
|
|
|
|
+ console.log('结束拖动')
|
|
|
|
+ if (m.isDrage) {
|
|
|
|
+ m.isDrage = false
|
|
|
|
+ handlePlay(m)
|
|
|
|
+ }
|
|
|
|
+ }}
|
|
|
|
+ min={0}
|
|
|
|
+ max={100}
|
|
|
|
+ />
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
|
|
- <div class={styles.actions}>
|
|
|
|
- <div class={styles.actionBtn}>
|
|
|
|
- {m.isprepare ? (
|
|
|
|
- <>
|
|
|
|
- {m.paused ? (
|
|
|
|
- <img
|
|
|
|
- src={iconplay}
|
|
|
|
- onClick={(e: Event) => handlePlay(e, m)}
|
|
|
|
- />
|
|
|
|
- ) : (
|
|
|
|
- <img
|
|
|
|
- src={iconpause}
|
|
|
|
- onClick={(e: Event) => handlePaused(e, m)}
|
|
|
|
- />
|
|
|
|
- )}
|
|
|
|
- </>
|
|
|
|
|
|
+ <div class={styles.actions}>
|
|
|
|
+ <div class={styles.actionBtn}>
|
|
|
|
+ {m.isprepare ? (
|
|
|
|
+ <>
|
|
|
|
+ {m.paused ? (
|
|
|
|
+ <img src={iconplay} onClick={(e: Event) => handlePlay(m)} />
|
|
) : (
|
|
) : (
|
|
- <Loading color="#fff" />
|
|
|
|
- )}
|
|
|
|
-
|
|
|
|
- {m.loop ? (
|
|
|
|
<img
|
|
<img
|
|
- src={iconLoopActive}
|
|
|
|
- onClick={(e: Event) => (m.loop = false)}
|
|
|
|
|
|
+ src={iconpause}
|
|
|
|
+ onClick={(e: Event) => handlePaused(m)}
|
|
/>
|
|
/>
|
|
- ) : (
|
|
|
|
- <img src={iconLoop} onClick={(e: Event) => (m.loop = true)} />
|
|
|
|
)}
|
|
)}
|
|
- </div>
|
|
|
|
- <div>{m.name}</div>
|
|
|
|
- </div>
|
|
|
|
|
|
+ </>
|
|
|
|
+ ) : (
|
|
|
|
+ <Loading color="#fff" />
|
|
|
|
+ )}
|
|
|
|
+
|
|
|
|
+ {m.loop ? (
|
|
|
|
+ <img
|
|
|
|
+ src={iconLoopActive}
|
|
|
|
+ onClick={(e: Event) => (m.loop = false)}
|
|
|
|
+ />
|
|
|
|
+ ) : (
|
|
|
|
+ <img src={iconLoop} onClick={(e: Event) => (m.loop = true)} />
|
|
|
|
+ )}
|
|
</div>
|
|
</div>
|
|
|
|
+ <div>{m.name}</div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ {/* <Transition name="bottom">
|
|
|
|
+ {activeData.model && (
|
|
|
|
+
|
|
)}
|
|
)}
|
|
- </Transition>
|
|
|
|
|
|
+ </Transition> */}
|
|
</>
|
|
</>
|
|
) : m.type === 'IMG' ? (
|
|
) : m.type === 'IMG' ? (
|
|
<img src={m.content} />
|
|
<img src={m.content} />
|