feat 抽取hls video工具

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Ironsp
2026-05-25 17:53:26 +08:00
parent 3b001f79e0
commit 988cf99a03
2 changed files with 129 additions and 4 deletions

63
src/utils/video.ts Normal file
View 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 };

View File

@@ -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();
}; };