From 5cebaec98af8b4d36b5bf7d24e6d8592dd5cf724 Mon Sep 17 00:00:00 2001
From: 罗广辉 <guanghui.luo@foxmail.com>
Date: Thu, 12 Feb 2026 00:22:41 +0800
Subject: [PATCH] feat: 语音

---
 applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue |   59 +++++++++++++++++++++++++++++++++++++++++------------------
 1 files changed, 41 insertions(+), 18 deletions(-)

diff --git a/applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue b/applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
index 6d7ee04..79c9fb0 100644
--- a/applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
+++ b/applications/mobile-web-view/src/appPages/voiceCallDetail/index.vue
@@ -8,7 +8,7 @@
 			<div class="contactAvatar">
 				<img :src="defaultAvatar" alt=""></img>
 			</div>
-			
+
 			<!--  联系人名称-->
 			<div class="contactName">
 				{{ contactName }}
@@ -39,6 +39,7 @@
 <script setup>
 import { useRoute } from 'vue-router'
 import defaultAvatar from '@/appDataSource/appwork/defaultAvatar.svg'
+import { showToast } from 'vant'
 const route = useRoute()
 /** ✅ 你的 WS 地址前缀(后面拼 userId) */
 // const WS_BASE = 'ws://218.202.104.82:38201/ws/chat?userId='
@@ -229,21 +230,43 @@
 	}
 
 	try {
-		localStream = await navigator.mediaDevices.getUserMedia({ 
-			audio: {
-				echoCancellation: true,
-				noiseSuppression: true,
-				autoGainControl: true,
-				// 移动端特定配置
-				channelCount: 1,
-				sampleRate: 16000,
-				sampleSize: 16
-			}
-	  	})
-		log('✅ 已获取本地麦克风')
+		// 尝试使用完整约束
+		try {
+			localStream = await navigator.mediaDevices.getUserMedia({
+				audio: {
+					echoCancellation: true,
+					noiseSuppression: true,
+					autoGainControl: true,
+					channelCount: 1,
+					sampleRate: 16000,
+					sampleSize: 16
+				}
+			})
+			log('✅ 已获取本地麦克风(标准约束)')
+		} catch (strictError) {
+			// 如果标准约束失败,尝试最简单的约束
+			log('⚠️ 标准约束失败,尝试简化约束:', String(strictError))
+			localStream = await navigator.mediaDevices.getUserMedia({
+				audio: true
+			})
+			log('✅ 已获取本地麦克风(简化约束)')
+		}
 		return localStream
 	} catch (e) {
 		log('❌ 获取麦克风失败:', String(e))
+
+		// 提供更详细的错误信息
+		if (e.name === 'NotReadableError') {
+			log('❌ NotReadableError: 麦克风可能被其他应用占用,或权限未正确配置')
+			showToast('麦克风被占用或权限未授予')
+		} else if (e.name === 'NotAllowedError') {
+			log('❌ NotAllowedError: 用户拒绝了麦克风权限')
+			showToast('请授予麦克风权限')
+		} else if (e.name === 'NotFoundError') {
+			log('❌ NotFoundError: 未找到麦克风设备')
+			showToast('未找到麦克风设备')
+		}
+
 		throw e
 	}
 }
@@ -530,13 +553,13 @@
 	lastOfferSdp = null
 
 	state.value = 'idle'
-	
+
 	// 清除之前的定时器
 	if (endTimer.value) {
 		clearTimeout(endTimer.value)
 		endTimer.value = null
 	}
-	
+
 	// 根据是谁发起的挂断决定不同的行为
 	if (sendToPeer) {
 		// 自己主动挂断:不提示,不延迟,直接跳转
@@ -552,7 +575,7 @@
 		// 对方挂断:显示提示,延迟10秒跳转
 		callEnded.value = true
 		endMessage.value = '对方已挂断'
-		
+
 		// 延迟5秒后跳转页面
 		endTimer.value = setTimeout(() => {
 			// 返回上一页(uni-app的语音通话列表页面)
@@ -580,7 +603,7 @@
 			if (params.access_token) {
 				accessToken.value = params.access_token;
 				log('🔗 从params获取access_token:', accessToken.value);
-			}	
+			}
 		} catch (e) {
 			log('❌ 解析params参数失败:', String(e));
 		}
@@ -882,4 +905,4 @@
 	height: 220px;
 	margin-bottom: 60px;
 }
-</style>
\ No newline at end of file
+</style>

--
Gitblit v1.9.3