无法触发WebRTC跟踪事件

问题描述 投票:0回答:1

我是WebRTC的初学者,并试图在两个浏览器窗口之间建立对等连接。我在本地运行的nodejs中实现了简单的websocket服务器。一切顺利,直到成为候选人为止。交换候选者后,远程流不会开始。我搜索并运行了几个示例,但无法进行我的工作。

我的UI有一些用于交流的输入。这是我正在打电话的内容:

  1. 在第一个窗口中输入用户名作为user1,在第一个窗口中输入远程用户名作为user2
  2. 在第二个窗口中输入用户名作为user2,在第二个窗口中输入远程用户名作为user1
  3. 在两个窗口中单击[单击到Connect to server按钮。 (信令服务器将在此之后了解它们)。
  4. [在第一个窗口中选择我的第一个相机设备,然后在第二个窗口中选择我的第二个相机设备。 (相机将在此之后启动)
  5. 单击第一个窗口中的呼叫

问题是:远程流显示在被调用者窗口(第二个窗口)上,但是从调用者窗口(第一个窗口)的开发控制台中显示,我看不到onTrack函数运行。因此,远程流不会显示在呼叫者上。但是我看到了候选日志。

因此,呼叫者看不到被叫者,但是被呼叫者却看到了呼叫者。

[index.html我在两个浏览器窗口中两次打开了此文件(作为文件:// ...)。

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Webrtc Test</title>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, shrink-to-fit=no"
    />
  </head>
  <body>
    <table border="2">
      <tr>
        <td>
          <span>Signaling Server addres:</span>
          <input type="text" id="serverAddress" value="localhost:3001" onload="window.serverAddress = this;" />
        </td>
        <td>
          <span>Username:</span>
          <input type="text" id="username" value="user1" onload="window.username = this;" />
        </td>
        <td>
          <span>Target username:</span>
          <input type="text" id="remoteUsername" value="user2" onload="window.remoteUsername = this;" />
        </td>
        <td>Devices</td>
      </tr>
      <tr>
        <td>
          <textarea
            name="log"
            id="log"
            cols="50"
            rows="10"
            style="width: 100%; resize: vertical;"
          ></textarea>
        </td>
        <td>
          <video
            id="selfVideo"
            autoplay
            playsinline
            muted
            onload="window.selfVideo = this;"
          ></video>
        </td>
        <td>
          <video id="remoteVideo" autoplay playsinline onload="window.remoteVideo = this;"></video deo>
        </td>
        <td rowspan="2">
          <div>
            <div>Video:<input id="videoCheck" type="checkbox" onload="window.videoCheck = this;" checked /></div>
            <select
              id="videoDevices"
              size="5"
              onload="window.videoDevices = this;"
              onchange="startSelf();"
            ></select>
          </div>
          <div>
            <div>Audio:<input id="audioCheck" type="checkbox" onload="window.audioCheck = this;" /></div>
            <select
              id="audioDevices"
              size="5"
              onload="window.audioDevices = this;"
              onchange="startSelf();"
            ></select>
          </div>
        </td>
      </tr>
      <tr>
        <td colspan="3">
          <div
            style="width: 100%; display: flex; justify-content: space-evenly;"
          >
            <button id="connect" onclick="connect();">Connect to server</button>
            <button id="call" onclick="call();">Call</button>
            <button id="hangup" onclick="hangup();">Hang up</button>
          </div>
        </td>
      </tr>
    </table>

    <!-- <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script> -->
    <script src="adapter.js"></script>
    <script src="setup.js"></script>
    <script src="socket.js"></script>
    <script src="rtc.js"></script>
  </body>
</html>

setup.js用于检测输入设备并在页面加载时创建选项。

const detectDevices = (deviceInfos) => {
  for (let i = 0; i !== deviceInfos.length; ++i) {
    const deviceInfo = deviceInfos[i];
    const element = document.createElement("option");
    element.value = deviceInfo.deviceId;
    if (deviceInfo.kind === "videoinput") {
      element.innerText =
        deviceInfo.label || `camera ${videoDevices.length + 1}`;
      videoDevices.add(element);
    } else if (deviceInfo.kind === "audioinput") {
      element.innerText =
        deviceInfo.label || `microphone ${audioDevices.length + 1}`;
      audioDevices.add(element);
    }
  }
};

navigator.mediaDevices
  .getUserMedia({ audio: true, video: true })
  .then((stream) => {
    window.localStream = stream;
    return navigator.mediaDevices.enumerateDevices();
  })
  .then(detectDevices)
  .then(() => {
    localStream.getTracks().forEach((t) => t.stop());
    delete localStream;
  })
  .catch((error) => console.log("Error detecting devices", error));

const startSelf = async () => {
  if (videoCheck.checked && !videoDevices.value) {
    videoDevices.selectedIndex = 0;
  }

  if (audioCheck.checked && !audioDevices.value) {
    audioDevices.selectedIndex = 0;
  }
  const vDevId = videoDevices.value;
  const aDevId = audioDevices.value;
  // const constraints = {
  //   audio: { deviceId: aDevId ? { exact: aDevId } : undefined },
  //   video: { deviceId: vDevId ? { exact: vDevId } : undefined }
  // };
  const constraints = {};
  if (videoCheck.checked) {
    constraints.video = { deviceId: vDevId ? { exact: vDevId } : undefined };
  }
  if (audioCheck.checked) {
    constraints.audio = { deviceId: aDevId ? { exact: aDevId } : undefined };
  }
  await navigator.mediaDevices
    .getUserMedia(constraints)
    .then((stream) => {
      window.localStream = stream;
      selfVideo.srcObject = stream;
    })
    .catch((error) => console.log("Error start self", error));
};

socket.js

let ws;

const send = (obj) => {
  const message = {
    from: username.value,
    to: remoteUsername.value
  };

  message.data = btoa(JSON.stringify(obj));
  ws.send(JSON.stringify(message));
};

const connect = () => {
  ws = new WebSocket("ws://" + serverAddress.value);
  registerEvents();
};

const registerEvents = () => {
  ws.onopen = () => {
    console.log("websocket open");
    ws.send(JSON.stringify({ from: username.value, data: "merheba" }));
  };

  ws.onmessage = (m) => {
    // parse message
    const message = JSON.parse(m.data);
    if (message.data === "siye de merheba") {
      console.log("connected to server");
      return;
    }
    const data = JSON.parse(atob(message.data));
    message.data = data;
    console.log("message: ", message);
    switch (data.type) {
      case "offer":
        onReceiveOffer(data);
        break;
      case "answer":
        onReceiveAnswer(data);
        break;
      case "candidate":
        console.log("received ice candidate", data);
        pc.addIceCandidate(new RTCIceCandidate(data.candidate));
        break;
    }
  };
};


[c0]用于webrtc调用功能

rtc.js

使用let pc; const initSelf = async () => { pc = new RTCPeerConnection(); pc.onicecandidate = onIceCandidate; pc.ontrack = onTrack; await startSelf(); pc.addStream(localStream); }; const call = async () => { if (!window.localStream || !pc) { await initSelf(); } // send offer pc.createOffer().then((offer) => { pc.setLocalDescription(offer); console.log("sending offer"); send(offer); }); }; const onReceiveOffer = async (receivedOffer) => { console.log("offer receive", receivedOffer); if (!window.localStream || !pc) { initSelf(); } pc.setRemoteDescription(new RTCSessionDescription(receivedOffer)); log.value = JSON.stringify(receivedOffer); pc.setRemoteDescription(receivedOffer); // answer await pc.createAnswer().then((answer) => { pc.setLocalDescription(answer); console.log("answer created: ", answer); send(answer); }); }; const onReceiveAnswer = async (receivedAnswer) => { console.log("answer receive", receivedAnswer); pc.setRemoteDescription(new RTCSessionDescription(receivedAnswer)); log.value = JSON.stringify(receivedAnswer); }; const onTrack = async (event) => { console.log("Add track"); remoteVideo.srcObject = event.streams[0]; }; const onIceCandidate = async (event) => { if (event.candidate) { console.log("ICE candidate"); send({ type: "candidate", candidate: event.candidate }); } }; const hangup = () => { if (pc) { pc.close(); pc = null; } localStream.getTracks().forEach((t) => t.stop()); delete localStream; }; 运行的信号服务器wsServer.js

node wsServer.js
javascript node.js websocket webrtc
1个回答
0
投票

这是语法:

const WebSocket = require("ws");

const wsserver = new WebSocket.Server({ port: 3001 }, () => {
  console.log("server started");
});

let clients = [];

wsserver.on("connection", (socket) => {
  socket.on("message", (message) => {
    console.log("Message: %s", message);

    let data;
    try {
      data = JSON.parse(message);
    } catch (error) {
      console.log("Invalid JSON");
      data = {};
      return;
    }

    if (!data.from || data.from === "") {
      console.log("unknown sender");
      return;
    }

    if (!clients[data.from]) {
      console.log("client add: ", data.from);
      clients[data.from] = socket;
    }

    if (data.data === "merheba") {
      socket.send(JSON.stringify({ data: "siye de merheba" }));
      clients[data.from] = socket;
      return;
    }

    if (data.to) {
      const target = clients[data.to];
      if (target) {
        console.log("forwarding to " + data.to);
        // console.log(target);
        target.send(message);
      }
    }
  });

  // socket.on("close", () => {
  //   if (socket.username) {
  //     delete clients[socket.from];
  //   }
  // });
});

因此,查看您的代码应该类似于:

RTCPeerConnection.ontrack = eventHandler;

您对onicecandidate的处理方式

© www.soinside.com 2019 - 2024. All rights reserved.