63
src/utils/video.ts
Normal file
63
src/utils/video.ts
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
import Hls from 'hls.js';
|
||||||
|
let hlsInstance: Hls | null = null;
|
||||||
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||||
|
|
||||||
|
export const initHls = (monitorVideoUrl, monitorVideoRef) => {
|
||||||
|
const url = monitorVideoUrl.value;
|
||||||
|
const video = monitorVideoRef.value;
|
||||||
|
if (!url || !video) return;
|
||||||
|
|
||||||
|
// 销毁已有实例
|
||||||
|
if (hlsInstance) {
|
||||||
|
try {
|
||||||
|
hlsInstance.destroy();
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
hlsInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Hls.isSupported()) {
|
||||||
|
const hls = new Hls();
|
||||||
|
hls.loadSource(url);
|
||||||
|
hls.attachMedia(video);
|
||||||
|
hls.on(Hls.Events.MANIFEST_PARSED, () => {
|
||||||
|
// 自动播放(若浏览器允许)
|
||||||
|
try {
|
||||||
|
video.play().catch(() => {});
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
hlsInstance = hls;
|
||||||
|
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
|
// Safari/原生支持 HLS
|
||||||
|
video.src = url;
|
||||||
|
video.addEventListener('loadedmetadata', () => {
|
||||||
|
try {
|
||||||
|
video.play().catch(() => {});
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
proxy?.$modal.msgWarning('当前浏览器不支持 HLS 播放');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const destroyHls = (monitorVideoRef) => {
|
||||||
|
try {
|
||||||
|
if (hlsInstance) {
|
||||||
|
hlsInstance.destroy();
|
||||||
|
hlsInstance = null;
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
const video = monitorVideoRef.value;
|
||||||
|
if (video) {
|
||||||
|
// 清理原生 src,避免残留
|
||||||
|
try {
|
||||||
|
video.pause();
|
||||||
|
video.removeAttribute('src');
|
||||||
|
// 对某些浏览器,需要调用 load() 来重置 media element
|
||||||
|
if (typeof video.load === 'function') video.load();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default { initHls, destroyHls };
|
||||||
@@ -138,6 +138,7 @@ import { listDemo, getDemo, delDemo, addDemo, updateDemo } from '@/api/demo/demo
|
|||||||
import { DemoVO, DemoQuery, DemoForm } from '@/api/demo/demo/types';
|
import { DemoVO, DemoQuery, DemoForm } from '@/api/demo/demo/types';
|
||||||
import { log } from 'node:console';
|
import { log } from 'node:console';
|
||||||
import Hls from 'hls.js';
|
import Hls from 'hls.js';
|
||||||
|
import { nextTick } from 'vue';
|
||||||
import { useVideosStore } from '@/store/modules/video';
|
import { useVideosStore } from '@/store/modules/video';
|
||||||
|
|
||||||
const videosStore = useVideosStore();
|
const videosStore = useVideosStore();
|
||||||
@@ -167,6 +168,65 @@ const dialog1 = reactive<DialogOption>({
|
|||||||
|
|
||||||
const monitorVideoUrl = ref('');
|
const monitorVideoUrl = ref('');
|
||||||
const monitorVideoRef = ref<HTMLVideoElement>();
|
const monitorVideoRef = ref<HTMLVideoElement>();
|
||||||
|
let hlsInstance: Hls | null = null;
|
||||||
|
|
||||||
|
const initHls = () => {
|
||||||
|
const url = monitorVideoUrl.value;
|
||||||
|
const video = monitorVideoRef.value;
|
||||||
|
if (!url || !video) return;
|
||||||
|
|
||||||
|
// 销毁已有实例
|
||||||
|
if (hlsInstance) {
|
||||||
|
try {
|
||||||
|
hlsInstance.destroy();
|
||||||
|
} catch (e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
hlsInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Hls.isSupported()) {
|
||||||
|
const hls = new Hls();
|
||||||
|
hls.loadSource(url);
|
||||||
|
hls.attachMedia(video);
|
||||||
|
hls.on(Hls.Events.MANIFEST_PARSED, () => {
|
||||||
|
// 自动播放(若浏览器允许)
|
||||||
|
try {
|
||||||
|
video.play().catch(() => {});
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
hlsInstance = hls;
|
||||||
|
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
|
||||||
|
// Safari/原生支持 HLS
|
||||||
|
video.src = url;
|
||||||
|
video.addEventListener('loadedmetadata', () => {
|
||||||
|
try {
|
||||||
|
video.play().catch(() => {});
|
||||||
|
} catch (e) {}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
proxy?.$modal.msgWarning('当前浏览器不支持 HLS 播放');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const destroyHls = () => {
|
||||||
|
try {
|
||||||
|
if (hlsInstance) {
|
||||||
|
hlsInstance.destroy();
|
||||||
|
hlsInstance = null;
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
const video = monitorVideoRef.value;
|
||||||
|
if (video) {
|
||||||
|
// 清理原生 src,避免残留
|
||||||
|
try {
|
||||||
|
video.pause();
|
||||||
|
video.removeAttribute('src');
|
||||||
|
// 对某些浏览器,需要调用 load() 来重置 media element
|
||||||
|
if (typeof video.load === 'function') video.load();
|
||||||
|
} catch (e) {}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
type MonitorPoint = { x: number; y: number };
|
type MonitorPoint = { x: number; y: number };
|
||||||
const monitorDrawCollecting = ref(false);
|
const monitorDrawCollecting = ref(false);
|
||||||
@@ -329,14 +389,16 @@ const handleSee = async (row?: any) => {
|
|||||||
Object.assign(form.value, res.data);
|
Object.assign(form.value, res.data);
|
||||||
dialog1.visible = true;
|
dialog1.visible = true;
|
||||||
dialog1.title = '修改设备';
|
dialog1.title = '修改设备';
|
||||||
videosStore.getVideos(row.id);
|
await videosStore.getVideos(row.id);
|
||||||
console.log('222222222222:', videosStore.hisUrl);
|
|
||||||
monitorVideoUrl.value = videosStore.hisUrl;
|
monitorVideoUrl.value = videosStore.hisUrl;
|
||||||
|
// 等待 DOM 更新后初始化 Hls
|
||||||
|
await nextTick();
|
||||||
|
initHls();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMonitorDialogClose = (done: () => void) => {
|
const handleMonitorDialogClose = (done: () => void) => {
|
||||||
monitorVideoRef.value?.pause();
|
// 卸载 Hls 与清理 video
|
||||||
monitorVideoRef.value && (monitorVideoRef.value.currentTime = 0);
|
destroyHls();
|
||||||
resetMonitorDraw();
|
resetMonitorDraw();
|
||||||
done();
|
done();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user