| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- <template>
- <div ref="videoEl" class="live-player-wrapper" style="width: 100%; height: 100%">
- <live-player ref="player" :video-url="src" live stretch autoplay muted controls style="width: 100%; height: 100%" @error="handleError" />
- </div>
- </template>
- <script setup lang="ts">
- import LivePlayer from '@liveqing/liveplayer-v3';
- import { useDrag } from '/@/hooks/event/useDrag';
- import { onBeforeUnmount, onMounted, onUnmounted, ref } from 'vue';
- // 注册组件
- defineProps<{
- src: string;
- }>();
- const videoEl = ref<HTMLElement | null>(null);
- const player = ref<LivePlayer | null>(null);
- let retryCount = 0;
- const maxRetry = 30; // 最大重试次数
- const retryInterval = 3000; // 重试间隔(毫秒)
- let timer: NodeJS.Timeout | null = null;
- function handleError(err) {
- if (retryCount < maxRetry) {
- retryCount++;
- console.log(`第 ${retryCount} 次重试...`);
- timer = setTimeout(() => {
- if (player.value && player.value.play) player.value.play();
- }, retryInterval);
- } else {
- console.error('重试次数已达上限,停止重连');
- // 可在此处显示“连接失败,请刷新”提示
- showReconnectButton();
- }
- }
- function showReconnectButton() {
- if (player.value)
- player.value.innerHTML = `
- <div style="color: white; text-align: center; padding: 20px;">
- 视频连接失败<br>
- <button onclick="location.reload()" style="margin-top: 10px; padding: 8px 16px;">点击重试</button>
- </div>
- `;
- }
- onMounted(() => {
- if (videoEl.value) useDrag(videoEl.value);
- });
- onBeforeUnmount(() => {
- if (timer) clearTimeout(timer);
- if (player.value && player.value.destroy) player.value.destroy();
- if (player.value && player.value.remove) player.value.remove();
- });
- </script>
- <style scoped>
- /* 断流重连时避免 video.js 黑色 poster/modal 突然压暗画面 */
- .live-player-wrapper :deep(.vjs-modal-dialog),
- .live-player-wrapper :deep(.vjs-loading-spinner),
- .live-player-wrapper :deep(.vjs-big-play-button),
- .live-player-wrapper :deep(.vjs-poster) {
- display: none !important;
- opacity: 0 !important;
- visibility: hidden !important;
- pointer-events: none !important;
- }
- .live-player-wrapper :deep(video),
- .live-player-wrapper :deep(.video-js) {
- opacity: 1 !important;
- }
- </style>
|