From ba7447ddb93fe7490ae067bb4fc5ca3421396df3 Mon Sep 17 00:00:00 2001 From: duoaohui <928970622@qq.com> Date: Sat, 23 May 2026 22:42:26 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=86=E9=A2=91=E4=BC=9A=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/cloud-law/video-call.vue | 30 ++++++++++++++++++--- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/frontend/src/pages/cloud-law/video-call.vue b/frontend/src/pages/cloud-law/video-call.vue index 94f7034..4280dd9 100644 --- a/frontend/src/pages/cloud-law/video-call.vue +++ b/frontend/src/pages/cloud-law/video-call.vue @@ -450,6 +450,22 @@ const swapPrimaryTile = () => { preferSelfMain.value = !preferSelfMain.value } +// 关键:在用户点击的"手势作用域"内自己 getUserMedia,把 track 传给 meetingStore, +// 避免 mediasoup 内部二次 getUserMedia 被 WebView 拒(NotAllowedError Permission denied)。 +const acquireAudioTrack = async () => { + if (!navigator?.mediaDevices?.getUserMedia) throw new Error('当前环境不支持 getUserMedia') + const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false }) + return stream.getAudioTracks()[0] +} +const acquireVideoTrack = async () => { + if (!navigator?.mediaDevices?.getUserMedia) throw new Error('当前环境不支持 getUserMedia') + const stream = await navigator.mediaDevices.getUserMedia({ + audio: false, + video: { width: { ideal: 640 }, height: { ideal: 480 }, facingMode: 'user' } + }) + return stream.getVideoTracks()[0] +} + const onMicToggle = async () => { pushDebug(`mic点击 loading=${audioLoading.value} leaving=${leaving.value} on=${audioEnabled.value} producer=${meetingStore.localProducers?.audio || 'null'}`) if (audioLoading.value || leaving.value) { @@ -463,8 +479,11 @@ const onMicToggle = async () => { await meetingStore.stopLocalAudio() pushDebug('mic stop 完成') } else { - pushDebug('mic -> startLocalAudio') - await meetingStore.startLocalAudio() + pushDebug('mic -> getUserMedia(audio)') + const track = await acquireAudioTrack() + pushDebug(`mic 拿到 track id=${track?.id?.slice(0, 8)} label=${track?.label || ''}`) + pushDebug('mic -> startLocalAudio(track)') + await meetingStore.startLocalAudio(undefined, track) pushDebug(`mic start 完成 enabled=${meetingStore.localAudioEnabled}`) localMediaError.value = '' } @@ -489,8 +508,11 @@ const onCamToggle = async () => { await meetingStore.stopLocalVideo() pushDebug('cam stop 完成') } else { - pushDebug('cam -> startLocalVideo') - await meetingStore.startLocalVideo() + pushDebug('cam -> getUserMedia(video)') + const track = await acquireVideoTrack() + pushDebug(`cam 拿到 track id=${track?.id?.slice(0, 8)} label=${track?.label || ''}`) + pushDebug('cam -> startLocalVideo(track)') + await meetingStore.startLocalVideo(undefined, track) pushDebug(`cam start 完成 enabled=${meetingStore.localVideoEnabled}`) localMediaError.value = '' }