From e4439e5d0a2cba9983f013bd044fe4e22c7b7077 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Wed, 11 Feb 2026 16:35:06 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'
---
applications/drone-command/src/views/audioCall.vue | 28 ++++++++++++++++++----------
1 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/applications/drone-command/src/views/audioCall.vue b/applications/drone-command/src/views/audioCall.vue
index 9957564..aa0cbaf 100644
--- a/applications/drone-command/src/views/audioCall.vue
+++ b/applications/drone-command/src/views/audioCall.vue
@@ -64,13 +64,11 @@
const s = String(seconds.value % 60).padStart(2, '0')
return `${m}:${s}`
})
-
function startTimer() {
stopTimer()
seconds.value = 0
timer = setInterval(() => seconds.value++, 1000)
}
-
function stopTimer() {
if (timer) clearInterval(timer)
timer = null
@@ -78,7 +76,6 @@
// 心跳
let pingTimer = null
-
function startPing() {
stopPing()
// 每 25 秒发一次 ping(你后端有 PING/PONG)
@@ -86,7 +83,6 @@
if (connected.value) send('ping', 'system', null)
}, 25000)
}
-
function stopPing() {
if (pingTimer) clearInterval(pingTimer)
pingTimer = null
@@ -121,7 +117,14 @@
function createPC() {
pc = new RTCPeerConnection({
- iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],
+ iceServers: [{ urls: 'stun:stun.l.google.com:19302' },
+ { urls: 'stun:stun.l.google.com:19302' },
+ { urls: 'stun:stun1.l.google.com:19302' },
+ { urls: 'stun:stun.stunprotocol.org:3478' },
+ // 添加多个公共TURN服务器以提高跨网络连接成功率
+ { urls: ['turn:freeturn.net:80', 'turn:freeturn.net:443'], username: 'free', credential: 'free' },
+ // 备用TURN服务器
+ { urls: 'turn:turn.cloudlifter.io:443', username: 'webrtc', credential: 'webrtc' }],
})
pc.onicecandidate = (e) => {
@@ -130,13 +133,13 @@
}
}
+ // 步骤7 接收音频流并且播放
pc.ontrack = (e) => {
log('✅ 收到远端音频流')
const stream = e.streams[0]
if (remoteAudio.value) {
remoteAudio.value.srcObject = stream
- remoteAudio.value.play().catch(() => {
- })
+ remoteAudio.value.play().catch(() => {})
}
}
@@ -172,6 +175,7 @@
pc.getSenders().map(s => (s.track ? s.track.id : null)).filter(Boolean)
)
+ // 步骤6 发送音频流
stream.getTracks().forEach(track => {
if (!existingTrackIds.has(track.id)) {
pc.addTrack(track, stream)
@@ -184,6 +188,7 @@
return stream
}
+// 步骤5
async function flushCandidates() {
if (!pc || !pc.remoteDescription) return
while (pendingCandidates.length) {
@@ -240,6 +245,7 @@
return
}
+ // 步骤2
if (t === 'offer') {
// 被叫收到 offer:只有点击接听后才真正应答(你要求“先点接听”)
offeredByPeer = true
@@ -259,10 +265,12 @@
return
}
+ // 步骤3
if (t === 'answer') {
log('✅ 收到 answer,通话建立')
if (!pc) createPC()
await pc.setRemoteDescription(new RTCSessionDescription(msg.payload?.sdp))
+ // 步骤4
await flushCandidates()
state.value = 'in-call'
@@ -373,6 +381,7 @@
// ✅ 不会重复 addTrack
await ensureLocalTracksAdded()
+ // 步骤1
const offer = await pc.createOffer()
await pc.setLocalDescription(offer)
@@ -380,6 +389,7 @@
log('➡️ 已发送 offer 给', peerUid.value)
}
+// 步骤2
async function answerOffer(offerSdp, from) {
if (!offerSdp) {
log('❌ offer sdp 为空,无法接听')
@@ -411,8 +421,7 @@
function cleanup(sendToPeer) {
try {
if (sendToPeer) send('hangup', peerUid.value, null)
- } catch {
- }
+ } catch {}
stopTimer()
@@ -442,4 +451,3 @@
if (ws) ws.close()
})
</script>
-
\ No newline at end of file
--
Gitblit v1.9.3