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
相关产品推荐
相关产品推荐

