From d004722d894944f086d3343497f4d61fe7cd3252 Mon Sep 17 00:00:00 2001 From: shinya Date: Tue, 26 Aug 2025 02:29:46 +0800 Subject: [PATCH] feat: totally destory artplayer after leaving page --- src/app/api/proxy/m3u8/route.ts | 2 +- src/app/live/page.tsx | 44 +++++++++++++++++++++++++++++++-- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/app/api/proxy/m3u8/route.ts b/src/app/api/proxy/m3u8/route.ts index 0154fdb..93fff2b 100644 --- a/src/app/api/proxy/m3u8/route.ts +++ b/src/app/api/proxy/m3u8/route.ts @@ -41,7 +41,7 @@ export async function GET(request: Request) { const contentType = response.headers.get('Content-Type') || ''; // rewrite m3u8 - if (contentType.toLowerCase().includes('mpegurl')) { + if (contentType.toLowerCase().includes('mpegurl') || contentType.toLowerCase().includes('octet-stream')) { // 获取最终的响应URL(处理重定向后的URL) const finalUrl = response.url; const m3u8Content = await response.text(); diff --git a/src/app/live/page.tsx b/src/app/live/page.tsx index 3412a13..3b20dca 100644 --- a/src/app/live/page.tsx +++ b/src/app/live/page.tsx @@ -413,14 +413,33 @@ function LivePageClient() { const cleanupPlayer = () => { if (artPlayerRef.current) { try { + // 先暂停播放 + if (artPlayerRef.current.video) { + artPlayerRef.current.video.pause(); + artPlayerRef.current.video.src = ''; + artPlayerRef.current.video.load(); + } + // 销毁 HLS 实例 if (artPlayerRef.current.video && artPlayerRef.current.video.hls) { artPlayerRef.current.video.hls.destroy(); + artPlayerRef.current.video.hls = null; } + + // 销毁 FLV 实例 if (artPlayerRef.current.video && artPlayerRef.current.video.flv) { artPlayerRef.current.video.flv.destroy(); + artPlayerRef.current.video.flv = null; } + // 移除所有事件监听器 + artPlayerRef.current.off('ready'); + artPlayerRef.current.off('loadstart'); + artPlayerRef.current.off('loadeddata'); + artPlayerRef.current.off('canplay'); + artPlayerRef.current.off('waiting'); + artPlayerRef.current.off('error'); + // 销毁 ArtPlayer 实例 artPlayerRef.current.destroy(); artPlayerRef.current = null; @@ -552,9 +571,16 @@ function LivePageClient() { return; } + // 清理之前的 HLS 实例 if (video.hls) { - video.hls.destroy(); + try { + video.hls.destroy(); + video.hls = null; + } catch (err) { + console.warn('清理 HLS 实例时出错:', err); + } } + const hls = new Hls({ debug: false, enableWorker: true, @@ -669,7 +695,7 @@ function LivePageClient() { autoMini: false, screenshot: false, setting: false, - loop: true, + loop: false, flip: false, playbackRate: false, aspectRatio: false, @@ -749,6 +775,20 @@ function LivePageClient() { }; }, []); + // 页面卸载时的额外清理 + useEffect(() => { + const handleBeforeUnload = () => { + cleanupPlayer(); + }; + + window.addEventListener('beforeunload', handleBeforeUnload); + + return () => { + window.removeEventListener('beforeunload', handleBeforeUnload); + cleanupPlayer(); + }; + }, []); + // 全局快捷键处理 useEffect(() => { const handleKeyboardShortcuts = (e: KeyboardEvent) => {