Browse Source

课件播放

liushengqiang 1 year ago
parent
commit
508c91f3f3

+ 40 - 7
src/views/attend-class/component/video-play.tsx

@@ -4,7 +4,8 @@ import {
   onMounted,
   onUnmounted,
   reactive,
-  toRefs
+  toRefs,
+  watch
 } from 'vue';
 import TCPlayer from 'tcplayer.js';
 import 'tcplayer.js/dist/tcplayer.min.css';
@@ -26,12 +27,16 @@ export default defineComponent({
         return {};
       }
     },
+    showModel: {
+      type: Boolean,
+      default: false
+    },
     isEmtry: {
       type: Boolean,
       default: false
     }
   },
-  emits: ['loadedmetadata', 'togglePlay', 'ended', 'reset', 'error'],
+  emits: ['canplay', 'pause', 'togglePlay', 'ended', 'reset', 'error', "close"],
   setup(props, { emit, expose }) {
     const { item, isEmtry } = toRefs(props);
     const videoFroms = reactive({
@@ -94,7 +99,8 @@ export default defineComponent({
         controls: false
       }); // player-container-id 为播放器容器 ID,必须与 html 中一致
       if (videoItem.value) {
-        videoItem.value.src(isEmtry.value ? '' : item.value.content); // url 播放地址
+        videoItem.value.poster(props.item.coverImg); // 封面
+        videoItem.value.src(item.value.content); // url 播放地址
 
         // 初步加载时
         videoItem.value.one('loadedmetadata', () => {
@@ -106,7 +112,13 @@ export default defineComponent({
           );
           videoFroms.durationNum = videoItem.value.duration();
 
-          emit('loadedmetadata', videoItem.value);
+          emit('canplay', videoItem.value);
+        });
+
+        // 视频开始播放
+        videoItem.value.on('play', () => {
+          emit('close')
+          emit('canplay')
         });
 
         // 视频播放时加载
@@ -126,12 +138,23 @@ export default defineComponent({
         //
         videoItem.value.on('pause', () => {
           videoFroms.paused = true;
+          emit('pause')
         });
 
         videoItem.value.on('playing', () => {
           videoFroms.paused = false;
         });
 
+        videoItem.value.on('canplay', (e: any) => {
+          console.log('canplay', );
+          // 获取时长
+          videoFroms.duration = timeFormat(
+            Math.round(videoItem.value.duration())
+          );
+          videoFroms.durationNum = videoItem.value.duration();
+          emit('canplay')
+        });
+
         // 视频播放异常
         videoItem.value.on('error', (e: any) => {
           emit('error');
@@ -151,6 +174,14 @@ export default defineComponent({
         videoItem.value.dispose();
       }
     });
+
+    watch(() => props.item, (val, oldVal) => {
+      videoItem.value.pause();
+      videoItem.value.currentTime(0)
+      videoItem.value.poster(props.item.coverImg); // 封面
+      videoItem.value.src(item.value.content); // url 播放地址
+      videoFroms.paused = true;
+    })
     expose({
       onPlay,
       stop,
@@ -161,20 +192,22 @@ export default defineComponent({
       <div class={styles.videoWrap}>
         <video
           style={{ width: '100%', height: '100%' }}
-          src={isEmtry.value ? '' : item.value.content}
           ref={videoRef}
           id={videoID.value}
           preload="auto"
           playsinline
-          webkit-playsinline></video>
+          webkit-playsinline 
+          x5-video-player-type="h5"></video>
 
         <div
           class={[
             styles.controls,
-            videoFroms.showBar ? '' : styles.sectionAnimate
+            props.showModel ? '' : styles.sectionAnimate
           ]}
           onClick={(e: MouseEvent) => {
             e.stopPropagation();
+            if (videoItem.value.paused()) return;
+            emit('close');
             emit('reset');
           }}>
           <div class={styles.actions}>

+ 1 - 1
src/views/attend-class/index.module.less

@@ -348,7 +348,7 @@
   padding: 0 40px;
   height: 126px;
   background-color: rgba(0, 0, 0, 0.7);
-  pointer-events: none;
+  // pointer-events: none;
 
   .switchSpace {
     gap: 0 48px !important;

+ 62 - 9
src/views/attend-class/index.tsx

@@ -169,7 +169,11 @@ export default defineComponent({
       homeworkStatus: true, // 布置作业完成时
       removeVisiable: false,
       removeTitle: '',
-      removeContent: ''
+      removeContent: '',
+
+      videoState: 'init' as 'init' | 'play',
+      videoItemRef: null as any,
+      animationState: 'start' as 'start' | 'end'
     });
     const activeData = reactive({
       // isAutoPlay: false, // 是否自动播放
@@ -219,6 +223,9 @@ export default defineComponent({
             isRender: false // 是否渲染了
           };
         });
+        setTimeout(() => {
+          data.animationState = 'end'
+        }, 500)
       } catch {
         //
       }
@@ -537,8 +544,11 @@ export default defineComponent({
     const handleSwipeChange = (index: number) => {
       // 如果是当前正在播放 或者是视频最后一个
       if (popupData.activeIndex == index) return;
+      data.animationState = 'start'
+      data.videoState = 'init'
       handleStop();
       clearTimeout(acitveTimer.value);
+      activeData.model = true;
       checkedAnimation(popupData.activeIndex, index);
       popupData.activeIndex = index;
 
@@ -569,6 +579,7 @@ export default defineComponent({
                   item.error = false;
                   //   item.videoEle?.onPlay();
                 }
+                data.animationState = 'end'
               });
             }
           }
@@ -1016,7 +1027,13 @@ 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, 'wrap']}>
         <div
@@ -1032,13 +1049,43 @@ export default defineComponent({
           }}>
           <div
             class={styles.coursewarePlay}
-            style={{ width: parentContainer.width }}
-            onClick={(e: Event) => {
-              e.stopPropagation();
-              setModelOpen();
-            }}>
+            style={{ width: parentContainer.width }}>
             {!popupData.chapterLoading ? (
               <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}
+                >
+                  <VideoPlay
+                    ref={(el: any) => data.videoItemRef = el}
+                    item={activeVideoItem.value}
+                    showModel={activeData.model}
+                    onClose={setModelOpen}
+
+                    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 = Math.abs(popupData.activeIndex - mIndex) < 2;
                   const isEmtry = Math.abs(popupData.activeIndex - mIndex) > 4;
@@ -1087,7 +1134,10 @@ export default defineComponent({
                       }}>
                       {m.type === 'VIDEO' ? (
                         <>
-                          <VideoPlay
+                          <img src={m.coverImg} onLoad={() => {
+                            m.isprepare = true;
+                          }} />
+                          {/* <VideoPlay
                             ref={(v: any) => (data.videoRefs[mIndex] = v)}
                             item={m}
                             isEmtry={isEmtry}
@@ -1112,7 +1162,7 @@ export default defineComponent({
                               console.log('video error');
                               m.error = true;
                             }}
-                          />
+                          /> */}
                           <Transition name="van-fade">
                             {!m.isprepare && (
                               <div class={styles.loadWrap}>
@@ -1184,6 +1234,9 @@ export default defineComponent({
         <div
           onClick={(e: any) => {
             e.stopPropagation();
+            if (activeData.timer){
+              setModalOpen();
+            }
           }}
           class={[
             styles.switchDisplaySection,