You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:27:18