jquery 如何识别实现webrtc的代码是否正常工作?

crcmnpdw  于 2022-12-12  发布在  jQuery
关注(0)|答案(1)|浏览(183)

我现在正在做一个webrtc项目,这个项目是之前由另一个开发者写的。虽然我现在是webrtc的新手,我在删除过时的函数和其他东西后努力使它工作,现在我能识别出我的步骤中有什么错误吗?
我正在here中执行以下步骤
我代码是关于触发器的呼叫按钮

$(dod)
  .find(".call")

然后我发出信号

wbsc.emit("SEND_EVENT_EMIT_CALL_AUDIO", {
  data: { type: "login", id: id },
});
$(dod).hide(); 
//call*donecallProccess 1
setTimeout(() => {
  wbsc.emit("SEND_EVENT_EMIT_CALL_AUDIO", {
    data: { type: "doneoif", id: id },
  });
}, 2e3);

可以在这里触发和处理

case "donecall":
    call(data.id);
    break;
    
  case "showcall":
    handleLogin(data.success, data.id);
    break;
  
  case "offercall":
    handleOffer(data.offer, data.name);
    break;
 
  case "answercall":
    handleAnswer(data.answer);
    break;
 
  case "candidatecall":
    handleCandidate(data.candidate);
    break;
  
  case "leavecall": 
    handleLeave();

然后,在每个处理程序login和getUserMediaSuccess之后运行此代码,从媒体流收集权限并创建新RTCPeerConnection(服务器),使用addtrack从我的流中获取曲目(如果我正确实现了它,且如果发生了ontrack),我可以收集流以像这样添加到远程对等体吗?或者应该只添加

yourConn.ontrack = (event) => {
      if (event.candidate !== null) {
       remoteVideo.srcObject = event.streams[0];
      } else {
        console.log("there is an error with on trackevent", event);
      }
    };

上次处理登录和呼叫完整代码是

let handleLogin = async (success) => {
  try {
    if (success) {
      localVideo = document.getElementById("wbrtclocal");
      remoteVideo = document.getElementById("wbrtcremote");
      var getUserMedia = navigator.mediaDevices.getUserMedia|| navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia ;

      if (getUserMedia) {
       getUserMedia({
            audio: { noiseSuppression: false },
          })
          .then(getUserMediaSuccess)
          .catch(errorHandler);
      } else {
        alert("Your browser does not support getUserMedia API");
      }
    } else {
      alert("Ooops...try a different username");
    }
  } catch (err) {
    errorHandler(error);
  }
};

let getUserMediaSuccess = async (streams) => {
  try {
    
    yourConn = new RTCPeerConnection(servers);
    if(streams){
      localStream = streams;
      localVideo.srcObject = streams;
      streams.getTracks().forEach((track) => yourConn.addTrack(track, streams));
    }
   
    yourConn.onicecandidate = (event) => {
      if (event.candidate) {

        wbsc.emit("SEND_EVENT_EMIT_CALL_AUDIO", {
          data: {
            type: "candidate",
            candidate: event.candidate,
            id: connectedUser,
          },
        });

      }
      console.log("nwe ice candidate is", event.candidate);
      console.log("nwe stream is", streams);
    };

     remoteStream = new MediaStream();
    remoteVideo.srcObject = remoteStream;

    yourConn.ontrack = (event) => {
      if (event.candidate !== null) {
        event.streams[0].getTracks().forEach((track) => {
          remoteStream.addTrack(track);
        });
      } else {
        console.log("there is an error with on trackevent", event);
      }
    };
  } catch (err) {
    errorHandler(error);
  }
  console.log("stream is", streams);
};

调用函数

async function call(id) {
  $("#videoCall").show();
  if (id.length > 0) {
    connectedUser = id;

    try {

     RTCPeerConnection.createOffer().
    offer.
      await yourConn
        .createOffer()
        .then((offer) => successCallback)
        .catch((e) => {
          fl(e);
        });
      let successCallback = async (offer) => {
        try {
     
         
          yourConn
            .setLocalDescription(offer)
            .then(
             
              wbsc.emit("SEND_EVENT_EMIT_CALL_AUDIO", {
                data: { type: "offer", offer: offer, id: connectedUser },
              })
            )
            .catch((e) => {
              fl(e);
            });
        } catch (e) {
          fl(e);
        }
      };
    } catch (e) {
      fl(e);
    }

    const user = U_CASH[id];
    if (user) {
      $("#videoCall")
        .find(".u-pic")
        .css("background-image", "url(" + removegifpic(user.pic + ")"));
      $("#videoCall").find(".u-topic").text(user.topic);
    }
    $(".statecall").text("جاري الإتصال");
    hl($(".statecall"), "warning");
  } else {
    alert("username can't be blank!");
  }
  console.log("connectedUser", id);
  console.log("offer", offer);
  console.log();
  console.log();
  console.log();
}

and this about each one for those 
[handleOffer , handleAnswer , handleCandidate , handleLeave]

let handleOffer = async (offer, name) => {
  $("#callvideonot").show();
  const user = U_CASH[name];
  if (user) {
    $("#callvideonot")
    .find(".u-pic")
    .css("background-image", "url(" + removegifpic(user.pic + ")"));
    $("#callvideonot").find(".u-topic").text(user.topic);
  }
 
  $(".callvideoaccept").on("click", async () => {
    connectedUser = name;
    

    await yourConn.setRemoteDescription(offer);

 
    yourConn
      .createAnswer()
      .then((answer) => t.setLocalDescription(answer))
      .then(() => {
        wbsc.emit("SEND_EVENT_EMIT_CALL_AUDIO", {
          data: { type: "answer", answer: answer, id: connectedUser },
        });
      })
      .catch(fl);

    
    const user = U_CASH[name];
    if (user) {
      $(".statecall").text("متصل");
      hl($(".statecall"), "success");
      $("#videoCall")
        .find(".u-pic")
        .css("background-image", "url(" + removegifpic(user.pic + ")"));
      $("#videoCall").find(".u-topic").text(user.topic);
    }
    $("#callvideonot").hide();
    $("#videoCall").show();
  });

   
  $(".callvideodeny").on("click", function () {
    wbsc.emit("SEND_EVENT_EMIT_CALL_AUDIO", {
      data: { type: "leave", id: name },
    });
  });
};

   
let handleAnswer = async (answer) => {
  try {
    $(".statecall").text("متصل");
    hl($(".statecall"), "success");
    //here we delete new RTCSessionDescription because constructor is deprecated.
   await yourConn.setRemoteDescription(answer);
  } catch (e) {
    fl(e);
  }
};

let handleCandidate = async (candidate) => {
  try {
      
    var NewlyIceCandidate = new RTCIceCandidate(candidate)
    .setRemoteDescription().
    await yourConn.addIceCandidate(NewlyIceCandidate);
   
  } catch (e) {
    fl(e);
  }
};
   
function handleLeave() {
  $("#callvideonot").hide();
  $(".statecall").text("رفض");
  hl($(".statecall"), "danger");
  $(".vloumemic").removeClass("fa-volume-off");
  $(".vloumemic").addClass("fa-volume-up");
  $(".mutemic").removeClass("fa-microphone-slash");
  $(".mutemic").addClass("fa-microphone");
  setTimeout(() => {
    $("#videoCall").hide();
  }, 1e3);
  if (localStream) {
    localStream.getTracks().forEach((e) => e.stop());
  }
  if (connectedUser) {
    connectedUser = null;
  }
  remoteVideo.src = null;
  if (yourConn) {
    yourConn.close();
    yourConn.onicecandidate = null;
    yourConn.ontrack = null;
    localStream = null;
  }
}

在这里here第7条指令中,他们说我应该添加等待来自信令服务的传入远程SDP描述,并使用RTCPeerConnection.setRemoteDescription()设置它。作为调用者,我可以在哪里添加它?在handleCandidate函数中?
并且在被调用方的第1条指令中,我应该创建一个具有适当ICE配置的新RTCPeerConnection示例。
我能重复使用吗

yourConn = new RTCPeerConnection(servers);

或者应该示例化一个新的连接,以防止在网站服务器进程中发生冲突,作为一个非yourConn的全局值,并在此文件的顶层中,在所有连接上重用它,对等方2或被调用方是否应该有另一个新的RTCPeerConnection?
对于remoteVideo.srcObject = remoteStream;,remoteStream值是全局的,我覆盖了它。我可以在这里添加新的媒体流吗?还是只处理当前的remoteVideo元素比较好?

// remoteStream = new MediaStream();
    remoteVideo.srcObject = remoteStream;
lf5gs5x2

lf5gs5x21#

这里的问题是拆分RTCPeerConnection对象,并为本地和远程的每个对等体创建一个新对象,我这样做了,在完全删除addtrack并将其替换为addtranceiver和gettranceiver后,它工作正常。您可以从上一个问题的答案中找到它,我修复了它here
并且不需要覆盖或重置srcObect值。同一MediaStream中接收器端的曲目过渡应该是“无缝的”RTCRtpSender.replaceTrack这允许您无缝地更改正在发送的曲目,而不必以另一个提供/应答周期为代价重新协商

相关问题