From f7e31a88e0c7ad76605e48ccb6570c172127ea93 Mon Sep 17 00:00:00 2001 From: liqi Date: Thu, 10 Jul 2025 10:38:23 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=EF=BC=9A=201.=20=E6=9C=AC?= =?UTF-8?q?=E5=9C=B0=E8=A7=86=E9=A2=91=E6=B5=81=E8=83=BD=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E5=88=B0=E4=BA=86=202.=20=E6=89=BE=E5=88=B0=E4=BA=86=E8=A7=86?= =?UTF-8?q?=E9=A2=91=E8=BF=9E=E6=8E=A5=E9=94=99=E8=AF=AF=E7=9A=84=E5=8E=9F?= =?UTF-8?q?=E5=9B=A0=EF=BC=9A=E6=8C=82=E6=96=AD=E5=90=8E=E6=9C=AC=E5=9C=B0?= =?UTF-8?q?=E9=BA=A6=E5=85=8B=E9=A3=8E=E5=92=8C=E8=A7=86=E9=A2=91=E5=B9=B6?= =?UTF-8?q?=E6=B2=A1=E6=9C=89=E5=85=B3=E9=97=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 现有问题: 1. 需要在挂断后关闭麦克风和摄像头 2. 没有渲染远程流推送的视频 --- src/components/VideoCallComponent.vue | 76 ++++++++++- src/composables/useWebRTC.js | 176 ++++++++++++++++++++++++-- 2 files changed, 234 insertions(+), 18 deletions(-) diff --git a/src/components/VideoCallComponent.vue b/src/components/VideoCallComponent.vue index ea1f880..8a445c2 100644 --- a/src/components/VideoCallComponent.vue +++ b/src/components/VideoCallComponent.vue @@ -45,13 +45,31 @@
-
+ +
+ 未检测到摄像头 +
+ + +
+ 未检测到麦克风 +
+ + +
摄像头未工作
-
+ + +
麦克风未工作
-
+ + +
对方未开启摄像头
@@ -84,12 +102,12 @@
@@ -113,12 +131,12 @@
@@ -282,6 +300,14 @@ const localVideo = ref(null); const remoteVideo = ref(null); const remoteVideoPreview = ref(null); +// 新增:设备状态检测 +const deviceStatus = reactive({ + hasCamera: false, + hasMicrophone: false, + cameraWorking: false, + microphoneWorking: false, +}) + // 获取当前通话状态 const callStatus = computed(() => { return chatStore.callStatus; @@ -533,6 +559,37 @@ const handleWindowResize = () => { position.y = Math.max(0, Math.min(position.y, window.innerHeight - height)); }; +// 远端视频轨道检测 +const hasRemoteVideo = computed(() => { + if (!webrtc.remoteStream.value) return false + const tracks = webrtc.remoteStream.value.getVideoTracks() + return tracks.length > 0 && tracks.some(t => t.readyState === 'live') +}) + +// 监听本地流变化 +watch(() => webrtc.localStream.value, (stream) => { + if (!stream) return + + // 更新设备工作状态 + deviceStatus.cameraWorking = stream.getVideoTracks().length > 0 && + stream.getVideoTracks().some(t => t.readyState === 'live') + + deviceStatus.microphoneWorking = stream.getAudioTracks().length > 0 && + stream.getAudioTracks().some(t => t.readyState === 'live') +}) + +// 初始化设备检测 +const checkDevices = async () => { + try { + const devices = await navigator.mediaDevices.enumerateDevices() + deviceStatus.hasCamera = devices.some(d => d.kind === 'videoinput' && d.deviceId !== '') + deviceStatus.hasMicrophone = devices.some(d => d.kind === 'audioinput' && d.deviceId !== '') + console.log("📷 设备检测结果:", deviceStatus) + } catch (error) { + console.error("❌ 设备检测失败:", error) + } +} + // 监听通话状态 watch(() => chatStore.callStatus, (status, oldStatus) => { console.log("📞 VideoCallComponent 监听到通话状态变化:", oldStatus, "->", status); @@ -597,6 +654,9 @@ onMounted(() => { window.addEventListener('resize', handleWindowResize); + // 初始化设备检测 + checkDevices(); + console.log("🚀 VideoCallComponent mounted, callStatus:", chatStore.callStatus, "isIncoming:", props.isIncoming); if (['calling', 'connecting', 'ongoing'].includes(chatStore.callStatus)) { @@ -621,6 +681,7 @@ onUnmounted(() => {