【问题标题】:No Ice Candidates gathering, peerConnection.iceGatheringState returns "complete" right away没有 Ice Candidates 聚集,peerConnection.iceGatheringState 立即返回“完成”
【发布时间】:2020-04-20 14:32:44
【问题描述】:

我已经坚持了一段时间了。我的代码基于https://webrtc.org/getting-started/firebase-rtc-codelab。我基本上只是将其更改为 React 和 firebase 实时数据库,而不是 firestore。

const VideoRoom = () => {
  const config = {
    apiKey: xxx,
    authDomain: xxx,
    databaseURL: xxx,
    projectId: xxx,
    storageBucket: xxx,
    messagingSenderId: xxx,
    appId: xxx,
  };

  const rtcconfig = {
    iceServers: [
      {
        urls: [
          "stun:stun1.l.google.com:19302",
          "stun:stun2.l.google.com:19302",
        ],
      },
    ],
    iceCandidatePoolSize: 10,
  };

  const { roomId } = useParams();

  if (!firebase.apps.length) {
    firebase.initializeApp(config);
  }

  const db = firebase.database();
  const rooms = () => db.ref("rooms");
  const room = (roomId) => db.ref(`rooms/${roomId}`);
  const callerCandidates = (roomId) =>
    db.ref(`rooms/${roomId}/callerCandidates`);
  const calleeCandidates = (roomId) =>
    db.ref(`rooms/${roomId}/calleeCandidates`);

  const peerConnection = new RTCPeerConnection(rtcconfig);
  var localStream = new MediaStream();
  var remoteStream = null;

  var localVideo = useRef(null);
  var remoteVideo = useRef(null);

  room(roomId)
    .once("value")
    .then((snapshot) => {
      if (!snapshot.val()) {
        createRoom();
        return;
      }
      joinRoomById(roomId, snapshot.val());
    });

  useEffect(() => {
    peerConnection.addEventListener("icegatheringstatechange", () => {
      console.log(
        `ICE gathering state changed: ${peerConnection.iceGatheringState}`
      );
    });

    peerConnection.addEventListener("connectionstatechange", () => {
      console.log(`Connection state change: ${peerConnection.connectionState}`);
    });

    peerConnection.addEventListener("signalingstatechange", () => {
      console.log(`Signaling state change: ${peerConnection.signalingState}`);
    });

    peerConnection.addEventListener("iceconnectionstatechange ", () => {
      console.log(
        `ICE connection state change: ${peerConnection.iceConnectionState}`
      );
    });
  });

  const createRoom = async () => {
    console.log("create room");
    localStream.getTracks().forEach((track) => {
      console.log("adding localStream to peerConnection");
      peerConnection.addTrack(track, localStream);
    });

    peerConnection.addEventListener("icecandidate", (event) => {
      console.log("listening for icecandidate on peerConnection");
      if (!event.candidate) {
        console.log("final icecandidate");
        return;
      }
      console.log("callerCandidate written to database");
      callerCandidates(roomId).set(event.candidate.toJSON());
    });

    const offer = await peerConnection.createOffer();
    await peerConnection.setLocalDescription(offer);
    console.log("Offer created and added to peerConnection local description");

    const roomWithOffer = {
      offer: {
        type: offer.type,
        sdp: offer.sdp,
      },
    };

    await room(roomId).update(roomWithOffer);
    console.log("Offer written to room database document");

    peerConnection.addEventListener("track", (event) => {
      event.streams[0].getTracks().forEach((track) => {
        console.log(
          "listening for track on peerConnection and adding them to remoteStream"
        );
        remoteStream.addTrack(track);
      });
    });

    room(roomId).on("value", async (snapshot) => {
      console.log("listening for remote session in room database document");
      const data = snapshot.val();
      if (!peerConnection.currentRemoteDescription && data && data.answer) {
        console.log("Got remote description: ", data.answer);
        const rtcSessionDescription = new RTCSessionDescription(data.answer);
        await peerConnection.setRemoteDescription(rtcSessionDescription);
      }
    });

    calleeCandidates(roomId).on("value", (snapshot) => {
      console.log(
        "listening for remote ICE candidates in room/calleCandidates database document"
      );
      if (snapshot.val()) {
        snapshot.val().forEach(async (change) => {
          if (change.type === "added") {
            let data = change.doc.data();
            await peerConnection.addIceCandidate(new RTCIceCandidate(data));
          }
        });
      }
    });
  };
};

我通过 react 路由器获取 roomId,为了便于阅读,我省略了其余的组件。

控制台返回如下:

创建房间
信号状态变化:have-local-offer
优惠已创建并添加到 peerConnection 本地描述
ICE 收集状态已更改:完成
在 peerConnection 上监听 icecandidate
最终的冰候选人
将 localStream 添加到 peerConnection
报价写入房间数据库文件
在 room/calleCandidates 数据库文档中监听远程 ICE 候选人
监听房间数据库文档中的远程会话

在 about:webrtc firefox 选项卡中,我可以看到报价已成功创建,但没有任何候选冰

提前致谢!

【问题讨论】:

  • 顺便说一句,我通过在 Google 上搜索完全相同的短语找到了您的问题 :)

标签: reactjs firebase webrtc


【解决方案1】:

因此,事实证明 ICE 候选人收集仅在某些曲目添加到流中时开始,并且必须在报价创建之前完成。

因此,如果您在创建报价之前收集媒体并将其添加到 RTCPeerConnection 实例中,那么您会看到 ICE 候选人被正确收集。

编辑:除此之外,如果您在创建优惠时提供如下选项,它将按预期开始 ICE 收集:

await this.connection.createOffer({
  offerToReceiveAudio: true,
  offerToReceiveVideo: true,
});

希望对你有帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-06
    • 2015-05-31
    • 1970-01-01
    • 2023-03-31
    相关资源
    最近更新 更多