9 次代碼提交 bd2e2bf8f4 ... 3c4b8d8b5f

作者 SHA1 備註 提交日期
  liushengqiang 3c4b8d8b5f 不自动跳 1 年之前
  liushengqiang e591979a97 fix 1 年之前
  liushengqiang 63ff198cef fix 1 年之前
  liushengqiang 1e9101e3e9 fix 1 年之前
  liushengqiang 4d89e6f1f9 循环播放,抖动 1 年之前
  liushengqiang 5b7613e572 动画时机 1 年之前
  liushengqiang d8a7b0b9f4 显示 1 年之前
  liushengqiang 4de9fd04bb 显示加载中 1 年之前
  liushengqiang a09e3176f6 课件播放 1 年之前
共有 2 個文件被更改,包括 132 次插入33 次删除
  1. 50 28
      src/views/courseware-play/component/video-item/index.tsx
  2. 82 5
      src/views/courseware-play/index.tsx

+ 50 - 28
src/views/courseware-play/component/video-item/index.tsx

@@ -44,7 +44,7 @@ export default defineComponent({
       default: false
     }
   },
-  emits: ['loadedmetadata', 'togglePlay', 'ended', 'reset', 'close', 'error'],
+  emits: ['canplay', 'pause', 'togglePlay', 'ended', 'reset', 'close', 'error'],
   setup(props, { emit, expose }) {
     const videoID = 'video' + Date.now() + Math.floor(Math.random() * 100);
     const videoItem = ref();
@@ -119,7 +119,7 @@ export default defineComponent({
       if (videoItem.value) {
         console.log(videoItem.value);
         videoItem.value.poster(props.item.coverImg); // 封面
-        videoItem.value.src(isEmtry.value ? '' : item.value.content); // url 播放地址
+        videoItem.value.src(item.value.content); // url 播放地址
 
         // 初步加载时
         videoItem.value.one('loadedmetadata', (e: any) => {
@@ -128,7 +128,17 @@ export default defineComponent({
           // 获取时长
           data.duration = videoItem.value.duration();
 
-          emit('loadedmetadata', videoItem.value);
+          emit('canplay', videoItem.value);
+        });
+        // 视频开始播放
+        videoItem.value.on('play', () => {
+          emit('close')
+          emit('canplay')
+        });
+        //
+        videoItem.value.on('pause', () => {
+          data.playState = 'pause';
+          emit('pause')
         });
 
         // 视频播放时加载
@@ -136,24 +146,20 @@ export default defineComponent({
           if (data.timer) return;
           data.currentTime = videoItem.value.currentTime();
         });
-
         // 视频播放结束
         videoItem.value.on('ended', () => {
           data.playState = 'pause';
-          emit('ended');
-        });
-
-        //
-        videoItem.value.on('pause', () => {
-          data.playState = 'pause';
-        });
+          // emit('ended');
+        });     
 
         videoItem.value.on('playing', () => {
           data.playState = 'play';
         });
 
         videoItem.value.on('canplay', (e: any) => {
-          console.log('canplay', e);
+          console.log('canplay', );
+          data.duration = videoItem.value.duration();
+          emit('canplay')
         });
 
         // 视频播放异常
@@ -164,27 +170,36 @@ export default defineComponent({
       }
     };
 
+    watch(() => props.item, (val, oldVal) => {
+      videoItem.value.currentTime(0)
+      videoItem.value.poster(props.item.coverImg); // 封面
+      videoItem.value.src(item.value.content); // url 播放地址
+      data.playState = 'pause';
+    })
+
     onMounted(() => {
       __init();
     });
 
+    const pause = () => {
+      videoItem.value.pause();
+    }
+
     expose({
-      onPlay
+      onPlay,
+      pause
     });
     return () => (
       <div class={styles.videoWrap}>
         <div class={styles.content}>
           <div ref={contetRef} class={styles.contentWrap}>
-            {!data.reload && (
-              <video
-                style={{ width: '100%', height: '100%' }}
-                poster={props.item.coverImg}
-                src={isEmtry.value ? '' : item.value.content}
-                id={videoID}
-                preload="auto"
-                playsinline
-                webkit-playsinline></video>
-            )}
+            <video
+              style={{ width: '100%', height: '100%' }}
+              id={videoID}
+              preload="auto"
+              playsinline
+              webkit-playsinline
+              x5-video-player-type="h5"></video>
           </div>
           <div class={styles.videoSection}></div>
         </div>
@@ -193,10 +208,14 @@ export default defineComponent({
           class={[styles.controls, props.showModel ? '' : styles.hide]}
           onClick={(e: Event) => {
             e.stopPropagation();
+            if(videoItem.value.paused()) return
+            emit('close')
+          }} 
+          onTouchmove={(e: Event) => {
+            if(videoItem.value.paused()) return
+            emit('close')
           }}
-          onTouchmove={(e: TouchEvent) => {
-            emit('close');
-          }}>
+          >
           <div class={styles.time}>
             <div>{getSecondRPM(data.currentTime)}</div>
             <div>{getSecondRPM(data.duration)}</div>
@@ -211,7 +230,7 @@ export default defineComponent({
               onUpdate:value={val => handleChangeTime(val)}
             />
           </div>
-          <div class={styles.actions} onClick={() => emit('close')}>
+          <div class={styles.actions}>
             <div
               class={styles.actionBtn}
               onClick={() =>
@@ -221,7 +240,10 @@ export default defineComponent({
             </div>
             <div
               class={styles.actionBtn}
-              onClick={() => (data.loop = !data.loop)}>
+              onClick={() => {
+                data.loop = !data.loop
+                videoItem.value.loop(data.loop)
+              }}>
               <img src={data.loop ? iconLoopActive : iconLoop} />
             </div>
           </div>

+ 82 - 5
src/views/courseware-play/index.tsx

@@ -143,7 +143,11 @@ export default defineComponent({
       knowledgePointList: [] as any,
       courseDetails: [] as any,
       itemList: [] as any,
-      videoRefs: {} as any[]
+      videoRefs: {} as any[],
+
+      videoState: 'init' as 'init' | 'play',
+      videoItemRef: null as any,
+      animationState: 'start' as 'start' | 'end'
     });
     const activeData = reactive({
       isAutoPlay: true, // 是否自动播放
@@ -222,6 +226,10 @@ export default defineComponent({
           isRender: false // 是否渲染了
         };
       });
+
+      setTimeout(() => {
+        data.animationState = 'end'
+      }, 500)
     };
 
     // ifram事件处理
@@ -284,6 +292,14 @@ export default defineComponent({
         activeData.model = false;
       }, 4000);
     };
+    const setModelOpen1 = () => {
+      clearTimeout(activeData.timer);
+      closeToast();
+      activeData.model = true;
+      activeData.timer = setTimeout(() => {
+        activeData.model = false;
+      }, 4000);
+    };
 
     // 双击
     const handleDbClick = (item: any) => {
@@ -351,13 +367,19 @@ export default defineComponent({
         current: { transitionDelay: '700ms' }
       }
     ];
-
+    const handleStop = () => {
+      data.videoItemRef.pause();
+    }
     const acitveTimer = ref();
     // 轮播切换
     const handleSwipeChange = (index: number) => {
       // 如果是当前正在播放 或者是视频最后一个
       if (popupData.activeIndex == index) return;
+      data.animationState = 'start'
+      data.videoState = 'init'
+      handleStop();
       clearTimeout(acitveTimer.value);
+      activeData.model = true;
       const item = data.itemList[index];
       popupData.activeIndex = index;
       popupData.itemActive = item.id;
@@ -368,6 +390,9 @@ export default defineComponent({
         if (item.error) {
           data.videoRefs[index]?.onPlay();
         }
+        setTimeout(() => {
+          data.animationState = 'end'
+        }, 800)
       }
     };
 
@@ -705,6 +730,14 @@ export default defineComponent({
 
       return false;
     });
+
+    const activeVideoItem = computed(() => {
+      const item = data.itemList[popupData.activeIndex]
+      if (item && item.type && item.type.toLocaleUpperCase() === 'VIDEO') {
+        return item
+      }
+      return {}
+    })
     return () => (
       <div id="playContent" class={styles.playContent}>
         <div
@@ -713,6 +746,40 @@ export default defineComponent({
           onClick={() => setModelOpen()}>
           {!loadingClass.value && (
             <div class={styles.wraps}>
+              <div
+                style={
+                  activeVideoItem.value.type &&
+                  data.animationState === 'end' &&
+                  data.videoState === 'play'
+                    ? {
+                        zIndex: 15,
+                        opacity: 1
+                      }
+                    : { opacity: 0, zIndex: -1 }
+                }
+                class={styles.itemDiv}
+              >
+                <VideoItem
+                  ref={(el: any) => data.videoItemRef = el}
+                  item={activeVideoItem.value}
+                  showModel={activeData.model}
+                  onClose={setModelOpen1}
+
+                  onCanplay={() => {
+                    data.videoState = 'play'
+                  }}
+                  onPause={() => {
+                    clearTimeout(activeData.timer)
+                    activeData.model = true
+                  }}
+                  onEnded={() => {
+                    // const _index = popupData.activeIndex + 1
+                    // if (_index < data.itemList.length) {
+                    //   handleSwipeChange(_index);
+                    // }
+                  }}
+                />
+              </div>
               {data.itemList.map((m: any, mIndex: number) => {
                 const isRender =
                   m.isRender || Math.abs(popupData.activeIndex - mIndex) < 2;
@@ -746,7 +813,10 @@ export default defineComponent({
                       activeData.nowTime = Date.now();
                     }}>
                     {m.type === 'IMG' && <img src={m.content} />}
-                    {m.type === 'VIDEO' && (
+                    {m.type === 'VIDEO' && <img src={m.coverImg} onLoad={() => {
+                      m.isprepare = true;
+                    }} />}
+                    {/* {m.type === 'VIDEO' && (
                       <VideoItem
                         ref={(v: any) => (data.videoRefs[mIndex] = v)}
                         item={m}
@@ -772,7 +842,7 @@ export default defineComponent({
                           m.error = true;
                         }}
                       />
-                    )}
+                    )} */}
                     {m.type === 'SONG' && (
                       <AudioItem
                         item={m}
@@ -806,7 +876,14 @@ export default defineComponent({
 
                     {m.type === 'VIDEO' && (
                       <Transition name="van-fade">
-                        {!m.isprepare && (
+                        {/* {!m.isprepare && (
+                          <div class={styles.loadWrap}>
+                            <Vue3Lottie
+                              style={{ width: '100%', height: '100%' }}
+                              animationData={playLoadData}></Vue3Lottie>
+                          </div>
+                        )} */}
+                        {data.videoState !== 'play' && (
                           <div class={styles.loadWrap}>
                             <Vue3Lottie
                               style={{ width: '100%', height: '100%' }}