gpt4 book ai didi

javascript - Chrome 中的 "Cannot create answer in state stable"

转载 作者:行者123 更新时间:2023-11-29 15:11:34 25 4
gpt4 key购买 nike

<分区>

我正在实现 WebRTC 点对点调用,它在所有浏览器中运行良好,除非 chrome 是调用初始化程序(调用邀请函数)。

如果 chrome 是 call initializer,ICE 连接状态变为 connected 并且视频出现在另一个 peer 中,然后会出现错误“DOMException: “Cannot create answer in state stable”' 并且视频停止传输到另一个 peer同行。

如果接收器也是 chrome,则错误显示“无法在‘RTCPeerConnection’上执行‘createAnswer’:PeerConnection 无法在 have-remote-offer 或 have-local-pranswer 以外的状态下创建答案。”

这些是 handleVideoOfferMsg 函数和 handleGetUserMediaError 函数(触发错误)代码:

function handleVideoOfferMsg(msg) {
// debugger;
// $("#ring")[0].play();

var localStream = null;

targetUsername = msg.from;

// Call createPeerConnection() to create the RTCPeerConnection.

log("Starting to accept invitation from " + targetUsername);
createPeerConnection();

// We need to set the remote description to the received SDP offer
// so that our local WebRTC layer knows how to talk to the caller.

var desc = new RTCSessionDescription(msg.sdp);

myPeerConnection.setRemoteDescription(desc).then(function () {

log("Setting up the local media stream...");
return navigator.mediaDevices.getUserMedia(responserConstraints);
})
.then(function(stream) {

$("#video-container").removeClass("hidden");
log("-- Local video stream obtained");
localStream = stream;
if(responserConstraints.hasOwnProperty('video'))
{
$("#localVideo").removeClass('hidden')[0].srcObject = localStream;
}

log("-- Adding outgoing tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.then(function() {
log("------> Creating answer");
// Now that we've successfully set the remote description, we need to
// start our stream up locally then create an SDP answer. This SDP
// data describes the local end of our call, including the codec
// information, options agreed upon, and so forth.
return myPeerConnection.createAnswer();
})
.then(function(answer) {
log("------> Setting local description after creating answer");
// We now have our answer, so establish that as the local description.
// This actually configures our end of the call to match the settings
// specified in the SDP.
return myPeerConnection.setLocalDescription(answer);
})
.then(function() {
var msg = {
name: myUsername,
target: targetUsername,
type: "video-answer",
sdp: myPeerConnection.localDescription
};

// We've configured our end of the call now. Time to send our
// answer back to the caller so they know that we want to talk
// and how to talk to us.

log("Sending answer packet back to other peer");
sendToServer(msg);
})
.catch(
handleGetUserMediaError);

}

function handleGetUserMediaError(e) {
log(e);
switch(e.name) {
case "NotFoundError":
alert("Unable to open your call because no camera and/or microphone" +
"were found.");
break;
case "SecurityError":
case "PermissionDeniedError":
// Do nothing; this is the same as the user canceling the call.
break;
default:
//the error occur here
alert("Error opening your camera and/or microphone: " + e.message);
console.log("----------");
console.log(e);
break;
}

// Make sure we shut down our end of the RTCPeerConnection so we're
// ready to try again.

closeVideoCall();
}

邀请函数:

function invite() {
log("Starting to prepare an invitation");
if (myPeerConnection) {
alert("You can't start a call because you already have one open!");
} else {

var clickedUsername = $("input[name=teacherId]").val();
console.log('user id is '+ clickedUsername);

// Don't allow users to call themselves, because weird.

if (clickedUsername === myUsername) {
alert("I'm afraid I can't let you talk to yourself. That would be weird.");
return;
}

// Record the username being called for future reference

targetUsername = clickedUsername;
log("Inviting user " + targetUsername);

// Call createPeerConnection() to create the RTCPeerConnection.

log("Setting up connection to invite user: " + targetUsername);
createPeerConnection();

// Now configure and create the local stream, attach it to the
// "preview" box (id "video"), and add it to the
// RTCPeerConnection.

log("Requesting webcam access...");

isInviter = true;

navigator.mediaDevices.getUserMedia(mediaConstraints)
.then(function(localStream) {

$("#video-container").removeClass("hidden");

console.log(localStream);
log("-- Local video stream obtained");

if(responserConstraints.hasOwnProperty('video'))
{
var localVideo = $('#localVideo');
localVideo.removeClass('hidden')[0].srcObject = localStream;
localVideo[0].mute;
}
else
{
var videoEl = document.getElementById("video");
videoEl.muted = true;
videoEl.srcObject = localStream;
}


log("-- Adding incoming tracks to the RTCPeerConnection");
localStream.getTracks().forEach(track => myPeerConnection.addTrack(track, localStream));
})
.catch(handleGetUserMediaError);
}
}

控制台响应如下:

    [3:28:31 PM] *** ICE gathering state changed to: gathering
opensocket.js:66 [3:28:31 PM] Outgoing ICE candidate: candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10
opensocket.js:66 [3:28:31 PM] Sending 'new-ice-candidate' message: {"type":"new-ice-candidate","candidate":{"candidate":"candidate:202810205 1 udp 2122260223 192.168.1.21 39265 typ host generation 0 ufrag 76SW network-id 1 network-cost 10","sdpMid":"audio","sdpMLineIndex":0,"usernameFragment":"76SW"},"hash":"m0wk8Kaz8JFejuJGte7kAmNtYDiWPZNBGl7fKA5b"}
opensocket.js:66 [3:28:31 PM] -- Local video stream obtained
opensocket.js:66 [3:28:31 PM] -- Adding outgoing tracks to the RTCPeerConnection
opensocket.js:66 [3:28:31 PM] ------> Creating answer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:363 stable
opensocket.js:66 [3:28:31 PM] *** Negotiation needed
opensocket.js:66 [3:28:31 PM] ---> Creating offer
opensocket.js:66 [3:28:31 PM] InvalidStateError: Failed to execute 'createAnswer' on 'RTCPeerConnection': PeerConnection cannot create an answer in a state other than have-remote-offer or have-local-pranswer.

我找不到解决它的方法!错误只发生在 chrome 中!

有什么帮助吗?

编辑:这是我的 handleNegotiationNeededEvent 函数:

function handleNegotiationNeededEvent() {
console.log(myPeerConnection.signalingState);
log("*** Negotiation needed");

log("---> Creating offer");
myPeerConnection.createOffer().then(function(offer) {
log("---> Creating new description object to send to remote peer");
return myPeerConnection.setLocalDescription(offer);
})
.then(function() {
log("---> Sending offer to remote peer");
sendToServer({
name: myUsername,
target: targetUsername,
type: "video-offer",
sdp: myPeerConnection.localDescription
});
})
.catch(reportError);
}

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com