Pārlūkot izejas kodu

fix: 视频预览卡顿销毁问题

dx 3 mēneši atpakaļ
vecāks
revīzija
a3812db2ba

+ 73 - 71
src/components/XGVideoViewer/hooks/useInitPlayer.js

@@ -1,53 +1,53 @@
-import { ref, onMounted, watch } from 'vue'
-import { postMessage } from '../utils/iframePip.js'
-import Player, { Events } from 'xgplayer'
-import 'xgplayer/dist/index.min.css'
+import { ref, onMounted, watch } from "vue";
+import { postMessage } from "../utils/iframePip.js";
+import Player, { Events } from "xgplayer";
+import "xgplayer/dist/index.min.css";
 // xgplay相关的
 const useInitPlayer = (props, emits) => {
-  const xgplayer = ref(null)
+  const xgplayer = ref(null);
   // 是否全屏
-  const isCssFullScreenRef = ref(false)
+  const isCssFullScreenRef = ref(false);
   // 是否展示问题
-  const questionShowRef = ref(false)
+  const questionShowRef = ref(false);
   // 视频历史记录
-  const historyListRef = ref([])
+  const historyListRef = ref([]);
 
   // 是否是移动端设备
   const isMobileDevice = () => {
     return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
       navigator.userAgent
-    )
-  }
+    );
+  };
   // 是否是手机
-  const isMobile = isMobileDevice()
+  const isMobile = isMobileDevice();
   // 获取全屏设置
   const getFullscreen = () => {
     const defaultConfig = {
-      needBackIcon: true
-    }
+      needBackIcon: true,
+    };
     return isMobile
       ? {
           rotateFullscreen: true,
-          ...defaultConfig
+          ...defaultConfig,
         }
       : {
           useCssFullscreen: true,
-          ...defaultConfig
-        }
-  }
+          ...defaultConfig,
+        };
+  };
 
   // 播放器容器对外发送信息
   const viewerPostMessage = (data) => {
-    props.ifSendMsg && postMessage(data)
-  }
+    props.ifSendMsg && postMessage(data);
+  };
 
   // 初始化播放器
   const initPlay = () => {
-    historyListRef.value = []
+    historyListRef.value = [];
 
     return new Player({
-      id: 'mse',
-      lang: 'zh',
+      id: "mse",
+      lang: "zh",
       url: props.videoUrl,
       height: props.height,
       width: props.width,
@@ -60,102 +60,104 @@ const useInitPlayer = (props, emits) => {
       // 全屏插件配置
       fullscreen: getFullscreen(),
       // 需要忽略的插件
-      ignores: ['cssfullscreen']
-    })
-  }
+      ignores: ["cssfullscreen"],
+    });
+  };
   const playNext = (url, poster) => {
     // 关闭问题
-    questionShowRef.value = false
+    questionShowRef.value = false;
     // 播放下一个视频
     xgplayer.value.playNext({
-      url: url
-    })
+      url: url,
+    });
     // 设置封面,playNext里面设置有点问题,时常不生效
     xgplayer.value.setConfig({
-      poster: poster
-    })
-  }
+      poster: poster,
+    });
+  };
   // 初始化事件
   const initHandler = (xgplayer) => {
-    if (!xgplayer) return
+    if (!xgplayer) return;
     // 全屏变化
     xgplayer.on(Events.FULLSCREEN_CHANGE, (isFullScreen) => {
-      isCssFullScreenRef.value = isFullScreen
-      emits('onFullscreenChange', isFullScreen)
-    })
+      isCssFullScreenRef.value = isFullScreen;
+      emits("onFullscreenChange", isFullScreen);
+    });
     // 视频播放结束
     xgplayer.on(Events.ENDED, () => {
-      questionShowRef.value = true
-    })
+      questionShowRef.value = true;
+    });
     // 视频开始播放
     xgplayer.on(Events.PLAY, () => {
-      questionShowRef.value = false
-    })
+      questionShowRef.value = false;
+    });
     // 视频资源加载成功
     xgplayer.on(Events.LOADED_DATA, () => {
-      console.log('视频资源加载成功')
+      console.log("视频资源加载成功");
       // 表示视频切换后加载成功
       if (historyListRef.value.length > 0) {
-        xgplayer.currentTime = 0
+        xgplayer.currentTime = 0;
         setTimeout(() => {
           xgplayer
             .play()
             .then(() => {
               // 播放成功
-              console.log('播放成功')
+              console.log("播放成功");
             })
             .catch((err) => {
-              console.log('播放失败', err)
+              console.log("播放失败", err);
               // 播放失败,一般发生于未经用户交互时的自动播放
-            })
-        }, 50)
+            });
+        }, 50);
       }
-      historyListRef.value.push(props.videoUrl)
-    })
-  }
+      historyListRef.value.push(props.videoUrl);
+    });
+  };
   const init = () => {
-    if (!props.videoUrl) return
-    console.log('开始初始化视频播放器')
+    // 有视频源的时候才进行初始化
+    if (!props.videoUrl) return;
+    // console.log('开始初始化视频播放器')
     try {
-      xgplayer.value = initPlay()
-      initHandler(xgplayer.value)
+      xgplayer.value = initPlay();
+      initHandler(xgplayer.value);
       viewerPostMessage({
-        msgType: 'video_init',
-        content: '视频播放器初始化成功'
-      })
+        msgType: "video_init",
+        content: "视频播放器初始化成功",
+      });
     } catch (error) {
       viewerPostMessage({
-        msgType: 'video_init_fail',
-        content: '视频播放器初始失败'
-      })
+        msgType: "video_init_fail",
+        content: "视频播放器初始失败",
+      });
     }
-  }
+  };
 
   watch(
     () => props.videoUrl,
     (val, oldVal) => {
       // 首次加载视频进行初始化
-      if (val && !oldVal) init()
+      if (val && !oldVal) init();
     }
-  )
+  );
 
   onMounted(() => {
-    init()
+    init();
+    // 这里延迟一下在通知,不然父页面不一定能接收到
     setTimeout(() => {
       viewerPostMessage({
-        msgType: 'video_ready',
-        content: '视频容器准备就绪'
-      })
-    }, 250)
-  })
+        msgType: "video_ready",
+        content: "视频容器准备就绪",
+      });
+    }, 250);
+  });
 
   return {
     xgplayer,
     isMobile,
     isCssFullScreenRef,
     questionShowRef,
-    playNext
-  }
-}
+    playNext,
+  };
+};
 
-export default useInitPlayer
+export default useInitPlayer;

+ 6 - 1
src/views/interactVideo/sourceMaterialManage/index.vue

@@ -156,7 +156,12 @@
     </el-dialog>
 
     <!-- 视频预览 -->
-    <el-dialog title="视频预览" v-model="videoViewOpen" width="1200">
+    <el-dialog
+      title="视频预览"
+      v-model="videoViewOpen"
+      width="1200"
+      destroy-on-close
+    >
       <XGVideoViewer
         :videoUrl="videoUrl"
         :autoplay="true"