使用PeerJS屏幕共享时远端无法收到共享流音频的问题求助
屏幕共享时对端无法接收共享音频问题排查
你代码里存在3个直接导致问题的核心错误:
- 获取到屏幕共享的音频轨道后仅定义变量存储,没有任何将其添加/转发到PeerConnection连接的逻辑,仅处理替换了视频轨道,最后调用
broadcastNewTracks也只传了video类型,音频轨完全没被传输到对端 getDisplayMedia的audio参数配置存在兼容性问题,多数Chromium内核浏览器不支持audio传入约束对象,仅支持布尔值true,传对象可能导致无法正常获取音频轨道- 缺少必要的权限引导和空值判断:浏览器弹出共享选择面板时,需要用户主动勾选「分享音频」选项才能拿到音频流,当前代码直接取
screenStream.getAudioTracks()[0],用户未勾选时会直接抛出JS错误中断流程
修复方案
1. 修正屏幕采集参数,兼容浏览器实现
不要在getDisplayMedia调用时直接给audio传约束,先传true拿到音频轨后,再单独给音频轨加回声消除、降噪配置,避免兼容问题。
2. 正确处理音频轨道的传输
注意:原有PeerConnection中的音频sender是用来传输麦克风音频的,不要直接用屏幕共享音频轨替换这个sender的轨道,否则对端会听不到你的麦克风声音。
如果需要同时传输麦克风声音+屏幕共享音频,有两种可选用法:
- 方案A:通过Web Audio API将麦克风音轨和屏幕共享音轨混合成单条音轨,替换原有音频sender的轨道,实现简单,对端无需修改播放逻辑
- 方案B:调用PeerConnection的
addTrack方法,将屏幕共享的音频轨作为新的音轨添加到连接中,灵活性更高,但对端需要新增音频元素播放这条音轨
3. 增加空值判断和用户引导
在获取到屏幕共享流后,先判断音频轨是否存在,如果不存在提示用户需要勾选共享音频选项。停止共享时也要记得关闭、移除对应的屏幕音频轨,避免漏音。
修复后的核心代码示例
sharescreen.addEventListener('click', async () => { if (screenStream != null) { alert("屏幕共享已在运行中"); return; } try { // 修正采集参数,audio先传true保证兼容性 const stream = await navigator.mediaDevices.getDisplayMedia({ video: { cursor: "always" }, audio: true }); screenStream = stream; socket.emit('share', myPeer.id, ROOM_ID); const videoTrack = screenStream.getVideoTracks()[0]; const screenAudioTrack = screenStream.getAudioTracks()[0]; // 判断用户是否勾选了共享音频 if (!screenAudioTrack) { alert("未检测到屏幕共享音频,请在共享选择面板中勾选「分享音频」选项"); } else { // 给屏幕共享音频轨加语音处理配置 await screenAudioTrack.applyConstraints({ echoCancellation: true, noiseSuppression: true }); // 新增音频轨到Peer连接,不要替换原有麦克风的音频sender pc.forEach(element => { element.peerConnection.addTrack(screenAudioTrack, stream); }); } // 视频轨原有逻辑保持不变 const stopShareHandler = () => stopSharingScreen(videoTrack); videoTrack.onended = stopShareHandler; screenStream.getVideoTracks()[0].addEventListener('ended', stopShareHandler); pc.forEach(element => { const videoSender = element.peerConnection.getSenders().find(s => s.track && s.track.kind === 'video'); videoSender.replaceTrack(videoTrack); }); // 修正广播逻辑,同步广播音频轨 broadcastNewTracks(stream, 'video', false); if (screenAudioTrack) { broadcastNewTracks(stream, 'audio', false); } } catch(err) { console.log(err.name + ": " + err.message); } });
额外注意事项
- 兼容性限制:目前仅Chromium内核浏览器(Chrome、Edge等)完整支持屏幕共享音频采集,Firefox仅支持标签页音频采集,MacOS下Safari 15.4+才部分支持,低版本Safari完全拿不到屏幕共享音频
- 系统权限限制:MacOS下共享整个屏幕时无法获取系统音频,仅共享单个浏览器标签页时可以采集到标签页播放的音频;Windows下共享整个屏幕时勾选「分享系统音频」即可采集到所有系统播放的声音
内容的提问来源于stack exchange,提问作者Yogesh Dobariya
相关产品推荐
相关产品推荐

