gpt4 book ai didi

javascript - 无法在 'RTCPeerConnection 上执行 'setLocalDescription'

转载 作者:行者123 更新时间:2023-11-30 14:17:20 24 4
gpt4 key购买 nike

这个错误已经有一段时间了

enter image description here

一直在尝试使用 async 来等待本地描述的更新,但由于我的代码现在的工作方式,它无法集成它,而且我听说 socket.on 本身已经执行了 async。

我也尝试过在 vs code 中使用断点来调试运行不佳的代码。

如果有人知道解决此问题的方法,将不胜感激。代码附在下面

'use strict';

var localStream;
var remoteStream;
var isInitiator;
var configuration = {
iceServers: [
{
urls: 'stun:stun.l.google.com:19302'
}
]
};
var pc = new RTCPeerConnection(configuration);

// Define action buttons.
const callButton = document.getElementById('callButton');
const hangupButton = document.getElementById('hangupButton');

/////////////////////////////////////////////

window.room = prompt('Enter room name:');

var socket = io.connect();

if (room !== '') {
console.log('Message from client: Asking to join room ' + room);
socket.emit('create or join', room);
}

socket.on('created', function(room) {
console.log('Created room ' + room);
isInitiator = true;
startVideo();
});

socket.on('joined', function(room) {
console.log('joined: ' + room);
startVideo();
});

socket.on('log', function(array) {
console.log.apply(console, array);
});

////////////////////////////////////////////////

function sendMessage(message) {
socket.emit('message', message);
}

// This client receives a message
socket.on('message', function(message) {
try {
if (message.type === 'offer') {
pc.setRemoteDescription(new RTCSessionDescription(message));
// const stream = navigator.mediaDevices.getUserMedia({
// audio: true,
// video: true
// });
// stream.getTracks().forEach(track => pc.addTrack(track, localStream));
pc.setLocalDescription(
pc.createAnswer(setLocalAndSendMessage, function(err) {
console
.log(err.name + ': ' + err.message)
.then(pc.setLocalDescription);
})
);
} else if (message.type === 'answer') {
console.log('This is to check if answer was returned');
pc.setRemoteDescription(new RTCSessionDescription(message));
} else if (message.type === 'candidate') {
pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
});

////////////////////////////////////////////////////

const localVideo = document.querySelector('#localVideo');
const remoteVideo = document.querySelector('#remoteVideo');

// Set up initial action buttons status: disable call and hangup.
callButton.disabled = true;
hangupButton.disabled = true;

// Add click event handlers for buttons.
callButton.addEventListener('click', callStart);
hangupButton.addEventListener('click', hangupCall);

function startVideo() {
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true
})
.then(function(mediaStream) {
localStream = mediaStream;
localVideo.srcObject = mediaStream;
})
.catch(function(err) {
console.log('getUserMedia() error: ' + err.name);
});
callButton.disabled = false;
}

function callStart() {
createPeerConnection();
//pc.addTrack(mediaStream);
//stream.getTracks().forEach(track => pc.addTrack(track, localStream));
callButton.disabled = true;
hangupButton.disabled = false;
if (isInitiator) {
console.log('Sending offer to peer');
pc.createOffer(setLocalAndSendMessage, function(err) {
console.log(err.name + ': ' + err.message).then(pc.setLocalDescription);
});
}
}

/////////////////////////////////////////////////////////

function createPeerConnection() {
try {
pc = new RTCPeerConnection(null);
pc.onicecandidate = ({ candidate }) => sendMessage({ candidate });
pc.ontrack = event => {
if (remoteVideo.srcObject) return;
remoteVideo.srcObject = event.streams[0];
};
console.log('Created RTCPeerConnnection');
} catch (e) {
console.log('Failed to create PeerConnection, exception: ' + e.message);
alert('Cannot create RTCPeerConnection object.');
return;
}
}

function setLocalAndSendMessage(sessionDescription) {
console.log('setLocalAndSendMessage sending message', sessionDescription);
pc.setLocalDescription(sessionDescription);
sendMessage(sessionDescription);
}

function hangupCall() {
pc.close();
pc = null;
}

最佳答案

理解异步代码没有解决方法。您正在此处剪切和粘贴。

如果您不打算使用 async/await ,那么你需要应对 JavaScript 是单线程的,并且永远不会阻塞等待异步操作完成,所以你永远不能直接使用异步方法的返回值,就像你试图在这里做:

createAnswer 是一个异步方法,返回一个 promise ,不是答案,所以这是错误的:

  pc.setLocalDescription(                                    // <-- wrong
pc.createAnswer(setLocalAndSendMessage, function(err) { //
console
.log(err.name + ': ' + err.message)
.then(pc.setLocalDescription);
})
);

您正在调用 setLocalDescription(promise),这会给出您提到的错误,因为 promise 不是有效的描述。相反,a promise is an object you attach callbacks to :

const promise = pc.createAnswer();
promise.then(setLocalAndSendMessage, function(err) {
console.log(err.name + ': ' + err.message);
});

或者简单地说:

pc.createAnswer()
.then(setLocalAndSendMessage, function(err) {
console.log(err.name + ': ' + err.message);
});

我们甚至可以连续使用then 来组成promise chain :

pc.createAnswer()
.then(function(answer) {
return pc.setLocalDescription(answer);
})
.then(function() {
sendMessage(pc.localDescription);
})
.catch(function(err) {
console.log(err.name + ': ' + err.message);
});

此外,我不应该告诉你 console.log() 不返回 promise !

遗憾的是,您正在复制 really old code在这里,RTCPeerConnection 有一些遗留的 API 并且做了一些技巧,有时让调用者在没有真正的 promise 链或检查错误的情况下调用这些协商方法。但这不可避免地会带来麻烦。

关于javascript - 无法在 'RTCPeerConnection 上执行 'setLocalDescription',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53359703/

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