// import { Popup } from 'vant'; import { defineComponent, onMounted, reactive, nextTick, onUnmounted, ref, watch, Transition } from 'vue'; // import iconBack from './image/back.svg'; import styles from './index.module.less'; import 'plyr/dist/plyr.css'; import MusicScore from './component/musicScore'; import iconMenu from './image/icon-menu.svg'; // import iconDian from './image/icon-dian.svg'; // import iconPoint from './image/icon-point.svg'; import iconUp from './image/icon-up.svg'; import iconUpDisabled from './image/icon-up-disabled.svg'; import iconDown from './image/icon-down.svg'; import iconDownDisabled from './image/icon-down-disabled.svg'; import iconWhiteboard from './image/icon-whiteboard.svg'; // import Points from './component/points'; import iconAssignHomework from './image/icon-assignHomework.svg'; import { Vue3Lottie } from 'vue3-lottie'; import playLoadData from './datas/data.json'; import { usePageVisibility } from '@vant/use'; import VideoPlay from './component/video-play'; import { useMessage, NDrawer, NDrawerContent, NModal, NSpace, NButton } from 'naive-ui'; import CardType from '@/components/card-type'; import { ToolItem, ToolType } from './component/tool'; import Pen from './component/tools/pen'; import AudioPay from './component/audio-pay'; import TrainSettings from './model/train-settings'; export default defineComponent({ name: 'CoursewarePlay', setup() { const message = useMessage(); 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.videoEle?.paused; togglePlay(activeItem, false); } else { // 页面显示,并且 if (isPlay.value) togglePlay(activeItem, true); } }); /** 设置播放容器 16:9 */ const parentContainer = reactive({ width: '100vw' }); const setContainer = () => { const min = Math.min(screen.width, screen.height); const max = Math.max(screen.width, screen.height); const width = min * (16 / 9); if (width > max) { parentContainer.width = '100vw'; return; } else { parentContainer.width = width + 'px'; } }; const handleInit = (type = 0) => { //设置容器16:9 setContainer(); }; handleInit(); onUnmounted(() => { handleInit(1); }); // const route = useRoute(); // const router = useRouter(); // const headeRef = ref(); const data = reactive({ detail: null, knowledgePointList: [] as any, itemList: [] as any, showHead: true, isCourse: false, isRecordPlay: false, videoRefs: {} as any[], modelAttendStatus: false, // 布置作业提示弹窗 modelTrainStatus: false // 训练设置 }); const activeData = reactive({ isAutoPlay: true, // 是否自动播放 nowTime: 0, model: true, // 遮罩 isAnimation: true, // 是否动画 videoBtns: true, // 视频 currentTime: 0, duration: 0, timer: null as any, item: null as any }); // const getTempList = async (materialList: any, name: any) => { // const list: any = []; // const browserInfo = browser(); // for (let j = 0; j < materialList.length; j++) { // const material = materialList[j]; // list.push({ // ...material, // iframeRef: null, // videoEle: null, // tabName: name, // autoPlay: false, //加载完成是否自动播放 // isprepare: false, // 视频是否加载完成 // isRender: false // 是否渲染了 // }); // } // return list; // }; const getDetail = async () => { data.knowledgePointList = [ // { // id: '5', // name: '歌曲表演 大鹿', // title: '歌曲表演 大鹿', // type: 'AUDIO', // content: // 'https://cloud-coach.ks3-cn-beijing.ksyuncs.com/1686819360752.mp3', // url: 'https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/23cc71b5d7874dcf8752cd257483e687_mergeImage.png' // }, { id: '1', name: '歌曲表演 大鹿', title: '歌曲表演 大鹿', type: 'VIDEO', content: 'https://courseware.lexiaoya.cn/%E5%BF%85%E5%AD%A6%E5%BF%85%E7%9C%8B-%E8%90%A8%E5%85%8B%E6%96%AF-1-C4-4.mp4', url: 'https://lanhu-dds-backend.oss-cn-beijing.aliyuncs.com/merge_image/imgs/23cc71b5d7874dcf8752cd257483e687_mergeImage.png' }, { id: '2', name: '知识 音的高低', title: '知识 音的高低', type: 'IMG', content: 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png', url: 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png' }, { id: '3', name: '欣赏 永远在童话里', title: '欣赏 永远在童话里', type: 'IMG', content: 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png', url: 'https://gyt.ks3-cn-beijing.ksyuncs.com/courseware/1686815979899.png' }, { id: '4', name: '唱歌 小红帽', title: '唱歌 小红帽', type: 'SONG', content: '11707', url: 'https://lanhu.oss-cn-beijing.aliyuncs.com/SketchPngd1f4e00a00bc8134db4ec43e51a66442f778756e2caf01d10a1ffdd51fc7c6cb' } ]; data.itemList = data.knowledgePointList.map((m: any) => { return { ...m, iframeRef: null, videoEle: null, autoPlay: false, //加载完成是否自动播放 isprepare: false, // 视频是否加载完成 isRender: false // 是否渲染了 }; }); }; onMounted(() => { getDetail(); }); // const playRef = ref(); // 返回 // const goback = () => { // try { // playRef.value?.handleOut(); // } catch { // // // } // postMessage({ api: 'goBack' }); // }; const popupData = reactive({ open: false, activeIndex: 0, // tabActive: '', // tabName: '', // itemActive: '', // itemName: '' // guideOpen: false, toolOpen: false // 工具弹窗控制 }); /**停止所有的播放 */ const handleStop = () => { for (let i = 0; i < data.itemList.length; i++) { const activeItem = data.itemList[i]; if (activeItem.type === 'VIDEO' && activeItem.videoEle) { activeItem.videoEle.stop(); } // console.log('🚀 ~ activeItem:', activeItem) // 停止曲谱的播放 if (activeItem.type === 'SONG') { activeItem.iframeRef?.contentWindow?.postMessage( { api: 'setPlayState' }, '*' ); } } }; // 切换素材 const toggleMaterial = (itemActive: any) => { const index = data.itemList.findIndex((n: any) => n.id == itemActive); if (index > -1) { handleSwipeChange(index); } }; /** 延迟收起模态框 */ const setModelOpen = () => { clearTimeout(activeData.timer); message.destroyAll(); activeData.timer = setTimeout(() => { activeData.model = false; Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(false) ); }, 4000); }; /** 立即收起所有的模态框 */ const clearModel = () => { clearTimeout(activeData.timer); message.destroyAll(); activeData.model = false; Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(false)); }; const toggleModel = (type = true) => { activeData.model = type; Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(type)); }; // 双击 const handleDbClick = (item: any) => { if (item && item.type === 'VIDEO') { const videoEle: HTMLVideoElement = item.videoEle; if (videoEle) { if (videoEle.paused) { message.destroyAll(); videoEle.play(); } else { message.warning('已暂停'); videoEle.pause(); } } } }; // 切换播放 const togglePlay = (m: any, isPlay: boolean) => { if (isPlay) { m.videoEle?.play(); } else { m.videoEle?.pause(); } }; const showIndex = ref(-4); const effectIndex = ref(3); const effects = [ { prev: { transform: 'translate3d(0, 0, -800px) rotateX(180deg)' }, next: { transform: 'translate3d(0, 0, -800px) rotateX(-180deg)' } }, { prev: { transform: 'translate3d(-100%, 0, -800px)' }, next: { transform: 'translate3d(100%, 0, -800px)' } }, { prev: { transform: 'translate3d(-50%, 0, -800px) rotateY(80deg)' }, next: { transform: 'translate3d(50%, 0, -800px) rotateY(-80deg)' } }, { prev: { transform: 'translate3d(-100%, 0, -800px) rotateY(-120deg)' }, next: { transform: 'translate3d(100%, 0, -800px) rotateY(120deg)' } }, // 风车4 { prev: { transform: 'translate3d(-50%, 50%, -800px) rotateZ(-14deg)', opacity: 0 }, next: { transform: 'translate3d(50%, 50%, -800px) rotateZ(14deg)', opacity: 0 } }, // 翻页5 { prev: { transform: 'translateZ(-800px) rotate3d(0, -1, 0, 90deg)', opacity: 0 }, next: { transform: 'translateZ(-800px) rotate3d(0, 1, 0, 90deg)', opacity: 0 }, current: { transitionDelay: '700ms' } } ]; const acitveTimer = ref(); // 轮播切换 const handleSwipeChange = (index: number) => { // 如果是当前正在播放 或者是视频最后一个 if (popupData.activeIndex == index) return; handleStop(); clearTimeout(acitveTimer.value); checkedAnimation(popupData.activeIndex, index); popupData.activeIndex = index; acitveTimer.value = setTimeout( () => { const item = data.itemList[index]; if (item) { // popupData.tabActive = item.knowledgePointId; // popupData.itemActive = item.id; // popupData.itemName = item.name; // popupData.tabName = item.tabName; if (item.type == 'SONG') { activeData.model = true; } if (item.type === 'VIDEO') { // 自动播放下一个视频 clearTimeout(activeData.timer); message.destroyAll(); item.autoPlay = true; nextTick(() => { item.videoEle?.play(); }); } } // requestAnimationFrame(() => { // const _effectIndex = effectIndex.value + 1; // effectIndex.value = // _effectIndex >= effects.length - 1 ? 0 : _effectIndex; // }); }, activeData.isAnimation ? 800 : 0 ); }; /** 是否有转场动画 */ const checkedAnimation = (index: number, nextIndex?: number) => { const item = data.itemList[index]; const nextItem = data.itemList[nextIndex!]; if (nextItem) { if (nextItem.knowledgePointId != item.knowledgePointId) { activeData.isAnimation = true; return; } const videoEle = item.videoEle; const nextVideo = nextItem.videoEle; if (videoEle && videoEle.duration < 8 && index < nextIndex!) { activeData.isAnimation = false; } else if (nextVideo && nextVideo.duration < 8 && index > nextIndex!) { activeData.isAnimation = false; } else { activeData.isAnimation = true; } } else { activeData.isAnimation = item?.adviseStudyTimeSecond < 8 ? false : true; } }; // 上一个知识点, 下一个知识点 const handlePreAndNext = (type: string) => { if (type === 'up') { handleSwipeChange(popupData.activeIndex - 1); } else { handleSwipeChange(popupData.activeIndex + 1); } }; /** 弹窗关闭 */ const handleClosePopup = () => { const item = data.itemList[popupData.activeIndex]; if (item?.type == 'VIDEO' && !item.videoEle?.paused) { setModelOpen(); } }; // 监听页面键盘事件 - 上下切换 document.body.addEventListener('keyup', (e: KeyboardEvent) => { if (e.key === 'ArrowUp') { if (popupData.activeIndex === 0) return; handlePreAndNext('up'); } else if (e.key === 'ArrowDown') { if (popupData.activeIndex === data.itemList.length - 1) return; handlePreAndNext('down'); } }); /** 教学数据 */ const studyData = reactive({ type: '' as ToolType, penShow: false }); /** 打开教学工具 */ const openStudyTool = (item: ToolItem) => { const activeItem = data.itemList[popupData.activeIndex]; // 暂停视频和曲谱的播放 if (activeItem.type === 'VIDEO' && activeItem.videoEle) { activeItem.videoEle.pause(); } if (activeItem.type === 'SONG') { activeItem.iframeRef?.contentWindow?.postMessage( { api: 'setPlayState' }, '*' ); } clearModel(); popupData.toolOpen = false; studyData.type = item.type; switch (item.type) { case 'pen': studyData.penShow = true; break; } }; /** 关闭教学工具 */ const closeStudyTool = () => { studyData.type = 'init'; toggleModel(); }; return () => (
{ clearTimeout(activeData.timer); activeData.model = !activeData.model; Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(activeData.model) ); }}>
{ e.stopPropagation(); setModelOpen(); }}>
{data.itemList.map((m: any, mIndex: number) => { const isRender = m.isRender || Math.abs(popupData.activeIndex - mIndex) < 2; const isEmtry = Math.abs(popupData.activeIndex - mIndex) > 4; if (isRender) { m.isRender = true; } return isRender ? (
popupData.activeIndex ? effects[effectIndex.value].next : {} } onClick={(e: Event) => { e.stopPropagation(); clearTimeout(activeData.timer); if (Date.now() - activeData.nowTime < 300) { handleDbClick(m); return; } activeData.nowTime = Date.now(); activeData.timer = setTimeout(() => { activeData.model = !activeData.model; Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(activeData.model) ); if (activeData.model) { setModelOpen(); } }, 300); }}> {m.type === 'VIDEO' ? ( <> (data.videoRefs[mIndex] = v)} item={m} isEmtry={isEmtry} onLoadedmetadata={(videoItem: any) => { m.videoEle = videoItem; m.isprepare = true; }} onTogglePlay={(paused: boolean) => { m.autoPlay = false; if (paused || popupData.open) { clearTimeout(activeData.timer); } else { setModelOpen(); } }} onEnded={() => { const _index = popupData.activeIndex + 1; if (_index < data.itemList.length) { handleSwipeChange(_index); } }} onReset={() => { if (!m.videoEle?.paused) { setModelOpen(); } }} /> {!m.isprepare && (
)}
) : m.type === 'IMG' ? ( ) : m.type === 'AUDIO' ? ( ) : ( { m.iframeRef = el; }} /> )}
) : null; })}
{activeData.model && (
{ e.stopPropagation(); clearTimeout(activeData.timer); }}>
(popupData.open = true)}>
)}
{/*
goback()}> 返回
{popupData.itemName}
*/} {/* 布置作业按钮 */}
(data.modelAttendStatus = true)}>
{/* 上下切换 */}
{ if (popupData.activeIndex === 0) return; handlePreAndNext('up'); }}>
{ if (popupData.activeIndex === data.itemList.length - 1) return; handlePreAndNext('down'); }}>
{/* 白板 */}
openStudyTool({ type: 'pen', icon: iconWhiteboard, name: '白板' }) }>
{/* 显示列表 */} {data.knowledgePointList.map((item: any, index: number) => ( { popupData.open = false; toggleMaterial(item.id); }} /> ))} {/* 批注 */} {studyData.penShow && ( closeStudyTool()} /> )} {/* 布置作业 */}
本节课已设置课后训练,是否布置?
{ // window.close(); data.modelAttendStatus = false; }}> 暂无布置 { data.modelTrainStatus = true; data.modelAttendStatus = false; }}> 布置
{/* 训练设置 */} (data.modelTrainStatus = false)} />
); } });