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

WebRTC 远端同伴流无法显示,请求排查问题原因

WebRTC 远程媒体流接收失败的问题排查与修复

你的代码存在几个核心问题,导致无法接收远程媒体流,下面逐一说明并给出修复方案:

1. 缺失WebRTC核心信令流程

WebRTC建立连接必须完成SDP交换(Offer/Answer)和ICE候选交换,你的代码只初始化了RTCPeerConnection和添加本地轨道,完全没处理这两个关键步骤——没有信令交换,两端根本无法发现彼此并建立连接。

2. 错误的track事件处理

在track回调里调用connection.addTrack(event.track)是多余且错误的,这会把收到的远程轨道重新添加到本地连接,毫无意义,还可能引发异常,必须删除这行代码。

修复后的完整示例代码

下面是包含完整信令流程(模拟信令交换,实际项目中需要替换为真实的信令服务器,比如WebSocket)的代码:

// 初始化PeerConnection
const connection = new RTCPeerConnection({ 
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] 
});

// 处理收到的远程轨道
const remoteVideo = document.querySelector('.remote-video');
connection.addEventListener('track', (event) => {
  const remoteStream = event.streams[0];
  remoteVideo.srcObject = remoteStream;
});

// 监听ICE候选,发送给对方(这里用模拟函数,实际要通过信令服务器发送)
connection.addEventListener('icecandidate', (event) => {
  if (event.candidate) {
    sendToPeer({ type: 'ice-candidate', candidate: event.candidate });
  }
});

// 本地媒体初始化与添加
async function start() {
  const localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
  // 若需要本地预览可添加以下代码
  // const localVideo = document.querySelector('.local-video');
  // localVideo.srcObject = localStream;
  
  localStream.getTracks().forEach(track => {
    connection.addTrack(track, localStream);
  });

  // 创建Offer并设置本地描述
  const offer = await connection.createOffer();
  await connection.setLocalDescription(offer);
  // 发送Offer给对方
  sendToPeer({ type: 'offer', sdp: offer });
}

// 模拟信令接收(实际要从信令服务器监听消息)
async function receiveFromPeer(message) {
  switch (message.type) {
    case 'offer':
      await connection.setRemoteDescription(new RTCSessionDescription(message.sdp));
      // 创建Answer并发送给对方
      const answer = await connection.createAnswer();
      await connection.setLocalDescription(answer);
      sendToPeer({ type: 'answer', sdp: answer });
      break;
    case 'answer':
      await connection.setRemoteDescription(new RTCSessionDescription(message.sdp));
      break;
    case 'ice-candidate':
      await connection.addIceCandidate(new RTCIceCandidate(message.candidate));
      break;
  }
}

// 模拟发送信令到对方(实际项目中替换为WebSocket等信令通道)
function sendToPeer(message) {
  // 此处需实现实际信令发送逻辑,比如通过WebSocket传递给对方
  console.log('发送信令:', message);
  // 本地测试时可取消注释,模拟对方收到消息
  // receiveFromPeer(message);
}

关键说明

  • 信令服务器:实际项目中必须实现一个信令服务器(比如Node.js + WebSocket)来传递Offer、Answer和ICE候选,WebRTC本身不负责信令传输。
  • ICE候选交换:必须监听icecandidate事件并把候选发送给对方,同时接收对方的候选并调用addIceCandidate,否则可能无法建立P2P连接。
  • 本地预览:如果需要预览本地视频,可以添加本地video元素并设置srcObject为本地流。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:40:54