feat hls错误自动恢复
This commit is contained in:
@@ -5,6 +5,10 @@
|
|||||||
"ComputedRef": true,
|
"ComputedRef": true,
|
||||||
"DirectiveBinding": true,
|
"DirectiveBinding": true,
|
||||||
"EffectScope": true,
|
"EffectScope": true,
|
||||||
|
"ElLoading": true,
|
||||||
|
"ElMessage": true,
|
||||||
|
"ElMessageBox": true,
|
||||||
|
"ElNotification": true,
|
||||||
"ExtractDefaultPropTypes": true,
|
"ExtractDefaultPropTypes": true,
|
||||||
"ExtractPropTypes": true,
|
"ExtractPropTypes": true,
|
||||||
"ExtractPublicPropTypes": true,
|
"ExtractPublicPropTypes": true,
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ import { log } from 'node:console';
|
|||||||
let hlsInstance: Hls | null = null;
|
let hlsInstance: Hls | null = null;
|
||||||
// let hlsRetryCount = 0;
|
// let hlsRetryCount = 0;
|
||||||
|
|
||||||
export const initHls = (monitorVideoUrl, monitorVideoRef) => {
|
export const initHls = (monitorVideoUrl, monitorVideoRef, isDialogVisible?: () => boolean) => {
|
||||||
|
console.log('isDialogVisible', isDialogVisible);
|
||||||
const url = monitorVideoUrl.value;
|
const url = monitorVideoUrl.value;
|
||||||
const video = monitorVideoRef.value;
|
const video = monitorVideoRef.value;
|
||||||
if (!url || !video) return;
|
if (!url || !video) return;
|
||||||
@@ -39,6 +40,26 @@ export const initHls = (monitorVideoUrl, monitorVideoRef) => {
|
|||||||
// 加载成功,重置重试计数
|
// 加载成功,重置重试计数
|
||||||
// hlsRetryCount = 0;
|
// hlsRetryCount = 0;
|
||||||
});
|
});
|
||||||
|
// ★ 错误自动恢复:hls.js 拿到空 m3u8 或 ts 加载失败时自动重试
|
||||||
|
hls.on(Hls.Events.ERROR, (event, data) => {
|
||||||
|
if (data.fatal && (!isDialogVisible || isDialogVisible())) {
|
||||||
|
switch (data.type) {
|
||||||
|
case Hls.ErrorTypes.NETWORK_ERROR:
|
||||||
|
hls.startLoad();
|
||||||
|
ElMessage.error('网络错误, 请检查网络或重试');
|
||||||
|
break;
|
||||||
|
case Hls.ErrorTypes.MEDIA_ERROR:
|
||||||
|
// 媒体解码错误 → 尝试恢复
|
||||||
|
hls.recoverMediaError();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// 其他致命错误 → 销毁,让下一次 initHls 重建
|
||||||
|
hls.destroy();
|
||||||
|
hlsInstance = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
hlsInstance = hls;
|
hlsInstance = hls;
|
||||||
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
// Safari/原生支持 HLS
|
// Safari/原生支持 HLS
|
||||||
|
|||||||
@@ -255,7 +255,6 @@
|
|||||||
import { addEquipment, getDevicetList, getDeviceInfo, delDevice, actDevice, updateDeviceInfo, drawInfo } from '@/api/equipmentList/index';
|
import { addEquipment, getDevicetList, getDeviceInfo, delDevice, actDevice, updateDeviceInfo, drawInfo } from '@/api/equipmentList/index';
|
||||||
import { EquipmentList, DeviceInfoForm, AlarmAreaData } from '@/api/equipmentList/types';
|
import { EquipmentList, DeviceInfoForm, AlarmAreaData } from '@/api/equipmentList/types';
|
||||||
import { DemoVO, DemoQuery, DemoForm } from '@/api/demo/demo/types';
|
import { DemoVO, DemoQuery, DemoForm } from '@/api/demo/demo/types';
|
||||||
import { log } from 'node:console';
|
|
||||||
import { initHls, destroyHls } from '@/utils/video';
|
import { initHls, destroyHls } from '@/utils/video';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
import { useVideosStore } from '@/store/modules/video';
|
import { useVideosStore } from '@/store/modules/video';
|
||||||
@@ -472,7 +471,7 @@ const handleSee = async (row?: any) => {
|
|||||||
|
|
||||||
// 等待 DOM 更新后初始化 Hls
|
// 等待 DOM 更新后初始化 Hls
|
||||||
await nextTick();
|
await nextTick();
|
||||||
initHls(monitorVideoUrl, monitorVideoRef);
|
initHls(monitorVideoUrl, monitorVideoRef, () => dialog1.visible);
|
||||||
// 等待视频加载完成后初始化 ResizeObserver,以便能正确获取视频尺寸
|
// 等待视频加载完成后初始化 ResizeObserver,以便能正确获取视频尺寸
|
||||||
initVideoResizeObserver();
|
initVideoResizeObserver();
|
||||||
|
|
||||||
@@ -757,7 +756,7 @@ const saveImage = async () => {
|
|||||||
|
|
||||||
const handleMonitorDialogOpen = () => {
|
const handleMonitorDialogOpen = () => {
|
||||||
// 初始化 Hls 与 video
|
// 初始化 Hls 与 video
|
||||||
initHls(monitorVideoUrl, monitorVideoRef);
|
initHls(monitorVideoUrl, monitorVideoRef, () => dialog1.visible);
|
||||||
initVideoResizeObserver();
|
initVideoResizeObserver();
|
||||||
monitorDrawCollecting.value = false;
|
monitorDrawCollecting.value = false;
|
||||||
monitorDrawPoints.value = [];
|
monitorDrawPoints.value = [];
|
||||||
@@ -804,7 +803,7 @@ const handleRefresh = async () => {
|
|||||||
monitorVideoUrl.value = videosStore.hisUrl || '';
|
monitorVideoUrl.value = videosStore.hisUrl || '';
|
||||||
if (monitorVideoUrl.value) {
|
if (monitorVideoUrl.value) {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
initHls(monitorVideoUrl, monitorVideoRef);
|
initHls(monitorVideoUrl, monitorVideoRef, () => dialog1.visible);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user