Javascript WebRTC 2路视频无法设置远程应答sdp:在错误状态下调用:kStable
嗨,我正试图建立一个视频聊天使用WebRTC与信号器的信号,它的基础上 错误是: setRemoteDescription:InvalidStateError:设置远程应答失败 sdp:在错误状态下调用:kStable onError@webrtc.js:26 pc.setRemoteDescription.error@webrtc.js:101 2webrtc.js:26 func LOCALDESCREATED:操作错误:无法设置本地应答sdp: 在错误状态下调用:kStable onError@webrtc.js:26 pc.setLocalDescription.error@webrtc.js:115 3webrtc.js:26 createAnswer:InvalidStateError:PeerConnection无法创建 在非远程报价或本地pranswer的州应答 还有我的js(请原谅一团糟!):Javascript WebRTC 2路视频无法设置远程应答sdp:在错误状态下调用:kStable,javascript,webrtc,Javascript,Webrtc,嗨,我正试图建立一个视频聊天使用WebRTC与信号器的信号,它的基础上 错误是: setRemoteDescription:InvalidStateError:设置远程应答失败 sdp:在错误状态下调用:kStable onError@webrtc.js:26 pc.setRemoteDescription.error@webrtc.js:101 2webrtc.js:26 func LOCALDESCREATED:操作错误:无法设置本地应答sdp: 在错误状态下调用:kStable onErr
如果对方是报价人,请手动创建报价,而不是在onnegotiationneeded函数中创建报价,有时会调用onnegotiationneeded两次,从而导致您面临的错误。
// Generate random room name if needed
if (!location.hash) {
location.hash = Math.floor(Math.random() * 0xFFFFFF).toString(16);
}
const roomHash = location.hash.substring(1);
const roomName = 'test';
const configuration = {
iceServers: [
{
'urls': [
'stun:74.125.142.127:19302',
'stun:23.21.150.121:3478'
]
}
]
};
let room;
let pc;
function onSuccess() { };
function onError(context, error) {
console.error(`${context} : ${error}`);
};
const connection = new signalR.HubConnectionBuilder()
.withUrl("/video")
.build();
connection.on('Start', () => {
connection.invoke('JoinRoom', roomName).catch(error => onError("on invoke join room",error));
connection.invoke('GetMembers', roomName).catch(error => onError("on invoke GetMembers",error));
});
connection.on('members',
users => {
console.log('MEMBERS', users);
// If we are the second or greater user to connect to the room we will be creating the offer
users = JSON.parse(users);
const isOfferer = users.length === 2 ? true : false;
console.log("isOfferer", isOfferer);
console.log("users length = ", users.length);
startWebRTC(isOfferer);
});
// Send signaling data via signalr
function sendMessage(message) {
connection.invoke('send', message);
}
function startWebRTC(isOfferer) {
pc = new RTCPeerConnection(configuration);
// 'onicecandidate' notifies us whenever an ICE agent needs to deliver a
// message to the other peer through the signaling server
pc.onicecandidate = event => {
if (event.candidate) {
sendMessage(JSON.stringify({ 'candidate': event.candidate }));
console.log("send message - ", { 'candidate': event.candidate });
}
};
// If user is offerer let the 'negotiationneeded' event create the offer
if (isOfferer) {
pc.onnegotiationneeded = () => {
pc.createOffer().then(localDescCreated).catch(error => onError("onnegotiationneeded",error));
}
}
// When a remote stream arrives display it in the #remoteVideo element
pc.ontrack = event => {
const stream = event.streams[0];
if (!remoteVideo.srcObject || remoteVideo.srcObject.id !== stream.id) {
remoteVideo.srcObject = stream;
}
};
navigator.mediaDevices.getUserMedia({
audio: true,
video: true,
}).then(stream => {
// Display your local video in #localVideo element
localVideo.srcObject = stream;
// Add your stream to be sent to the conneting peer
stream.getTracks().forEach(track => pc.addTrack(track, stream));
}, error => onError("adding media devices", error));
// Listen to signaling data from Scaledrone
connection.on('newMessage', (message) => {
message = JSON.parse(message);
if (message.sdp) {
// This is called after receiving an offer or answer from another peer
pc.setRemoteDescription(new RTCSessionDescription(message.sdp), () => {
// When receiving an offer lets answer it
if (pc.remoteDescription.type === 'offer') {
pc.createAnswer().then(localDescCreated).catch(error => onError("createAnswer", error));
}
}, error => onError("setRemoteDescription", error));
} else if (message.candidate) {
// Add the new ICE candidate to our connections remote description
pc.addIceCandidate(
new RTCIceCandidate(message.candidate), onSuccess, error => onError("addIceCandidate", error)
);
}
});
}
function localDescCreated(desc) {
pc.setLocalDescription(
desc,
() => sendMessage(JSON.stringify({ 'sdp': pc.localDescription })),
error => onError("func localDescCreated", error)
);
}
connection.start().catch(err => console.error(err.toString()));