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

WebRTC视频通话站点摄像头授权后无画面问题求助

排查WebRTC视频通话授权后无画面及按钮事件失效问题

我帮你梳理了代码里的几个关键问题,这些应该就是导致画面不显示和按钮事件异常的原因,逐个修复后应该能解决问题:


1. Call按钮事件绑定错误

你在HTML的init函数里已经给Call按钮绑定了一次click事件,但在video-client.js里又写了一行错误的绑定代码:

call.onclick(function(){ createPeerConnection(); });

这里语法本身就不对(正确写法是call.addEventListener('click', fn)),而且重复绑定会导致逻辑冲突。

修复方案:直接删除video-client.js里的这行重复代码,保留HTML中init函数里的绑定逻辑即可。


2. 本地视频流渲染API过时+异步顺序错误

(1)废弃API导致渲染失败

你用了已经被浏览器废弃的window.URL.createObjectURL(stream)来绑定视频流,现代浏览器应该用srcObject直接赋值,兼容性和可靠性更好。

修复displayLocalVideo和displayRemoteVideo:

function displayLocalVideo(stream) {
  localStream = stream;
  local.srcObject = stream; // 替换createObjectURL
  local.play().catch(logError); // 捕获play的错误,避免自动播放限制导致的静默失败
}

function displayRemoteVideo(stream) {
  remoteStream = stream;
  remote.srcObject = stream;
  remote.play().catch(logError);
}

(2)异步流获取顺序错误

在createPeerConnection里,你同步调用getUserMedia后立刻执行pc.addStream(localStream),但getUserMedia是异步操作,此时localStream还没被赋值,导致流根本没添加到PeerConnection里。

重构createPeerConnection函数:

function createPeerConnection() {
  try {
    pc = new RTCPeerConnection(config);
    pc.onicecandidate = handleIceCandidate;
    pc.onaddstream = handleRemoteStreamAdded;
    pc.onremovestream = handleRemoteStreamRemoved;
    pc.onnegotiationneeded = handleNegotiationNeeded;
    console.log("Created RTCPeerConnection");

    // 先获取媒体流,拿到流后再添加到PeerConnection并启动协商
    navigator.mediaDevices.getUserMedia({video: true, audio: false})
      .then(function(stream) {
        displayLocalVideo(stream);
        localStream = stream;
        pc.addStream(localStream);
        pc.createOffer(localDescCreated, logError);
      })
      .catch(logError);
  } catch (e) {
    console.log("Failed to create PeerConnection: " + e.message);
    return;
  }
}

同时删除原来单独调用的getUserMedia(displayLocalVideo),避免重复获取流。


3. ICE候选发送的语法错误

在handleIceCandidate里,你把参数event写成了evt,还出现了拼写错误consolel.log,导致ICE候选根本发不出去,连接无法建立。

修复handleIceCandidate:

function handleIceCandidate(event) {
  console.log("handleIceCandidate event: ", event);
  if(event.candidate) {
    sendMessage(JSON.stringify({'candidate': event.candidate})); // 修正evt为event
  } else {
    console.log("End of ice candidates"); // 修正consolel.log为console.log
  }
}

4. 远端SDP设置错误

在socket接收消息的逻辑里,你犯了两个错误:

  • 把socket接收的参数当成了evt,实际应该是直接的message(因为你emit的时候传的是message)
  • pc.setRemoteDescription的第一个参数是空的RTCSessionDescription,应该传入解析后的SDP数据

修复socket消息接收逻辑:

socket.on("message", function(message){
  if(!pc) createPeerConnection();
  var parsedMsg = JSON.parse(message);
  if(parsedMsg.sdp) {
    pc.setRemoteDescription(new RTCSessionDescription(parsedMsg.sdp), function() {
      if(pc.remoteDescription.type == 'offer') {
        pc.createAnswer(localDescCreated, logError);
      }
    }, logError);
  } else if(parsedMsg.candidate) {
    pc.addIceCandidate(new RTCIceCandidate(parsedMsg.candidate))
      .catch(logError); // 捕获添加候选的错误
  }
});

额外调试建议

修复后可以打开浏览器控制台(F12),查看是否还有报错:

  • 检查媒体流是否正确获取:在displayLocalVideo里打印stream,确认包含视频轨道
  • 检查socket消息收发:在sendMessage和socket.on("message")里打印消息内容,确认SDP和ICE候选正常传递

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:39:18