Selaa lähdekoodia

统一音频视频播放

liushengqiang 1 vuosi sitten
vanhempi
commit
eba9cd7463

+ 9 - 9
src/helpers/native-message.ts

@@ -33,8 +33,15 @@ const loop = () => {};
 const calls: { [key: string]: CallBack | CallBack[] } = {};
 
 const browserInfo = browser();
+const instance: any =
+  (window as any).DAYA ||
+  (window as any).webkit?.messageHandlers?.DAYA ||
+  (window as any).COLEXIU ||
+  (window as any).webkit?.messageHandlers?.COLEXIU ||
+  (window as any).ORCHESTRA ||
+  (window as any).webkit?.messageHandlers?.ORCHESTRA;
 
-if (browserInfo.isApp) {
+if (instance) {
   window.addEventListener('message', evt => {
     try {
       console.log('app交互接受:', evt.data);
@@ -77,13 +84,6 @@ if (browserInfo.isApp) {
   });
 }
 
-const instance: any =
-  (window as any).DAYA ||
-  (window as any).webkit?.messageHandlers?.DAYA ||
-  (window as any).COLEXIU ||
-  (window as any).webkit?.messageHandlers?.COLEXIU ||
-  (window as any).ORCHESTRA ||
-  (window as any).webkit?.messageHandlers?.ORCHESTRA;
 
 export const postMessage = (data: IPostMessage, callback?: CallBack) => {
   if (instance) {
@@ -103,7 +103,7 @@ export const listenerMessage = (api: string, callback: CallBack) => {
 };
 
 export const removeListenerMessage = (api: string, callback: CallBack) => {
-  if (browserInfo.isApp) {
+  if (instance) {
     const uuid = api;
     if (Array.isArray(calls[uuid])) {
       const indexOf = (calls[uuid] as CallBack[]).indexOf(callback);

+ 24 - 23
src/views/courseware-list/component/book/index.tsx

@@ -11,6 +11,7 @@ import icon_back from '../../image/icon_back.svg';
 import icon_play from '../../image/icon_play.svg';
 import { useRouter } from 'vue-router';
 import { postMessage } from '@/helpers/native-message';
+import { showToast } from 'vant';
 
 export default defineComponent({
   name: 'the-book',
@@ -173,6 +174,28 @@ export default defineComponent({
         }
       }
     );
+    const handleOpenPlay = (item: any) => {
+      if (!item.containMaterial) {
+        showToast('暂无资源');
+        return;
+      }
+      if (item.id) {
+        postMessage({
+          api: 'openWebView',
+          content: {
+            url:
+              location.origin +
+              location.pathname +
+              '#/courseware-play?id=' +
+              item.id +
+              '&name=' +
+              item.name,
+            orientation: 0,
+            isHideTitle: false
+          }
+        });
+      }
+    };
     return () => (
       <div class={[styles.book, data.show ? '' : styles.bookHide]}>
         <div class={styles.back} onClick={handleClose}>
@@ -201,29 +224,7 @@ export default defineComponent({
                             }}
                             onClick={(e: Event) => {
                               e.stopPropagation();
-                              if (item.id) {
-                                postMessage({
-                                  api: 'openWebView',
-                                  content: {
-                                    url:
-                                      location.origin +
-                                      location.pathname +
-                                      '#/courseware-play?id=' +
-                                      item.id +
-                                      '&name=' +
-                                      item.name,
-                                    orientation: 0,
-                                    isHideTitle: false
-                                  }
-                                });
-                                // router.push({
-                                //   path: '/courseware-play',
-                                //   query: {
-                                //     id: item.id,
-                                //     name: item.name
-                                //   }
-                                // });
-                              }
+                              handleOpenPlay(item);
                             }}>
                             <div class={styles.name}>{item.name}</div>
                             {item.id ? (

+ 21 - 12
src/views/courseware-play/component/audio-item/index.tsx

@@ -23,6 +23,10 @@ export default defineComponent({
       type: Boolean,
       default: false
     },
+    pageVisibility: {
+      type: String,
+      default: ''
+    },
     showModel: {
       type: Boolean,
       default: false
@@ -57,6 +61,18 @@ export default defineComponent({
         }
       }
     );
+    watch(
+      () => props.pageVisibility,
+      val => {
+        if (val === 'hidden' && props.show) {
+          audioRef.value.pause();
+        } else {
+          if (props.show){
+            onToggleAudio();
+          }
+        }
+      }
+    );
 
     // 切换音频播放
     const onToggleAudio = () => {
@@ -98,23 +114,18 @@ export default defineComponent({
     /** 加载成功 */
     const onLoadedmetadata = () => {
       data.duration = audioRef.value.duration;
-      // if (data.isFirst) {
-      //   data.isFirst = false;
-      //   return;
-      // }
-      // if (props.playState === 'play'){
-      //     audioRef.value.play();
-      // }
+      // 加载成功后台, 如果是第一次加载, 且是show状态, 则播放
+      if (props.show) {
+        onToggleAudio();
+      }
     };
 
     /** 改变播放时间 */
     const handleChangeTime = (val: number) => {
-      // audioRef.value.pause();
       data.currentTime = val;
       clearTimeout(data.timer);
       data.timer = setTimeout(() => {
         audioRef.value.currentTime = val;
-        // audioRef.value.play();
         data.timer = null;
       }, 300);
     };
@@ -159,9 +170,7 @@ export default defineComponent({
               onUpdate:value={val => handleChangeTime(val)}
             />
           </div>
-          <div
-            class={styles.actions}
-            onClick={(e: Event) => e.stopPropagation()}>
+          <div class={styles.actions}>
             <div class={styles.actionBtn} onClick={() => onToggleAudio()}>
               <img src={data.playState === 'pause' ? iconplay : iconpause} />
             </div>

+ 33 - 6
src/views/courseware-play/component/musicScore.tsx

@@ -11,6 +11,14 @@ import { browser } from '@/helpers/utils';
 export default defineComponent({
   name: 'musicScore',
   props: {
+    pageVisibility: {
+      type: String,
+      default: ''
+    },
+    show: {
+      type: Boolean,
+      default: false
+    },
     music: {
       type: Object,
       default: () => {}
@@ -24,14 +32,33 @@ export default defineComponent({
     const browserInfo = browser();
     const route = useRoute();
     const isLoading = ref(false);
-    const pageVisibility = usePageVisibility();
     /** 页面显示和隐藏 */
-    watch(pageVisibility, value => {
-      console.log('🚀 ~ value:', value);
-      if (value == 'hidden') {
-        isLoading.value = false;
+    watch(
+      () => props.pageVisibility,
+      value => {
+        if (value == 'hidden') {
+          isLoading.value = false;
+        }
+        if (value == 'hidden' && props.show) {
+          iframeRef.value?.contentWindow?.postMessage(
+            { api: 'setPlayState' },
+            '*'
+          );
+        }
       }
-    });
+    );
+    // 是否显示当前曲谱
+    watch(
+      () => props.show,
+      val => {
+        if (!val) {
+          iframeRef.value?.contentWindow?.postMessage(
+            { api: 'setPlayState' },
+            '*'
+          );
+        }
+      }
+    );
     const iframeRef = ref();
     const isLoaded = ref(false);
     const renderError = ref(false);

+ 132 - 0
src/views/courseware-play/component/video-item/index.module.less

@@ -0,0 +1,132 @@
+.videoWrap {
+    position: relative;
+    width: 100%;
+    height: 100%;
+}
+.content{
+    height: 100%;
+}
+.contentWrap{
+    height: 100%;
+    video{
+        width: 100%;
+        height: 100%;
+    }
+}
+
+.controls {
+    position: absolute;
+    left: 0;
+    bottom: 0;
+    right: 0;
+    height: 80px;
+    background: linear-gradient(0deg, rgba(0, 0, 0, 0.5), transparent);
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    transition: all 0.5s;
+
+    &.hide{
+        transform: translateY(100%);
+    }
+
+    .time {
+        display: flex;
+        justify-content: space-between;
+        width: 100%;
+        color: #fff;
+        font-size: 10px;
+        padding: 4px 20px;
+    }
+
+    .slider {
+        width: 100%;
+        padding: 0 20px;
+        :global {
+            .n-slider{
+                --n-handle-size: 13px !important;
+                --n-fill-color: var(--van-primary-color) !important;
+                --n-fill-color-hover: var(--van-primary-color) !important;
+            }
+            .van-loading {
+                width: 100%;
+                height: 100%;
+            }
+        }
+    }
+
+    .actions {
+        display: flex;
+        width: 100%;
+        color: #fff;
+        font-size: 12px;
+        padding: 0 20px;
+        align-items: center;
+
+        .actionWrap {
+            display: flex;
+        }
+
+        .actionBtn {
+            display: flex;
+            width: 38px;
+            height: 38px;
+            padding: 4px 0;
+            background: transparent;
+        }
+
+        .actionBtn>img {
+            width: 100%;
+            height: 100%;
+        }
+
+        :global {
+            .van-loading__circular {
+                width: 100%;
+                height: 100%;
+            }
+        }
+
+        .playIcon {
+            display: none;
+        }
+
+        .btnPlay img:nth-child(2) {
+            display: block;
+        }
+
+        .btnPause img:nth-child(3) {
+            display: block;
+        }
+
+        .btnPlay,
+        .btnPause {
+            :global {
+                .van-loading {
+                    display: none;
+                }
+            }
+        }
+        .loopBtn{
+            :global{
+                .loop{
+                    display: block;
+                }
+                .loopActive{
+                    display: none;
+                }
+            }
+        }
+        .loopBtn.active{
+            :global{
+                .loop{
+                    display: none;
+                }
+                .loopActive{
+                    display: block;
+                }
+            }
+        }
+
+    }
+}

+ 166 - 0
src/views/courseware-play/component/video-item/index.tsx

@@ -0,0 +1,166 @@
+import { defineComponent, onMounted, reactive, toRefs, watch } from 'vue';
+import { ref } from 'vue';
+import styles from './index.module.less';
+
+import iconLoop from '../../image/icon-loop.svg';
+import iconLoopActive from '../../image/icon-loop-active.svg';
+import iconplay from '../../image/icon-play.svg';
+import iconpause from '../../image/icon-pause.svg';
+import { NSlider } from 'naive-ui';
+import { getSecondRPM } from '@/helpers/utils';
+
+export default defineComponent({
+  name: 'video-play',
+  props: {
+    item: {
+      type: Object,
+      default: () => {
+        return {};
+      }
+    },
+    pageVisibility: {
+      type: String,
+      default: ''
+    },
+    show: {
+      type: Boolean,
+      default: false
+    },
+    showModel: {
+      type: Boolean,
+      default: false
+    },
+    isEmtry: {
+      type: Boolean,
+      default: false
+    }
+  },
+  emits: ['loadedmetadata', 'togglePlay', 'ended', 'reset'],
+  setup(props, { emit }) {
+    const { item, isEmtry } = toRefs(props);
+    const data = reactive({
+      timer: null as any,
+      currentTime: 0,
+      duration: 0,
+      loop: false,
+      playState: 'pause' as 'play' | 'pause',
+      vudio: null as any
+    });
+    const canvasRef: any = ref();
+    const elRef: any = ref();
+    const contetRef = ref();
+
+    watch(
+      () => props.show,
+      val => {
+        onToggleAudio(val ? 'play' : 'pause');
+      }
+    );
+    watch(
+      () => props.pageVisibility,
+      val => {
+        if (val === 'hidden' && props.show) {
+          onToggleAudio('pause');
+        } else {
+          if (props.show){
+            onToggleAudio('play');
+          }
+        }
+      }
+    );
+
+    let playTimer = null as any;
+    // 切换音频播放
+    const onToggleAudio = (state: 'play' | 'pause') => {
+      clearTimeout(playTimer);
+      if (state === 'play') {
+        playTimer = setTimeout(() => {
+          elRef.value.play();
+          data.playState = 'play';
+        }, 100);
+      } else {
+        elRef.value.pause();
+        data.playState = 'pause';
+      }
+    };
+
+    /** 加载成功 */
+    const onLoadedmetadata = () => {
+      data.duration = elRef.value.duration;
+      // 加载成功后台, 如果是第一次加载, 且是show状态, 则播放
+      if (props.show) {
+        onToggleAudio('play');
+      }
+      emit('loadedmetadata');
+    };
+
+    /** 改变播放时间 */
+    const handleChangeTime = (val: number) => {
+      data.currentTime = val;
+      clearTimeout(data.timer);
+      data.timer = setTimeout(() => {
+        elRef.value.currentTime = val;
+        data.timer = null;
+      }, 300);
+    };
+
+    /** 播放结束 */
+    const onEnded = () => {
+      data.playState = 'pause';
+      emit('ended');
+    };
+    onMounted(() => {
+      console.log('加载');
+    });
+    return () => (
+      <div class={styles.videoWrap}>
+        <div class={styles.content}>
+          <div ref={contetRef} class={styles.contentWrap}>
+            <video
+              src={isEmtry.value ? '' : item.value.content}
+              ref={elRef}
+              loop={data.loop}
+              onLoadedmetadata={onLoadedmetadata}
+              onTimeupdate={() => {
+                if (data.timer) return;
+                data.currentTime = elRef.value.currentTime;
+              }}
+              onEnded={onEnded}
+              playsinline="false"></video>
+          </div>
+        </div>
+
+        <div class={[styles.controls, props.showModel ? '' : styles.hide]}>
+          <div class={styles.time}>
+            <div>{getSecondRPM(data.currentTime)}</div>
+            <div>{getSecondRPM(data.duration)}</div>
+          </div>
+          <div class={styles.slider}>
+            <NSlider
+              tooltip={false}
+              step={0.01}
+              class={styles.timeProgress}
+              value={data.currentTime}
+              max={data.duration}
+              onUpdate:value={val => handleChangeTime(val)}
+            />
+          </div>
+          <div class={styles.actions}>
+            <div
+              class={styles.actionBtn}
+              onClick={() =>
+                onToggleAudio(data.playState === 'pause' ? 'play' : 'pause')
+              }>
+              <img src={data.playState === 'pause' ? iconplay : iconpause} />
+            </div>
+            <div
+              class={styles.actionBtn}
+              onClick={() => (data.loop = !data.loop)}>
+              <img src={data.loop ? iconLoopActive : iconLoop} />
+            </div>
+          </div>
+        </div>
+      </div>
+    );
+  }
+});

+ 20 - 3
src/views/courseware-play/component/video-play.tsx

@@ -8,6 +8,7 @@ import iconLoop from '../image/icon-loop.svg'
 import iconLoopActive from '../image/icon-loop-active.svg'
 import iconplay from '../image/icon-play.svg'
 import iconpause from '../image/icon-pause.svg'
+import { watch } from 'vue'
 
 export default defineComponent({
   name: 'video-play',
@@ -21,6 +22,10 @@ export default defineComponent({
     isEmtry: {
       type: Boolean,
       default: false
+    },
+    show: {
+      type: Boolean,
+      default: false
     }
   },
   emits: ['loadedmetadata', 'togglePlay', 'ended', 'reset'],
@@ -99,8 +104,9 @@ export default defineComponent({
             </div>`
 
     onMounted(() => {
+      console.log('onMounted')
       videoItem.value = new Plyr(videoRef.value, {
-        autoplay: true,
+        autoplay: props.item.autoPlay,
         controls: controls,
         autopause: true, // 一次只允许
         ratio: '16:9', // 强制所有视频的纵横比
@@ -118,8 +124,6 @@ export default defineComponent({
           // console.log('开始播放', item.value)
           if (!item.value.autoPlay && !item.value.isprepare && videoItem.value) {
             // 加载完成后,取消静音播放
-            
-            console.log(videoItem.value)
             videoItem.value.pause()
           }
           changePlayBtn('')
@@ -134,6 +138,7 @@ export default defineComponent({
           changePlayBtn('play')
         })
         videoItem.value.once('loadedmetadata', (e: Event) => {
+          console.log('loadedmetadata')
           changePlayBtn('play')
           if (item.value.autoPlay && videoItem.value) {
             videoItem.value.play()
@@ -150,6 +155,18 @@ export default defineComponent({
       changePlayBtn,
       toggleHideControl
     })
+
+    /** 监听当前元素是否显示 */
+    watch(
+      () => props.show,
+      val => {
+        if (val) {
+          videoItem.value?.play();
+        } else {
+          videoItem.value?.pause()
+        }
+      }
+    );
     return () => (
       <div class={styles.videoWrap}>
         <video

+ 77 - 235
src/views/courseware-play/index.tsx

@@ -16,7 +16,8 @@ import { useRoute, useRouter } from 'vue-router';
 import {
   listenerMessage,
   postMessage,
-  promisefiyPostMessage
+  promisefiyPostMessage,
+  removeListenerMessage
 } from '@/helpers/native-message';
 import MusicScore from './component/musicScore';
 import iconMenu from './image/icon-menu.svg';
@@ -28,29 +29,17 @@ import Points from './component/points';
 import { browser, getSecondRPM } from '@/helpers/utils';
 import { Vue3Lottie } from 'vue3-lottie';
 import playLoadData from './datas/data.json';
-import { usePageVisibility, useRect } from '@vant/use';
+import { usePageVisibility } from '@vant/use';
 import VideoPlay from './component/video-play';
-import Tool, { ToolItem, ToolType } from './component/tool';
 import AudioItem from './component/audio-item';
 import { api_lessonCoursewareKnowledgeDetailDetail } from './api';
+import VideoItem from './component/video-item';
 
 export default defineComponent({
   name: 'CoursewarePlay',
   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.videoEle?.paused;
-        togglePlay(activeItem, false);
-      } else {
-        // 页面显示,并且
-        if (isPlay.value) togglePlay(activeItem, true);
-      }
-    });
+
     /** 设置播放容器 16:9 */
     const parentContainer = reactive({
       width: '100vw'
@@ -110,15 +99,10 @@ export default defineComponent({
     });
 
     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[]
     });
     const activeData = reactive({
@@ -132,24 +116,6 @@ export default defineComponent({
       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 () => {
       const res = await api_lessonCoursewareKnowledgeDetailDetail({
         lessonCoursewareKnowledgeDetailId: route.query.id
@@ -162,14 +128,16 @@ export default defineComponent({
           };
         });
       }
-      popupData.itemActive = data.knowledgePointList[0].id;
-      popupData.itemName = data.knowledgePointList[0].name;
       data.itemList = data.knowledgePointList.map((m: any, index: number) => {
+        if (!popupData.itemActive) {
+          popupData.itemActive = m.id;
+          popupData.itemName = m.name;
+        }
         return {
           ...m,
           iframeRef: null,
           videoEle: null,
-          autoPlay: false, //加载完成是否自动播放
+          autoPlay: index === 0, //加载完成是否自动播放
           isprepare: false, // 视频是否加载完成
           isRender: false // 是否渲染了
         };
@@ -209,31 +177,10 @@ export default defineComponent({
     const popupData = reactive({
       open: false,
       activeIndex: 0,
-      tabActive: '',
-      tabName: '',
       itemActive: '',
-      itemName: '',
-      guideOpen: false,
-      toolOpen: false // 工具弹窗控制
+      itemName: ''
     });
 
-    /**停止所有的播放 */
-    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);
@@ -245,51 +192,18 @@ export default defineComponent({
     const setModelOpen = () => {
       clearTimeout(activeData.timer);
       closeToast();
+      activeData.model = true;
       activeData.timer = setTimeout(() => {
         activeData.model = false;
-        Object.values(data.videoRefs).map((n: any) =>
-          n.toggleHideControl(false)
-        );
       }, 4000);
     };
-    /** 立即收起所有的模态框 */
-    const clearModel = () => {
-      clearTimeout(activeData.timer);
-      closeToast();
-      activeData.model = false;
-      Object.values(data.videoRefs).map((n: any) => n.toggleHideControl(false));
-    };
-    const toggleModel = (type: boolean = 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) {
-            closeToast();
-            videoEle.play();
-          } else {
-            showToast('已暂停');
-            videoEle.pause();
-          }
-        }
+      if (item && ['VIDEO'].includes(item.type)) {
+        console.log('双击');
       }
     };
-
-    // 切换播放
-    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 = [
       {
@@ -354,62 +268,12 @@ export default defineComponent({
     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);
-              closeToast();
-              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;
+      popupData.activeIndex = index;
+      popupData.itemActive = item.id;
+      if (item.type == 'MUSIC') {
+        activeData.model = true;
       }
     };
 
@@ -424,29 +288,14 @@ export default defineComponent({
 
     /** 弹窗关闭 */
     const handleClosePopup = () => {
-      const item = data.itemList[popupData.activeIndex];
-      if (item?.type == 'VIDEO' && !item.videoEle?.paused) {
-        setModelOpen();
-      }
+      setModelOpen();
     };
-
     return () => (
       <div id="playContent" class={styles.playContent}>
-        <div
-          onClick={() => {
-            clearTimeout(activeData.timer);
-            activeData.model = !activeData.model;
-            Object.values(data.videoRefs).map((n: any) =>
-              n.toggleHideControl(activeData.model)
-            );
-          }}>
+        <div onClick={() => setModelOpen()} onTouchmove={() => setModelOpen()}>
           <div
             class={styles.coursewarePlay}
-            style={{ width: parentContainer.width }}
-            onClick={(e: Event) => {
-              e.stopPropagation();
-              setModelOpen();
-            }}>
+            style={{ width: parentContainer.width }}>
             <div class={styles.wraps}>
               {data.itemList.map((m: any, mIndex: number) => {
                 const isRender =
@@ -474,94 +323,87 @@ export default defineComponent({
                         : {}
                     }
                     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' ? (
-                      <>
-                        <VideoPlay
-                          ref={(v: any) => (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 ||
-                              popupData.guideOpen
-                            ) {
-                              clearTimeout(activeData.timer);
-                            } else {
-                              setModelOpen();
-                            }
-                          }}
-                          onEnded={() => {
-                            const _index = popupData.activeIndex + 1;
-                            if (_index < data.itemList.length) {
-                              handleSwipeChange(_index);
-                            }
-                          }}
-                          onReset={() => {
-                            if (!m.videoEle?.paused) {
-                              setModelOpen();
-                            }
-                          }}
-                        />
-                        <Transition name="van-fade">
-                          {!m.isprepare && (
-                            <div class={styles.loadWrap}>
-                              <Vue3Lottie
-                                animationData={playLoadData}></Vue3Lottie>
-                            </div>
-                          )}
-                        </Transition>
-                      </>
-                    ) : m.type === 'IMG' ? (
-                      <img src={m.content} />
-                    ) : m.type === 'SONG' ? (
+                    {m.type === 'IMG' && <img src={m.content} />}
+                    {m.type === 'VIDEO' && (
+                      <VideoItem
+                        item={m}
+                        show={popupData.activeIndex === mIndex}
+                        pageVisibility={pageVisibility.value}
+                        showModel={activeData.model}
+                        isEmtry={isEmtry}
+                        onLoadedmetadata={() => {
+                          m.isprepare = true;
+                        }}
+                        onEnded={() => {
+                          const _index = popupData.activeIndex + 1;
+                          if (_index < data.itemList.length) {
+                            handleSwipeChange(_index);
+                          }
+                        }}
+                      />
+                    )}
+                    {m.type === 'SONG' && (
                       <AudioItem
                         item={m}
                         show={popupData.activeIndex === mIndex}
+                        pageVisibility={pageVisibility.value}
                         showModel={activeData.model}
                         isEmtry={isEmtry}
                         onEnded={() => {
                           const _index = popupData.activeIndex + 1;
-                          console.log('🚀 ~ _index:', _index);
                           if (_index < data.itemList.length) {
                             handleSwipeChange(_index);
                           }
                         }}
                       />
-                    ) : (
+                    )}
+                    {m.type === 'MUSIC' && (
                       <MusicScore
+                        pageVisibility={pageVisibility.value}
+                        show={popupData.activeIndex === mIndex}
                         activeModel={activeData.model}
                         data-vid={m.id}
                         music={m}
-                        onSetIframe={(el: any) => {
-                          m.iframeRef = el;
-                        }}
                       />
                     )}
+
+                    {m.type === 'VIDEO' && (
+                      <Transition name="van-fade">
+                        {!m.isprepare && (
+                          <div class={styles.loadWrap}>
+                            <Vue3Lottie
+                              style={{ width: '100%', height: '100%' }}
+                              animationData={playLoadData}></Vue3Lottie>
+                          </div>
+                        )}
+                      </Transition>
+                    )}
                   </div>
-                ) : null;
+                ) : (
+                  <div
+                    key={'index' + mIndex}
+                    class={[
+                      styles.itemDiv,
+                      popupData.activeIndex === mIndex && styles.itemActive,
+                      activeData.isAnimation && styles.acitveAnimation,
+                      Math.abs(popupData.activeIndex - mIndex) < 2
+                        ? styles.show
+                        : styles.hide
+                    ]}
+                    style={
+                      mIndex < popupData.activeIndex
+                        ? effects[effectIndex.value].prev
+                        : mIndex > popupData.activeIndex
+                        ? effects[effectIndex.value].next
+                        : {}
+                    }></div>
+                );
               })}
             </div>
             <Transition name="right">