声网Agora JS SDK 4.6.3语音通话本地音频无法推流,手动开关麦恢复
问题根因
你代码中的核心问题是调用setEnabled异步方法时未添加await,导致执行时序错乱:
AgoraRTC.createMicrophoneAudioTrack生成的本地音频轨道默认就是启用状态,无需额外调用setEnabled(true)setEnabled是异步方法,你未等待该方法执行完成就调用publish发布轨道,此时轨道状态仍处于切换中,SDK不会传输音频数据,后续手动重新调用两次setEnabled等待状态同步完成后,推流就恢复正常- 额外问题:纯语音通话场景指定
codec: "vp8"(视频编码)会增加不必要的状态同步开销,且你将user-published等事件监听放在join之后执行,存在漏收远端用户发布通知的风险
修复方案
修改后的代码如下,你可以直接替换原有逻辑:
首先CDN保持不变:
<script src="https://download.agora.io/sdk/release/AgoraRTC_N-4.6.3.js"></script>
JS逻辑修改如下:
var rtc = { client: null, localAudioTrack: null, }; let searchParams = new URLSearchParams(window.location.search) let channel = searchParams.get('cid') var options = { appId: "<appId>", channel: channel, token: null, }; async function startBasicCall() { // 纯语音场景无需指定codec参数 rtc.client = AgoraRTC.createClient({ mode: "rtc" }); // 先注册事件监听,再加入频道,避免漏收事件 rtc.client.on("user-published", async (user, mediaType) => { await rtc.client.subscribe(user, mediaType); if (mediaType === "audio") { user.audioTrack.play(); } }); rtc.client.on("user-unpublished", user => { // 原代码中未创建过对应DOM,这里先加判空避免报错 const playerContainer = document.getElementById(user.uid); playerContainer && playerContainer.remove(); }); const uid = await rtc.client.join(options.appId, options.channel, options.token, null); rtc.localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack(); // 删掉多余的setEnabled调用,如果确实需要调用必须加await // 发布轨道 await rtc.client.publish([rtc.localAudioTrack]); } async function leaveCall() { rtc.localAudioTrack && rtc.localAudioTrack.close(); await rtc.client.leave(); } if(channel != "" && channel != null){ startBasicCall(); }
额外兼容方案
如果修改后仍偶现该问题,可以在发布轨道成功后增加短延迟校验,主动同步一次轨道状态:
await rtc.client.publish([rtc.localAudioTrack]); setTimeout(async () => { await rtc.localAudioTrack.setEnabled(false); await rtc.localAudioTrack.setEnabled(true); }, 100);
内容的提问来源于stack exchange,提问作者Vikas Chauhan
相关产品推荐
相关产品推荐

