浏览代码

添加禁止录屏功能

lex 11 月之前
父节点
当前提交
ae42fe615a

+ 1 - 8
src/views/courseware-play/component/audio-item/index.tsx

@@ -163,6 +163,7 @@ export default defineComponent({
       //     onInit(audioRef.value, canvasRef.value);
       //   };
       // }
+      emit('loadedmetadata', audioRef.value)
     };
 
     /** 改变播放时间 */
@@ -262,14 +263,6 @@ export default defineComponent({
             <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)}
-            /> */}
             <Slider
               step={0.01}
               class={styles.timeProgress}

+ 27 - 21
src/views/courseware-play/component/instrument-info/index.tsx

@@ -39,7 +39,7 @@ export default defineComponent({
     }
   },
   emits: ['close', 'select'],
-  setup(props, { emit }) {
+  setup(props, { emit, expose }) {
     const route = useRoute();
     const initDone = ref(false);
     const forms = reactive({
@@ -76,7 +76,7 @@ export default defineComponent({
             url: item.url
           };
         });
-      } catch {}
+      } catch { }
       forms.loading = false;
     };
 
@@ -115,6 +115,21 @@ export default defineComponent({
       }
     };
 
+    const onChangeAudioStop = () => {
+      handleChangeAudio('pause');
+      try {
+        // 暂停视频
+        const doms = document.querySelectorAll('.video-music');
+        if (doms && doms.length > 0) {
+          doms.forEach((dom: any) => {
+            dom.pause();
+          });
+        }
+      } catch {
+        //
+      }
+    }
+
     watch(
       () => props.show,
       val => {
@@ -124,24 +139,15 @@ export default defineComponent({
           forms.musicList = [];
           getDetail();
         } else {
-          //  audioRef.value.pause();
-          //  data.playState = 'pause';
-          handleChangeAudio('pause');
-          try {
-            // 暂停视频
-            const doms = document.querySelectorAll('.video-music');
-            if (doms && doms.length > 0) {
-              doms.forEach((dom: any) => {
-                dom.pause();
-              });
-            }
-          } catch {
-            //
-          }
+          onChangeAudioStop()
         }
       }
     );
 
+    expose({
+      onChangeAudioStop
+    })
+
     onMounted(async () => {
       await getDetail();
     });
@@ -223,7 +229,7 @@ export default defineComponent({
                         <div
                           class={[
                             forms.listActive === index &&
-                            forms.playState === 'play'
+                              forms.playState === 'play'
                               ? styles.playingIcon
                               : styles.hidePlayLoading
                           ]}>
@@ -270,10 +276,10 @@ export default defineComponent({
             {props.type === 'wiki'
               ? '名曲故事'
               : props.type === 'instrument'
-              ? '乐器简介'
-              : props.type === 'musician'
-              ? '个人简介'
-              : ''}
+                ? '乐器简介'
+                : props.type === 'musician'
+                  ? '个人简介'
+                  : ''}
           </div>
           <div class={styles.desc} v-html={forms.dataInfo.intros}></div>
           {!forms.loading && !forms.dataInfo.intros && (

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

@@ -46,7 +46,7 @@ export default defineComponent({
       default: false
     }
   },
-  emits: ['canplay', 'pause', 'togglePlay', 'ended', 'reset', 'close', 'error'],
+  emits: ['canplay', 'pause', 'togglePlay', 'ended', 'reset', 'close', 'error', 'loadedmetadata'],
   setup(props, { emit, expose }) {
     const videoID = 'video' + Date.now() + Math.floor(Math.random() * 100);
     const speedBtnId = 'speed' + Date.now() + Math.floor(Math.random() * 100);
@@ -144,6 +144,7 @@ export default defineComponent({
     };
 
     const __init = () => {
+      // videoEle
       if (videoItem.value) {
         // console.log(videoItem.value);
         videoItem.value.poster(props.item.coverImg); // 封面
@@ -155,7 +156,6 @@ export default defineComponent({
           data.reload = false;
           // 获取时长
           data.duration = videoItem.value.duration();
-
           emit('canplay', videoItem.value);
 
           if (item.value.autoPlay && videoItem.value) {
@@ -166,6 +166,7 @@ export default defineComponent({
               nextTick(handlePlayVideo);
             });
           }
+          emit('loadedmetadata', videoItem.value)
         });
         // 视频开始播放
         videoItem.value.on('play', () => {
@@ -210,7 +211,6 @@ export default defineComponent({
     watch(
       () => props.item,
       () => {
-        // console.log(props.item, 'watch ---- item');
         videoItem.value.pause();
         videoItem.value.currentTime(0);
         if (item.value?.id) {

+ 158 - 63
src/views/courseware-play/index.tsx

@@ -156,6 +156,7 @@ export default defineComponent({
     const headeRef = ref();
     const loadingClass = ref(false); // 重新加载课件
     const data = reactive({
+      disableScreenRecordingFlag: '0',
       allList: [] as any, // 所选章节下的所有课件列表
       kjId: route.query.id as string, // 所选的课件id
       currentCourse: {} as any, // 当前选中的课件
@@ -294,7 +295,6 @@ export default defineComponent({
           });
           allResource = allResource.concat(material.materialInfo);
         });
-        console.log(allResource, 'allResource');
       });
 
       // 当前章节下,所选的课件所有资源列表
@@ -325,6 +325,8 @@ export default defineComponent({
           ...m,
           iframeRef: null,
           videoEle: null,
+          audioEle: null,
+          domEle: null,
           autoPlay: showMember.value
             ? false
             : data.currentCourse.autoPlay || false, //加载完成是否自动播放
@@ -360,7 +362,82 @@ export default defineComponent({
       }
     };
 
-    onMounted(() => {
+    let timers: any = null
+    const checkVideoPlay = (activeItem: any) => {
+      const activeVideoRef = activeItem.type === 'VIDEO' ? activeItem.videoEle : activeItem.audioEle
+      if (activeVideoRef) {
+        timers = setInterval(() => {
+          const paused = activeItem.type === 'VIDEO' ? activeVideoRef.paused() : activeVideoRef.paused
+          if (!paused) {
+            activeVideoRef.pause()
+            clearInterval(timers)
+          }
+          activeVideoRef.pause()
+        }, 100)
+      }
+
+      setTimeout(() => {
+        clearInterval(timers)
+      }, 3000)
+    }
+    //录屏时间触发
+    const handleLimitScreenRecord = async () => {
+      const result = await promisefiyPostMessage({
+        api: 'getDeviceStatus',
+        content: { type: 'video' }
+      })
+      const { status } = result?.content || {}
+      if (status == '1') {
+        data.itemList.forEach((item: any) => (item.autoPlay = false))
+        handleStop()
+
+        const activeItem = data.itemList[popupData.activeIndex]
+        if (activeItem.type === 'VIDEO' || activeItem.type === 'SONG') {
+          // 处理事件 - 事件事件后加载的
+          checkVideoPlay(activeItem)
+        }
+
+        showDialog({
+          title: '温馨提示',
+          message: '课件内容请勿录屏',
+          beforeClose: () => {
+            return new Promise((resolve) => {
+              promisefiyPostMessage({
+                api: 'getDeviceStatus',
+                content: { type: 'video' }
+              }).then((res: any) => {
+                const content = res.content
+                if (content?.status == '1') {
+                  // const activeItem = data.itemList[popupData.activeIndex]
+                  // togglePlay(activeItem, false)
+                  resolve(false)
+                } else {
+                  // const activeItem = data.itemList[popupData.activeIndex]
+                  // togglePlay(activeItem, true)
+                  resolve(true)
+                }
+              })
+            })
+          }
+        })
+      }
+    }
+
+    // 获取支付渠道
+    const sysParamConfig = async () => {
+      try {
+        const res = await request.get('/edu-app/sysParamConfig/queryByParamName', {
+          params: {
+            paramName: 'disable_screen_recording_flag'
+          }
+        })
+        data.disableScreenRecordingFlag = res.data.paramValue || ''
+      } catch {
+        //
+      }
+    }
+    onMounted(async () => {
+      await sysParamConfig()
       // needVipLock
       const schoolInfos = state.user.data?.schoolInfos;
       const schoolLock =
@@ -383,6 +460,22 @@ export default defineComponent({
       getDetail();
       getCourseDetail();
       window.addEventListener('message', iframeHandle);
+
+      if (data.disableScreenRecordingFlag === '1') {
+        //禁止录屏 ios
+        listenerMessage('setVideoPlayer', (result) => {
+          if (result?.content?.status == 'pause') {
+            handleLimitScreenRecord()
+          }
+        })
+        // 安卓
+        postMessage({
+          api: 'limitScreenRecord',
+          content: {
+            type: 1
+          }
+        })
+      }
     });
 
     const playRef = ref();
@@ -510,7 +603,47 @@ export default defineComponent({
       }
     ];
     const handleStop = () => {
-      data.videoItemRef?.pause();
+      // data.videoItemRef?.pause();
+      for (let i = 0; i < data.itemList.length; i++) {
+        const activeItem = data.itemList[i];
+        if (activeItem.type === 'VIDEO' && activeItem.videoEle) {
+          activeItem.videoEle?.pause();
+        }
+        if (activeItem.type === 'SONG' && activeItem.audioEle) {
+          console.log(1111, '---------')
+          activeItem.audioEle?.pause();
+        }
+        // 停止曲谱的播放
+        if (activeItem.type === 'MUSIC') {
+          activeItem.iframeRef?.contentWindow?.postMessage(
+            { api: 'setPlayState' },
+            '*'
+          );
+        }
+
+        if (
+          activeItem.type === 'INSTRUMENT' ||
+          activeItem.type === 'MUSICIAN' ||
+          activeItem.type === 'MUSIC_WIKI'
+        ) {
+          activeItem.domEle?.onChangeAudioStop();
+        }
+
+        // console.log(activeItem.type, 'activeItem.type');
+        if (activeItem.type === 'RHYTHM') {
+          activeItem.iframeRef?.contentWindow?.postMessage(
+            { api: 'setPlayState', data: false },
+            '*'
+          );
+        }
+
+        if (activeItem.type === 'LISTEN') {
+          activeItem.iframeRef?.contentWindow?.postMessage(
+            { api: 'setPlayState' },
+            '*'
+          );
+        }
+      }
     };
     const acitveTimer = ref();
     // 轮播切换
@@ -584,22 +717,6 @@ export default defineComponent({
         }
         // 判断当前章节下面课程是否有内容,否则往上一个章节走
         if (lessonStatus) {
-          // loadingClass.value = true;
-          // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
-          // activeData.lessonCoursewareDetailId = lessonCoursewareDetailId;
-          // await getDetail();
-          // popupData.activeIndex = data.itemList.length - 1 || 0;
-          // popupData.itemActive =
-          //   data.knowledgePointList[data.itemList.length - 1]?.id ||
-          //   data.knowledgePointList[0]?.id;
-          // popupData.itemPointName = coursewareDetailKnowledgeName;
-          // popupData.itemName =
-          //   data.knowledgePointList[data.itemList.length - 1]?.name ||
-          //   data.knowledgePointList[0]?.name;
-          // localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId);
-          // popupData.chapterOpen = false;
-          // loadingClass.value = false;
-          // console.log
           temporaryData.zjId = coursewareDetailKnowledgeId;
           temporaryData.dyId = lessonCoursewareDetailId;
           // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
@@ -639,22 +756,6 @@ export default defineComponent({
 
         // 判断当前章节下面课程是否有内容,否则往上一个章节走
         if (prevLessonStatus) {
-          // loadingClass.value = true;
-          // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
-          // activeData.lessonCoursewareDetailId = lessonCoursewareDetailId;
-          // await getDetail();
-          // popupData.activeIndex = data.itemList.length - 1 || 0;
-          // popupData.itemActive =
-          //   data.knowledgePointList[data.itemList.length - 1]?.id ||
-          //   data.knowledgePointList[0]?.id;
-          // localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId);
-          // popupData.itemPointName = coursewareDetailKnowledgeName;
-          // popupData.itemName =
-          //   data.knowledgePointList[data.itemList.length - 1]?.name ||
-          //   data.knowledgePointList[0]?.name;
-          // popupData.chapterOpen = false;
-          // loadingClass.value = false;
-          // console.log('2', coursewareItem, coursewareDetailKnowledgeId);
           temporaryData.zjId = coursewareDetailKnowledgeId;
           temporaryData.dyId = lessonCoursewareDetailId;
           // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
@@ -704,17 +805,6 @@ export default defineComponent({
         }
         // 判断当前章节下面课程是否有内容,否则往下一个章节走
         if (lessonStatus) {
-          // loadingClass.value = true;
-          // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
-          // activeData.lessonCoursewareDetailId = lessonCoursewareDetailId;
-          // await getDetail();
-          // popupData.activeIndex = 0;
-          // popupData.itemActive = data.knowledgePointList[0].id;
-          // popupData.itemName = data.knowledgePointList[0].name;
-          // localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId);
-          // popupData.itemPointName = coursewareDetailKnowledgeName;
-          // popupData.chapterOpen = false;
-          // loadingClass.value = false;
           temporaryData.zjId = coursewareDetailKnowledgeId;
           temporaryData.dyId = lessonCoursewareDetailId;
           // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
@@ -754,17 +844,6 @@ export default defineComponent({
 
         // 判断当前章节下面课程是否有内容,否则往下一个单元走
         if (nextLessonStatus) {
-          // loadingClass.value = true;
-          // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
-          // activeData.lessonCoursewareDetailId = lessonCoursewareDetailId;
-          // await getDetail();
-          // popupData.activeIndex = 0;
-          // popupData.itemActive = data.knowledgePointList[0].id;
-          // localStorage.setItem(lastTimeKey, coursewareDetailKnowledgeId);
-          // popupData.itemName = data.knowledgePointList[0].name;
-          // popupData.itemPointName = coursewareDetailKnowledgeName;
-          // popupData.chapterOpen = false;
-          // loadingClass.value = false;
           temporaryData.zjId = coursewareDetailKnowledgeId;
           temporaryData.dyId = lessonCoursewareDetailId;
           // activeData.coursewareDetailKnowledgeId = coursewareDetailKnowledgeId;
@@ -783,9 +862,6 @@ export default defineComponent({
       // setModelOpen();
     };
 
-    // popupData.activeIndex == 0 && styles.btnsDisabled
-    // popupData.activeIndex == data.itemList.length - 1
-
     // 是否允许上一页
     const isUpArrow = computed(() => {
       /**
@@ -1011,14 +1087,12 @@ export default defineComponent({
     watch(
       () => pageVisibility.value,
       async (val: any) => {
-        console.log(val, 'pageVisibility.value -----');
+        // 为了处理从没有会员,到购买会员返回时状态变化
         if (val === 'visible') {
           const userCash = await request.get('/edu-app/user/getUserInfo', {
             initRequest: true // 初始化接口
           });
           setLogin(userCash.data);
-
-          console.log(userCash, 'userCash');
           const schoolInfos = userCash.data?.schoolInfos;
           const schoolLock =
             schoolInfos && schoolInfos.length > 0
@@ -1057,6 +1131,11 @@ export default defineComponent({
                   ref={(el: any) => (data.videoItemRef = el)}
                   item={activeVideoItem.value}
                   showModel={activeData.model}
+                  onLoadedmetadata={(videoItem: any) => {
+                    if (data.itemList[popupData.activeIndex]) {
+                      data.itemList[popupData.activeIndex].videoEle = videoItem;
+                    }
+                  }}
                   onClose={setModelOpen1}
                   onCanplay={() => {
                     data.videoState = 'play';
@@ -1157,6 +1236,10 @@ export default defineComponent({
                         pageVisibility={pageVisibility.value}
                         showModel={activeData.model}
                         isEmtry={isEmtry}
+                        onLoadedmetadata={(audioEle: any) => {
+                          console.log(audioEle, 'audioEle', m)
+                            m.audioEle = audioEle;
+                        }}
                         onEnded={() => {
                           const _index = popupData.activeIndex + 1;
                           if (_index < data.itemList.length) {
@@ -1178,6 +1261,9 @@ export default defineComponent({
                         activeModel={activeData.model}
                         data-vid={m.id}
                         music={m}
+                        onSetIframe={(el: any) => {
+                          m.iframeRef = el;
+                        }}
                       />
                     )}
 
@@ -1208,6 +1294,9 @@ export default defineComponent({
                         dataJson={m.dataJson}
                         show={popupData.activeIndex === mIndex}
                         pageVisibility={pageVisibility.value}
+                        onSetIframe={(el: any) => {
+                          m.iframeRef = el;
+                        }}
                       />
                       // <TempoPractice
                       //   key={mIndex}
@@ -1225,6 +1314,7 @@ export default defineComponent({
                           type={'wiki'}
                           id={m.bizId}
                           show={popupData.activeIndex === mIndex}
+                          ref={(el) => m.domEle = el}
                         />
                       )}
                       {m.type === 'INSTRUMENT' && (
@@ -1232,6 +1322,7 @@ export default defineComponent({
                           type={'instrument'}
                           id={m.bizId}
                           show={popupData.activeIndex === mIndex}
+                          ref={(el) => m.domEle = el}
                         />
                       )}
                       {m.type === 'MUSICIAN' && (
@@ -1239,6 +1330,7 @@ export default defineComponent({
                           type={'musician'}
                           id={m.bizId}
                           show={popupData.activeIndex === mIndex}
+                          ref={(el) => m.domEle = el}
                         />
                       )}
                       {m.type === 'LISTEN' && (
@@ -1248,6 +1340,9 @@ export default defineComponent({
                           activeModel={activeData.model}
                           data-vid={m.id}
                           item={m}
+                          onSetIframe={(el: any) => {
+                            m.iframeRef = el;
+                          }}
                         />
                       )}
                     </>