修复web和微信小程序的通话

This commit is contained in:
2025-12-16 14:10:07 +08:00
parent 5a977f1b7c
commit ad73df1498
3 changed files with 67 additions and 8 deletions

View File

@@ -41,8 +41,8 @@
>
<div class="relative" :class="call.minimized ? 'scale-50' : ''">
<Avatar
:name="target?.remark_name || target?.user?.name"
:avatar="target?.user?.avatar"
:name="displayName"
:avatar="displayAvatar"
size="2xl"
class="w-32 h-32 text-5xl border-4 border-gray-800 shadow-2xl relative z-20"
/>
@@ -52,7 +52,7 @@
</div>
<div v-if="!call.minimized" class="text-2xl font-bold text-gray-100 tracking-wide mt-6">
{{ target?.remark_name || target?.user?.name || '未知用户' }}
{{ displayName }}
</div>
<div class="text-gray-400 mt-2 font-mono flex items-center gap-2 text-sm" :class="{'scale-75': call.minimized}">
@@ -189,6 +189,10 @@ interface Props {
remoteCamOff: boolean
duration: number
miniprogramStreams?: FlvStreamInfo[]
// 来电者信息(用于来电显示,当 target 为 null 时使用)
callerName?: string
callerAvatar?: string
callerId?: string
}
target: Contact | null
isMobile: boolean
@@ -220,6 +224,16 @@ const hasFlvStream = computed(() => {
(props.call.miniprogramStreams && props.call.miniprogramStreams.length > 0)
})
// 计算显示的用户名(优先使用 targetfallback 到 call.callerName
const displayName = computed(() => {
return props.target?.remark_name || props.target?.user?.name || props.call.callerName || '未知用户'
})
// 计算显示的头像(优先使用 targetfallback 到 call.callerAvatar
const displayAvatar = computed(() => {
return props.target?.user?.avatar || props.call.callerAvatar
})
const shouldShowLocalVideo = computed(() => {
return props.call.type === 'video' &&
!props.call.minimized &&

View File

@@ -6,6 +6,7 @@ import * as callApi from '@/api/modules/call'
import { wsManager } from '@/api/websocket'
import { useToastStore } from '@/stores/toast'
import { useChatStore } from '@/stores/chat'
import { useAuthStore } from '@/stores/auth'
import { isRTMPMode, isAutoMode, shouldUseRTMP, parsePlatform, type Platform } from '@/config/call'
import type { ChatMessage, Contact, ICEServerConfig } from '@/types/api'
import type { CallStatus } from '@/types/message'
@@ -25,6 +26,10 @@ export interface CallState {
startTime: number | null
// 小程序流信息
miniprogramStreams: FlvStreamInfo[]
// 来电者信息(用于来电显示)
callerName?: string
callerAvatar?: string
callerId?: string
}
// FLV 流信息(来自小程序端)
@@ -43,6 +48,7 @@ export function useWebRTC(
) {
const toastStore = useToastStore()
const chatStore = useChatStore()
const authStore = useAuthStore()
const call = reactive<CallState>({
active: false,
@@ -58,6 +64,10 @@ export function useWebRTC(
duration: 0,
startTime: null,
miniprogramStreams: [],
// 来电者信息
callerName: undefined,
callerAvatar: undefined,
callerId: undefined,
})
const isCaller = ref(false)
@@ -124,7 +134,9 @@ export function useWebRTC(
type: extra.type,
platform: extra.platform,
remotePlatform,
useRTMP: useRTMP.value
useRTMP: useRTMP.value,
senderName: extra.senderName,
senderAvatar: extra.senderAvatar
})
if (call.active) {
console.log('[WebRTC] ⚠️ 当前有通话,忽略新来电')
@@ -138,6 +150,26 @@ export function useWebRTC(
call.minimized = false
call.status = 'incoming'
call.statusText = `邀请你通话`
// 设置来电者信息
call.callerId = message.sender_user_id
// 优先从信令 extra 获取来电者信息(小程序端会发送)
if (extra.senderName) {
call.callerName = extra.senderName
call.callerAvatar = extra.senderAvatar
} else {
// 否则从本地联系人列表查找
const contact = chatStore.contacts.find(c =>
c.contact_user_id === message.sender_user_id ||
c.user_id === message.sender_user_id
)
if (contact?.user) {
call.callerName = contact.remark_name || contact.user.name
call.callerAvatar = contact.user.avatar
}
}
console.log('[WebRTC] 👤 来电者信息:', { name: call.callerName, avatar: call.callerAvatar })
console.log('[WebRTC] ✅ 设置来电状态, roomId:', currentRoomId, 'mode:', useRTMP.value ? 'RTMP' : 'WebRTC')
playRingtone('incoming')
if (onIncomingCall) onIncomingCall(message.sender_user_id)
@@ -443,6 +475,9 @@ export function useWebRTC(
console.log('[WebRTC] 📤 发送信令:', status, { to: targetUserId, roomId, callId: call.id })
// 获取当前用户信息,发送给对方(让对方显示来电者信息)
const currentUser = authStore.user
const payload = {
sender_client_id: wsManager.getClientId() || '',
receiver_user_id: targetUserId,
@@ -451,8 +486,13 @@ export function useWebRTC(
content: JSON.stringify(data || {}),
call_id: call.id,
call_status: status,
// 包含平台信息,让对方知道我们是 web 端
extra: JSON.stringify({ type: call.type, platform: 'web' }),
// 包含平台信息和发送者信息,让对方显示来电者昵称和头像
extra: JSON.stringify({
type: call.type,
platform: 'web',
senderName: currentUser?.name,
senderAvatar: currentUser?.avatar
}),
}
messageApi.sendMessage(payload).catch(err => {
console.error('[WebRTC] ❌ 发送信令失败:', err)
@@ -605,6 +645,10 @@ export function useWebRTC(
call.status = 'idle'
call.statusText = ''
call.id = null
// 清除来电者信息
call.callerName = undefined
call.callerAvatar = undefined
call.callerId = undefined
stopCallTimer()
// 停止 WebSocket 推流 (RTMP 模式)

View File

@@ -14,10 +14,11 @@ export type Platform = 'h5' | 'app' | 'miniprogram' | 'unknown'
/**
* 获取当前通话模式
* 从 window.__CALL_MODE__ 读取,默认为 'webrtc'
* 从 window.__CALL_MODE__ 读取,默认为 'auto'
* auto 模式会根据对方平台自动选择Web-Web 用 WebRTCWeb-小程序 用 RTMP
*/
export function getCallMode(): CallMode {
return (window as any).__CALL_MODE__ || 'webrtc'
return (window as any).__CALL_MODE__ || 'auto'
}
/**