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

WebRTC结合Node.js+Socket.io实现屏幕共享时报getSender未定义错误

问题根因

你遇到的报错mediaTypeError: Cannot read properties of undefined (reading 'getSender')核心是两个问题:

  1. currentPeer变量在调用时未完成初始化,值为undefined
  2. 原生RTCPeerConnection获取发送轨道的方法是复数形式getSenders(),你使用了单数的getSender(),方法本身不存在

修复方案

1. 调整currentPeer赋值时机

你之前将currentPeer赋值放在call.on("stream")回调中,该回调仅在收到远端流时才触发,会导致初始化延迟。将赋值逻辑提前到应答呼叫的阶段:

peer.on("call", function (call) {
    getUserMedia(
        { video: true, audio: true },
        function (stream) {
            call.answer(stream); // Answer the call with stream.
            // 此处提前赋值对等连接实例
            currentPeer = call.peerConnection
            const video = document.createElement("video");
            call.on("stream", function (remoteStream) {
                if (!peerList.includes(call.peer)) {
                    addVideoStream(video, remoteStream);
                    peerList.push(call.peer);
                }
            });
        },
        function (err) {
            console.log("Failed to get local stream", err);
        }
    );
});

2. 修正屏幕共享逻辑,补全校验和方法名

修改屏幕共享触发代码,修正方法名、补全非空校验,同时增加屏幕共享停止后自动切回摄像头的逻辑:

share__Btn.addEventListener("click", (e) => {
    navigator.mediaDevices.getDisplayMedia({
        video: {
            cursor: "always"
        },
        audio: {
            echoCancellation: true,
            noiseSuppression: true
        }
    }).then((stream) => {
        let videoTrack = stream.getVideoTracks()[0];
        // 对等连接未初始化时直接抛出提示,避免报错
        if (!currentPeer) {
            console.log("当前无活跃通话连接,请等待其他用户加入后再尝试屏幕共享");
            return;
        }
        // 修正为正确的复数方法getSenders
        let sender = currentPeer.getSenders().find(function (s) {
            // 加可选链避免track为空时报错
            return s.track?.kind == videoTrack.kind
        })
        if (sender) {
            sender.replaceTrack(videoTrack)
        }
        // 监听用户主动停止屏幕共享事件,自动切回摄像头流
        videoTrack.onended = () => {
            navigator.mediaDevices.getUserMedia({video: true, audio: true}).then(camStream => {
                const camTrack = camStream.getVideoTracks()[0]
                const camSender = currentPeer.getSenders().find(s => s.track?.kind == 'video')
                if (camSender) camSender.replaceTrack(camTrack)
            })
        }
    }).catch((err) => {
        console.log("无法获取屏幕共享流:" + err)
    })
})

3. 多人会议适配(可选)

如果你的应用要支持多人同时参会,不要使用单个currentPeer变量存储对等连接,改用Map结构存储所有参会用户ID对应的peerConnection实例,屏幕共享时遍历所有实例替换轨道即可。

内容的提问来源于stack exchange,提问作者Thibaut

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 15:06:00