Browse Source

课后训练播放

skyblued 2 years ago
parent
commit
8cbeaa6f8a
2 changed files with 127 additions and 176 deletions
  1. 26 9
      src/views/exercise-after-class/index.module.less
  2. 101 167
      src/views/exercise-after-class/index.tsx

+ 26 - 9
src/views/exercise-after-class/index.module.less

@@ -18,7 +18,7 @@
     left: 0;
     right: 0;
     z-index: 1;
-    padding: 10px;
+    padding: 10px 24px;
     display: flex;
     align-items: center;
     color: #fff;
@@ -68,6 +68,20 @@
       object-fit: contain;
     }
   }
+  .videoModel{
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    & > img{
+      width: 50px;
+      height: 50px;
+    }
+  }
   .rightFixedBtns {
     position: fixed;
     top: 50%;
@@ -113,28 +127,31 @@
     bottom: 0;
     z-index: 10;
     background: linear-gradient(0deg, rgba(0, 0, 0, 0.5), transparent);
+    padding: 0 30px;
     .time {
       display: flex;
       justify-content: space-between;
       color: #fff;
       font-size: 10px;
-      padding: 4px 10px;
+      padding: 4px 0;
     }
     .slider {
-      padding: 8px 10px;
+      padding: 10px 0;
     }
     .actions {
       display: flex;
       justify-content: space-between;
       color: #fff;
       font-size: 12px;
-      padding: 8px 10px;
       align-items: center;
-      :global {
-        .van-icon {
-          font-size: 20px;
-          margin-right: 14px;
-        }
+      .actionBtn{
+        display: flex;
+      }
+      .actionBtn > img {
+        width: 26px;
+        height: 26px;
+        display: block;
+        padding: 8px 8px 14px 8px;
       }
     }
   }

+ 101 - 167
src/views/exercise-after-class/index.tsx

@@ -1,9 +1,6 @@
 import {
-  closeToast,
   Icon,
-  Popup,
   showConfirmDialog,
-  showToast,
   Slider,
   Swipe,
   SwipeItem
@@ -12,12 +9,10 @@ import {
   defineComponent,
   onMounted,
   reactive,
-  nextTick,
   onUnmounted,
   ref,
   watch,
   Transition,
-  computed
 } from 'vue'
 import styles from './index.module.less'
 import 'plyr/dist/plyr.css'
@@ -72,10 +67,13 @@ export default defineComponent({
     })
 
     const route = useRoute()
-    watch(() => route.query, () => {
-      getDetail()
-      trainingRecord()
-    })
+    watch(
+      () => route.query,
+      () => {
+        getDetail()
+        trainingRecord()
+      }
+    )
     const router = useRouter()
     const query = route.query
     const browserInfo = browser()
@@ -95,20 +93,6 @@ export default defineComponent({
       timer: null as any,
       item: null as any
     })
-    // 获取缓存路径
-    const getCacheFilePath = async (material: any) => {
-      const res = await promisefiyPostMessage({
-        api: 'getCourseFilePath',
-        content: {
-          url: material.content,
-          localPath: '',
-          materialId: material.id,
-          updateTime: material.updateTime,
-          type: material.type
-        }
-      })
-      return res
-    }
     const getDetail = async () => {
       let details = []
       try {
@@ -129,16 +113,6 @@ export default defineComponent({
         try {
           videoData.training = JSON.parse(videoData?.lessonTrainingTemp?.trainingConfigJson)
         } catch (error) {}
-        //请求本地缓存
-        if (browserInfo.isApp && videoData.updateTime && ['VIDEO'].includes(videoData.type)) {
-          console.log('开始检查本地缓存')
-          const localData = await getCacheFilePath(videoData)
-          console.log("🚀 ~ 本地缓存数据", localData)
-          if (localData?.content?.localPath) {
-            videoData.url = videoData.content
-            videoData.content = localData.content.localPath
-          }
-        }
         data.itemList.push({
           ...videoData,
           id: videoData.materialId,
@@ -148,7 +122,9 @@ export default defineComponent({
           loop: false,
           videoEle: null,
           timer: null,
-          playModel: true
+          muted: true, // 静音
+          autoplay: true, //自动播放
+          firstFrame: false
         })
         popupData.itemActive = videoData.id
         popupData.tabName = videoData.materialName
@@ -199,27 +175,10 @@ export default defineComponent({
       itemName: ''
     })
 
-    // 双击
-    const handleDbClick = (item: any) => {
-      if (item && item.type === 'VIDEO') {
-        const videoEle: HTMLVideoElement = document.querySelector(`[data-vid='${item.id}']`)!
-        if (videoEle) {
-          if (videoEle.paused) {
-            closeToast()
-            videoEle.play()
-          } else {
-            showToast('已暂停')
-            videoEle.pause()
-          }
-        }
-        item.timer = setTimeout(() => {
-          activeData.model = false
-        }, 3000)
-      }
-    }
-
     // 达到指标,记录
     const addTrainingRecord = async (m: any) => {
+      if (data.recordLoading) return
+      console.log('记录观看次数')
       data.recordLoading = true
       const query = route.query
       const body = {
@@ -243,9 +202,7 @@ export default defineComponent({
         )
         trainingRecord()
       } catch (error) {}
-      setTimeout(() => {
-        data.recordLoading = false
-      }, 2000)
+      data.recordLoading = false
     }
     // 停止所有的播放
     const handleStopVideo = () => {
@@ -271,45 +228,50 @@ export default defineComponent({
           confirmButtonColor: 'var(--van-primary)',
           confirmButtonText: isLastIndex ? '完成' : '下一题',
           cancelButtonText: '继续'
-        }).then(() => {
-          if (!isLastIndex) {
-            const nextItem = data.details[itemIndex + 1]
-            if (nextItem?.type === materialType.视频) {
-              console.log('下一题视频',data.details[itemIndex].materialId, nextItem.materialId)
-              router.replace({
-                path: '/exerciseAfterClass',
-                query: {
-                  ...query,
+        })
+          .then(() => {
+            if (!isLastIndex) {
+              const nextItem = data.details[itemIndex + 1]
+              if (nextItem?.type === materialType.视频) {
+                // console.log('下一题视频', data.details[itemIndex].materialId, nextItem.materialId)
+                router.replace({
+                  path: '/exerciseAfterClass',
+                  query: {
+                    ...query,
+                    materialId: nextItem.materialId
+                  }
+                })
+              }
+              if (nextItem?.type === materialType.曲目) {
+                handleInit(1)
+                goback()
+                const parmas = qs.stringify({
+                  id: nextItem.content,
+                  courseScheduleId: query.courseScheduleId,
+                  lessonTrainingId: query.lessonTrainingId,
                   materialId: nextItem.materialId
-                }
-              })
+                })
+                let src = `${location.origin}/orchestra-music-score/?` + parmas
+                // console.log("🚀 ~ src", src)
+                postMessage({
+                  api: 'openAccompanyWebView',
+                  content: {
+                    url: src,
+                    orientation: 0,
+                    isHideTitle: true,
+                    statusBarTextColor: false,
+                    isOpenLight: true
+                  }
+                })
+              }
             }
-            if (nextItem?.type === materialType.曲目) {
-              handleInit(1)
-              goback()
-              const parmas = qs.stringify({
-                id: nextItem.content,
-                courseScheduleId: query.courseScheduleId,
-                lessonTrainingId: query.lessonTrainingId,
-                materialId: nextItem.materialId
-              })
-              let src = `${location.origin}/orchestra-music-score/?` + parmas
-              // console.log("🚀 ~ src", src)
-              postMessage({
-                api: 'openAccompanyWebView',
-                content: {
-                  url: src,
-                  orientation: 0,
-                  isHideTitle: true,
-                  statusBarTextColor: false,
-                  isOpenLight: true
-                }
-              })
-            }
-          }
-        })
+          })
+          .catch(() => {
+            data.details[itemIndex].currentTime = 0
+          })
       }
     }
+
     return () => (
       <div class={styles.coursewarePlay}>
         <Swipe
@@ -328,16 +290,8 @@ export default defineComponent({
                   <div
                     class={styles.itemDiv}
                     onClick={() => {
-                      clearTimeout(activeData.timer)
                       clearTimeout(m.timer)
-                      if (Date.now() - activeData.nowTime < 300) {
-                        handleDbClick(m)
-                        return
-                      }
-                      activeData.nowTime = Date.now()
-                      activeData.timer = setTimeout(() => {
-                        activeData.model = !activeData.model
-                      }, 300)
+                      activeData.model = !activeData.model
                     }}
                   >
                     <video
@@ -348,101 +302,81 @@ export default defineComponent({
                       data-vid={m.id}
                       src={m.content}
                       loop={m.loop}
-                      onLoadedmetadata={(e: Event) => {
+                      autoplay={m.autoplay}
+                      muted={m.muted}
+                      onLoadedmetadata={async (e: Event) => {
                         const videoEle = e.target as unknown as HTMLVideoElement
-                        m.currentTime = videoEle.currentTime
                         m.duration = videoEle.duration
                         m.videoEle = videoEle
                       }}
                       onTimeupdate={(e: Event) => {
                         const videoEle = e.target as unknown as HTMLVideoElement
                         m.currentTime = videoEle.currentTime
-                        if (m.duration - m.currentTime < 1) {
-                          if (data.recordLoading) return
-                          console.log('完成观看次数')
-                          addTrainingRecord(m)
-                        }
                       }}
                       onPlay={() => {
                         // 播放
                         m.paused = false
+                        if (!m.firstFrame){
+                          m.firstFrame = true
+                          m.videoEle.pause()
+                        }
                       }}
                       onPause={() => {
                         //暂停
-                        clearTimeout(m.timer)
                         m.paused = true
                       }}
+                      onEnded={() => addTrainingRecord(m)}
                     >
                       <source src={m.content} type="video/mp4" />
                     </video>
-                    <Transition name="bottom">
-                      {activeData.model && (
-                        <div class={styles.bottomFixedContainer}>
-                          <div class={styles.time}>
-                            <span>{getSecondRPM(m.currentTime)}</span>
-                            <span>{getSecondRPM(m.duration)}</span>
-                          </div>
-                          <div class={styles.slider}>
+                  </div>
+                  <Transition name="bottom">
+                    {activeData.model && (
+                      <div class={styles.bottomFixedContainer}>
+                        <div class={styles.time}>
+                          <span>{getSecondRPM(m.currentTime)}</span>
+                          <span>{getSecondRPM(m.duration)}</span>
+                        </div>
+                        <div class={styles.slider}>
+                          {m.duration && (
                             <Slider
                               buttonSize={16}
-                              step={0.01}
                               modelValue={m.currentTime}
                               min={0}
                               max={m.duration}
                             />
-                          </div>
+                          )}
+                        </div>
 
-                          <div class={styles.actions}>
-                            <div>
-                              {m.paused ? (
-                                <Icon
-                                  name={iconplay}
-                                  onClick={(e: Event) => {
-                                    e.stopPropagation()
-                                    clearTimeout(m.timer)
-                                    closeToast()
-                                    m.videoEle?.play()
-                                    m.paused = false
-                                    m.timer = setTimeout(() => {
-                                      activeData.model = false
-                                    }, 3000)
-                                  }}
-                                />
-                              ) : (
-                                <Icon
-                                  name={iconpause}
-                                  onClick={(e: Event) => {
-                                    e.stopPropagation()
-                                    console.log('点击暂停')
-                                    m.videoEle?.pause()
-                                    m.paused = true
-                                  }}
-                                />
-                              )}
-                              {m.loop ? (
-                                <Icon
-                                  name={iconLoopActive}
-                                  onClick={(e: Event) => {
-                                    e.stopPropagation()
-                                    m.loop = false
-                                  }}
-                                />
-                              ) : (
-                                <Icon
-                                  name={iconLoop}
-                                  onClick={(e: Event) => {
-                                    e.stopPropagation()
-                                    m.loop = true
-                                  }}
-                                />
-                              )}
-                            </div>
-                            <div>{m.name}</div>
+                        <div class={styles.actions}>
+                          <div class={styles.actionBtn}>
+                            {m.paused ? (
+                              <img
+                                src={iconplay}
+                                onClick={(e: Event) => {
+                                  clearTimeout(m.timer)
+                                  m.videoEle?.play()
+                                  m.paused = false
+                                  m.timer = setTimeout(() => {
+                                    activeData.model = false
+                                  }, 4000)
+                                }}
+                              />
+                            ) : (
+                              <img
+                                src={iconpause}
+                                onClick={(e: Event) => {
+                                  clearTimeout(m.timer)
+                                  m.videoEle?.pause()
+                                  m.paused = true
+                                }}
+                              />
+                            )}
                           </div>
                         </div>
-                      )}
-                    </Transition>
-                  </div>
+                      </div>
+                    )}
+                  </Transition>
                 </>
               </SwipeItem>
             )