修复web和微信小程序的通话
This commit is contained in:
@@ -389,9 +389,16 @@ watchEffect(() => {
|
||||
// 监听小程序流,初始化 FLV 播放器
|
||||
let flvPlayer: flvjs.Player | null = null
|
||||
let currentFlvUrl: string | null = null // 跟踪当前播放的 FLV URL
|
||||
let chaseFrameTimer: number | null = null // 追帧定时器(解决累积延迟问题)
|
||||
|
||||
// 清理 FLV 播放器的辅助函数
|
||||
function cleanupFlvPlayer() {
|
||||
// 清理追帧定时器
|
||||
if (chaseFrameTimer) {
|
||||
clearInterval(chaseFrameTimer)
|
||||
chaseFrameTimer = null
|
||||
}
|
||||
|
||||
if (flvPlayer) {
|
||||
try {
|
||||
// @ts-ignore - flv.js Player 内部属性
|
||||
@@ -448,6 +455,31 @@ watch(
|
||||
console.log('[CallWindow] 初始化 FLV 播放器:', newFlvUrl)
|
||||
flvPlayer = props.initFlvPlayer(flvVideoRef.value, 0)
|
||||
currentFlvUrl = newFlvUrl
|
||||
|
||||
// 启动追帧定时器(解决累积延迟问题)
|
||||
if (flvVideoRef.value) {
|
||||
// 先清理可能存在的旧定时器
|
||||
if (chaseFrameTimer) {
|
||||
clearInterval(chaseFrameTimer)
|
||||
}
|
||||
chaseFrameTimer = window.setInterval(() => {
|
||||
if (!flvPlayer || !flvVideoRef.value) return
|
||||
|
||||
const video = flvVideoRef.value
|
||||
// 检查缓冲区是否有数据
|
||||
if (video.buffered.length > 0) {
|
||||
const end = video.buffered.end(0) // 缓冲区末尾时间
|
||||
const current = video.currentTime // 当前播放时间
|
||||
const diff = end - current // 延迟时长
|
||||
|
||||
// 如果延迟超过 1.5 秒,执行追帧
|
||||
if (diff > 1.5) {
|
||||
console.log(`[CallWindow] 检测到延迟 ${diff.toFixed(2)}s,执行追帧...`)
|
||||
video.currentTime = end - 0.1 // 跳到缓冲区末尾附近
|
||||
}
|
||||
}
|
||||
}, 1500) // 每 1.5 秒检查一次
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: true, deep: true }
|
||||
|
||||
@@ -209,6 +209,15 @@ export function useWebRTC(
|
||||
} else {
|
||||
console.log('[WebRTC] RTMP 模式:等待 FLV 流')
|
||||
}
|
||||
|
||||
// 延迟刷新房间流信息,确保小程序推流成功后能获取到 FLV 地址
|
||||
// 小程序推流成功需要时间(通常 2-3 秒),所以延迟刷新
|
||||
setTimeout(() => {
|
||||
if (call.active && call.miniprogramStreams.length === 0 && currentRoomId) {
|
||||
console.log('[WebRTC] 📡 通话建立后延迟刷新房间信息...')
|
||||
refreshRoomStreams()
|
||||
}
|
||||
}, 2000)
|
||||
|
||||
} else if (signal === 'offer') {
|
||||
// WebRTC 模式才处理 offer(RTMP 模式不使用 WebRTC 信令)
|
||||
@@ -251,27 +260,37 @@ export function useWebRTC(
|
||||
pull_url: content.pull_url
|
||||
})
|
||||
|
||||
// 如果有 FLV 地址,添加或更新小程序流列表
|
||||
if (content.flv_url && content.user_id) {
|
||||
// 获取 FLV 地址(优先使用 flv_url,兼容 pull_url 转换)
|
||||
let flvUrl = content.flv_url || ''
|
||||
|
||||
// 如果有 FLV 地址或用户 ID,添加或更新小程序流列表
|
||||
if (flvUrl && content.user_id) {
|
||||
const existingIndex = call.miniprogramStreams.findIndex(s => s.userId === content.user_id)
|
||||
if (existingIndex >= 0) {
|
||||
// 更新现有流的地址(重要:当用户重新加入时使用新的流地址)
|
||||
const oldFlvUrl = call.miniprogramStreams[existingIndex].flvUrl
|
||||
call.miniprogramStreams[existingIndex].flvUrl = content.flv_url
|
||||
call.miniprogramStreams[existingIndex].flvUrl = flvUrl
|
||||
console.log('[WebRTC] 🔄 更新小程序流地址:', content.user_id)
|
||||
console.log('[WebRTC] 旧地址:', oldFlvUrl)
|
||||
console.log('[WebRTC] 新地址:', content.flv_url)
|
||||
console.log('[WebRTC] 新地址:', flvUrl)
|
||||
} else {
|
||||
// 添加新的小程序流
|
||||
call.miniprogramStreams.push({
|
||||
userId: content.user_id,
|
||||
flvUrl: content.flv_url
|
||||
flvUrl: flvUrl
|
||||
})
|
||||
console.log('[WebRTC] ✅ 添加小程序流:', content.user_id, content.flv_url)
|
||||
console.log('[WebRTC] ✅ 添加小程序流:', content.user_id, flvUrl)
|
||||
}
|
||||
console.log('[WebRTC] 📺 当前小程序流列表:', call.miniprogramStreams)
|
||||
} else {
|
||||
console.log('[WebRTC] ⚠️ participant_joined 没有 FLV 地址')
|
||||
} else if (content.user_id && !flvUrl) {
|
||||
// 兼容性处理:如果没有 FLV 地址,尝试延迟获取
|
||||
console.log('[WebRTC] ⚠️ participant_joined 没有 FLV 地址,1秒后尝试刷新房间信息')
|
||||
setTimeout(() => {
|
||||
if (call.active && currentRoomId && call.miniprogramStreams.length === 0) {
|
||||
console.log('[WebRTC] 📡 延迟刷新房间信息...')
|
||||
refreshRoomStreams()
|
||||
}
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
// 如果当前没有小程序流,尝试重新获取房间信息
|
||||
@@ -615,6 +634,14 @@ export function useWebRTC(
|
||||
|
||||
console.log('[WebRTC] 📤 发送 accepted 信令给:', currentReceiverUserId)
|
||||
sendSignal('accepted', undefined, currentReceiverUserId)
|
||||
|
||||
// 延迟刷新房间流信息,确保小程序推流成功后能获取到 FLV 地址
|
||||
setTimeout(() => {
|
||||
if (call.active && call.miniprogramStreams.length === 0 && currentRoomId) {
|
||||
console.log('[WebRTC] 📡 接听后延迟刷新房间信息...')
|
||||
refreshRoomStreams()
|
||||
}
|
||||
}, 2000)
|
||||
} catch (error) {
|
||||
console.error('[WebRTC] ❌ 接听失败:', error)
|
||||
endCall()
|
||||
@@ -1033,16 +1060,30 @@ export function useWebRTC(
|
||||
isLive: true,
|
||||
hasAudio: true,
|
||||
hasVideo: true,
|
||||
cors: true, // 允许跨域
|
||||
}, {
|
||||
enableWorker: false,
|
||||
enableStashBuffer: false,
|
||||
enableStashBuffer: false, // 关闭堆积缓存,减少延迟
|
||||
stashInitialSize: 128,
|
||||
lazyLoad: false,
|
||||
lazyLoadMaxDuration: 0.2, // 极短的懒加载时间
|
||||
autoCleanupSourceBuffer: true, // 自动清理缓存防止内存泄漏
|
||||
})
|
||||
|
||||
player.attachMediaElement(videoElement)
|
||||
player.load()
|
||||
player.play()
|
||||
|
||||
// 自动播放失败时静音重试(兼容浏览器自动播放策略)
|
||||
player.play().catch(async (e) => {
|
||||
console.warn('[WebRTC] 自动播放失败,尝试静音播放:', e)
|
||||
videoElement.muted = true
|
||||
try {
|
||||
await player.play()
|
||||
console.log('[WebRTC] 静音播放成功')
|
||||
} catch (e2) {
|
||||
console.error('[WebRTC] 静音播放也失败:', e2)
|
||||
}
|
||||
})
|
||||
|
||||
// 监听错误
|
||||
player.on(flvjs.Events.ERROR, (errorType, errorDetail, errorInfo) => {
|
||||
|
||||
Reference in New Issue
Block a user