WebRTC连接后为什么收不到对方的视频流?

司空艺诺 阅读 3

我在用 WebRTC 做一个简单的点对点视频通话 demo,信令服务器用的是 WebSocket,offer/answer 和 ICE 候选都正常交换了。本地流能显示,但 ontrack 回调一直没触发,远端视频就是出不来。

我检查了 RTCPeerConnection 的配置,也加了 ontrack 监听,但就是没反应。是不是漏了什么关键步骤?比如 addTrack 或者 setRemoteDescription 的顺序问题?

pc.ontrack = (event) => {
  console.log('收到远端流:', event.streams[0]);
  remoteVideo.srcObject = event.streams[0];
};

// 发送方
localStream.getTracks().forEach(track => {
  pc.addTrack(track, localStream);
});
我来解答 赞 8 收藏
二维码
手机扫码查看
1 条解答
皇甫统维
你这个问题很典型,十有八九是下面这几个地方没注意到:

1. createOffer 的时机太早

发送方必须在 addTrack 之后才能 createOffer,否则 offer 里根本没带轨道信息,对方当然收不到。

正确的顺序应该是:
// 发送方
localStream.getTracks().forEach(track => {
pc.addTrack(track, localStream);
});

// 添加完轨道后再创建 offer
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
// 然后通过信令服务器发给对方


2. 接收方 setRemoteDescription 的时机

接收方必须先 setRemoteDescription(offer),ontrack 才会触发。如果你先设置了 ontrack 监听,但还没 setRemoteDescription,那事件是不会来的。

// 接收方 - 收到 offer 后
await pc.setRemoteDescription(new RTCSessionDescription(offer));

// 然后创建 answer
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
// 通过信令服务器发给对方


3. 检查一下 createOffer 生成的 sdp

你可以 console.log 一下创建出来的 offer,看里面有没有 m=video 媒体描述,而且有没有 a=msid 字段。如果没有,那就是 addTrack 的时机问题。

4. 确认对方真的发送了数据

你可以在接收方加个监听看看连接状态:

pc.onconnectionstatechange = () => {
console.log('连接状态:', pc.connectionState);
};

pc.oniceconnectionstatechange = () => {
console.log('ICE状态:', pc.iceConnectionState);
};


如果显示 completed 或 connected,但 ontrack 还是没触发,那就是前面的顺序问题。如果一直是 checking 或 failed,那就是网络穿透的问题,跟代码顺序无关。

你先把 createOffer 放在 addTrack 之后试试,大概率是这个问题。
点赞
2026-03-14 11:01