diff --git a/src/components/call/CallWindow.vue b/src/components/call/CallWindow.vue index d42ea8a..2eb8991 100644 --- a/src/components/call/CallWindow.vue +++ b/src/components/call/CallWindow.vue @@ -388,33 +388,12 @@ watchEffect(() => { // 监听小程序流,初始化 FLV 播放器 let flvPlayer: flvjs.Player | null = null +let currentFlvUrl: string | null = null // 跟踪当前播放的 FLV URL -watch( - () => [props.call.miniprogramStreams, props.call.status, flvVideoRef.value], - () => { - // 当有小程序流且通话已连接时,初始化 FLV 播放器 - if ( - props.call.status === 'connected' && - props.call.miniprogramStreams && - props.call.miniprogramStreams.length > 0 && - flvVideoRef.value && - props.initFlvPlayer - ) { - // 避免重复初始化 - if (!flvPlayer) { - console.log('[CallWindow] 初始化 FLV 播放器') - flvPlayer = props.initFlvPlayer(flvVideoRef.value, 0) - } - } - }, - { immediate: true } -) - -// 组件卸载时清理 FLV 播放器 -onUnmounted(() => { +// 清理 FLV 播放器的辅助函数 +function cleanupFlvPlayer() { if (flvPlayer) { try { - // 检查播放器状态,避免空指针错误 // @ts-ignore - flv.js Player 内部属性 if (flvPlayer._mediaElement) { flvPlayer.pause() @@ -425,10 +404,57 @@ onUnmounted(() => { } catch (e) { // 忽略已销毁的播放器错误 if (!(e instanceof TypeError && (e as Error).message?.includes("Cannot read properties of null"))) { - console.error('[CallWindow] 销毁 FLV 播放器失败:', e) + console.warn('[CallWindow] 销毁 FLV 播放器时出错:', e) } } flvPlayer = null + currentFlvUrl = null } +} + +watch( + () => [props.call.miniprogramStreams, props.call.status, flvVideoRef.value], + () => { + const streams = props.call.miniprogramStreams + const newFlvUrl = streams && streams.length > 0 ? streams[0].flvUrl : null + + // 当通话结束或没有流时,清理播放器 + if (props.call.status !== 'connected' || !newFlvUrl) { + if (flvPlayer) { + console.log('[CallWindow] 通话状态变化或无流,清理 FLV 播放器') + cleanupFlvPlayer() + } + return + } + + // 当有小程序流且通话已连接时,初始化 FLV 播放器 + if ( + props.call.status === 'connected' && + newFlvUrl && + flvVideoRef.value && + props.initFlvPlayer + ) { + // 避免重复初始化相同的流(URL 未变化) + if (flvPlayer && currentFlvUrl === newFlvUrl) { + return + } + + // URL 变化时,先清理旧播放器 + if (flvPlayer && currentFlvUrl !== newFlvUrl) { + console.log('[CallWindow] FLV URL 变化,重新初始化播放器') + cleanupFlvPlayer() + } + + console.log('[CallWindow] 初始化 FLV 播放器:', newFlvUrl) + flvPlayer = props.initFlvPlayer(flvVideoRef.value, 0) + currentFlvUrl = newFlvUrl + } + }, + { immediate: true } +) + +// 组件卸载时清理 FLV 播放器 +onUnmounted(() => { + cleanupFlvPlayer() }) diff --git a/src/composables/useWebRTC.ts b/src/composables/useWebRTC.ts index 8027a91..2f8d5af 100644 --- a/src/composables/useWebRTC.ts +++ b/src/composables/useWebRTC.ts @@ -1011,10 +1011,18 @@ export function useWebRTC( return null } - // 如果已有播放器,先销毁 + // 如果已有播放器,先完整销毁(必须按顺序调用 pause, unload, detachMediaElement, destroy) if (stream.player) { console.log('[WebRTC] 🔄 销毁已有的 FLV 播放器') - stream.player.destroy() + try { + stream.player.pause() + stream.player.unload() + stream.player.detachMediaElement() + stream.player.destroy() + } catch (e) { + console.warn('[WebRTC] 销毁 FLV 播放器时出错:', e) + } + stream.player = undefined } console.log('[WebRTC] 🎬 创建 FLV 播放器:', stream.flvUrl)