|
@@ -1,6 +1,9 @@
|
|
|
<template>
|
|
<template>
|
|
|
<div class="video-content-wrapper">
|
|
<div class="video-content-wrapper">
|
|
|
- <div class="videoLoading" v-loading="true" element-loading-text="视频加载中..."></div>
|
|
|
|
|
|
|
+ <div class="videoLoading" v-loading="!isVideoLoadingFailed" :element-loading-text="loadingText">
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <div class="loadingError" v-if="isVideoLoadingFailed">视频加载失败</div>
|
|
|
|
|
|
|
|
<video v-loading="true" id="video" autoplay muted loop class="video-js video-content">
|
|
<video v-loading="true" id="video" autoplay muted loop class="video-js video-content">
|
|
|
<source :src="props.url" />
|
|
<source :src="props.url" />
|
|
@@ -9,15 +12,25 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
- import { onMounted, onBeforeUnmount, watch } from 'vue';
|
|
|
|
|
|
|
+ import { onMounted, onBeforeUnmount, watch, ref, computed } from 'vue';
|
|
|
import mpegts from 'mpegts.js';
|
|
import mpegts from 'mpegts.js';
|
|
|
|
|
|
|
|
|
|
+ const restartNum = ref(0);
|
|
|
|
|
+
|
|
|
|
|
+ const MAX_RESTART_NUM = 20;
|
|
|
|
|
+ let isVideoLoadingFailed = ref(false);
|
|
|
|
|
+
|
|
|
const props = defineProps<{
|
|
const props = defineProps<{
|
|
|
url: string;
|
|
url: string;
|
|
|
}>();
|
|
}>();
|
|
|
|
|
|
|
|
let player: mpegts.Player | null;
|
|
let player: mpegts.Player | null;
|
|
|
|
|
|
|
|
|
|
+ const loadingText = computed(() => {
|
|
|
|
|
+ if (restartNum.value === 0) return '视频加载中...';
|
|
|
|
|
+ return `正在尝试第${restartNum.value}次重连...`;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
const initPlay = () => {
|
|
const initPlay = () => {
|
|
|
const videoElement = document.getElementById('video') as HTMLMediaElement;
|
|
const videoElement = document.getElementById('video') as HTMLMediaElement;
|
|
|
player = mpegts.createPlayer(
|
|
player = mpegts.createPlayer(
|
|
@@ -36,6 +49,23 @@
|
|
|
player.on(mpegts.Events.MEDIA_INFO, () => {
|
|
player.on(mpegts.Events.MEDIA_INFO, () => {
|
|
|
// testStore.setVideoReady(true);
|
|
// testStore.setVideoReady(true);
|
|
|
});
|
|
});
|
|
|
|
|
+ player.on(mpegts.Events.ERROR, (e) => {
|
|
|
|
|
+ // testStore.setVideoReady(true);
|
|
|
|
|
+ console.log('video error', e);
|
|
|
|
|
+ if (restartNum.value >= MAX_RESTART_NUM) {
|
|
|
|
|
+ isVideoLoadingFailed.value = true;
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (player) {
|
|
|
|
|
+ player.pause();
|
|
|
|
|
+ player.unload();
|
|
|
|
|
+ player.detachMediaElement();
|
|
|
|
|
+ player.destroy();
|
|
|
|
|
+ player = null;
|
|
|
|
|
+ restartNum.value += 1;
|
|
|
|
|
+ initPlay();
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
// player.play();
|
|
// player.play();
|
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
|
player?.play();
|
|
player?.play();
|
|
@@ -95,4 +125,10 @@
|
|
|
width: 100%;
|
|
width: 100%;
|
|
|
height: 100%;
|
|
height: 100%;
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ .loadingError {
|
|
|
|
|
+ font-size: 20px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ margin-top: 200px;
|
|
|
|
|
+ }
|
|
|
</style>
|
|
</style>
|