我用websocket和js写了一个语音通话。运行代码后出现错误,问题出现在客户报价阶段。 这是我的 client.js 代码:
'use strict';
var loginPage = document.querySelector('#loginPage');
var usernameInput = document.querySelector('#usernameInput');
var loginBtn = document.querySelector('#loginBtn');
var callPage = document.querySelector('#callPage');
var callToUsernameInput = document.querySelector('#callToUsernameInput');
var callBtn = $('#callBtn');
var answerBtn = $('#answerBtn');
var hangUpBtn = $('#hangUpBtn');
var localAudio = document.querySelector('#localAudio');
var remoteAudio = document.querySelector('#remoteAudio');
let pc;
let sendTo = callBtn.val();
let localStream;
const mediaConst = {
audio:true
};
const options = {
offerToReceiveAudio : 1,
}
function getConn(){
if (!pc){
pc = new RTCPeerConnection();
}
}
async function getCam(){
let mediaStram;
try{
if (!pc){
await getConn();
}
mediaStram = await navigator.mediaDevices.getUserMedia(mediaConst);
localAudio.srcObject = mediaStram;
localStream = mediaStram;
localStream.getTracks().forEach(track => pc.addTrack(track,localStream));
}catch (error){
console.log(error);
}
}
async function createOffer(sendTo){
await sendIceCandidate(sendTo);
await pc.createOffer(options);
await pc.setLocalDescription(pc.localDescription);
send('client-offer',pc.localDescription,sendTo);
}
async function createAnswer(sendTO , data){
if (!pc){
await getConn();
}
if (!localStream){
await getCam();
}
await sendIceCandidate(sendTo);
await pc.setRemoteDescription(data);
await pc.createAnswer();
await pc.setLocalDescription(pc.localDescription);
send('client-answer',pc.localDescription,sendTo);
}
function sendIceCandidate(sendTo){
pc.onicecandidate = e =>{
if (e.candidate !== null){
send('client-candidate' , e.candidate, sendTo);
}
}
pc.ontrack = e =>{
remoteAudio.srcObject = e.streams[0];
}
}
$('#callBtn').on('click' , () =>{
getCam();
send('is-client-ready',null,sendTo);
})
conn.onopen = e =>{
console.log('connected to socket');
}
conn.onmessage = async function(e){
let message = JSON.parse(e.data);
let by = message.by;
let data = message.data;
let type = message.type;
switch (type){
case 'client-candidate':
if (pc.localDescription){
await pc.addIceCandidate(new RTCIceCandidate(data));
}
break;
case 'is-client-ready':
if (!pc){
await getConn();
}
if (pc.iceConnectionState === "connected"){
send('client-already-oncall');
}else{
/*hangUpBtn.on('click', () =>{
send('leave' , null , sendTo);
location.reload(true);
})*/
answerBtn.on('click' , ()=>{
send('client-is-ready',null,sendTo)
})
}
break;
case 'client-answer':
if(pc.localDescription){
await pc.setRemoteDescription(data);
}
break;
case 'client-offer':
createAnswer(sendTo,data);
break;
case 'client-is-ready':
createOffer(sendTo);
break;
case 'client-already-oncall':
setTimeout('window.location.reload(true)',2000);
break;
case 'client-rejected':
alert("client-reject-the-call");
break;
}
}
function send(type,data , sendTo){
conn.send(JSON.stringify({
sendTo:sendTo,
type:type,
data:data
}));
}
这是错误: 未捕获(承诺中)DOMException:无法在“RTCPeerConnection”上执行“setRemoteDescription”:无法设置远程应答 sdp:在错误状态下调用:稳定 client.js 第 139 行
我试过这个:
async function createAnswer(sendTo, data) {
if (!pc) {
await getConn();
}
if (!localStream) {
await getCam();
}
try {
await pc.setRemoteDescription(new RTCSessionDescription(data));
const answer = await pc.createAnswer();
await pc.setLocalDescription(answer);
send('client-answer', pc.localDescription, sendTo);
} catch (error) {
console.error('Error creating answer:', error);
}
}
这里的问题可能是你的 pc 变量是全局变量