2 回答

TA貢獻(xiàn)1765條經(jīng)驗(yàn) 獲得超5個(gè)贊
在兩個(gè)瀏覽器窗口中打開它,然后點(diǎn)擊其中一個(gè)窗口中的按鈕。這是代碼:Connect
const pc = new RTCPeerConnection();
call.onclick = async () => {
const stream = await navigator.mediaDevices.getUserMedia({video:true,audio:true})
video.srcObject = stream;
for (const track of stream.getTracks()) {
pc.addTrack(track, stream);
}
};
pc.ontrack = ({streams}) => video.srcObject = streams[0];
pc.oniceconnectionstatechange = () => console.log(pc.iceConnectionState);
pc.onicecandidate = ({candidate}) => sc.send({candidate});
pc.onnegotiationneeded = async () => {
await pc.setLocalDescription(await pc.createOffer());
sc.send({sdp: pc.localDescription});
}
const sc = new localSocket(); // localStorage signaling hack
sc.onmessage = async ({data: {sdp, candidate}}) => {
if (sdp) {
await pc.setRemoteDescription(sdp);
if (sdp.type == "offer") {
await pc.setLocalDescription(await pc.createAnswer());
sc.send({sdp: pc.localDescription});
}
} else if (candidate) await pc.addIceCandidate(candidate);
}
這是A和B的相同來源,用您喜歡的信令通道(例如websocket)替換黑客攻擊。localSocket
不要緩存ICE候選者,因?yàn)檫@違背了涓流ICE的目的。它可能在本地看起來很快,但在實(shí)際網(wǎng)絡(luò)中ICE可能需要時(shí)間。
事實(shí)上,如果您延遲發(fā)送報(bào)價(jià)/答案,直到收集了所有本地候選人,則發(fā)送候選人是沒有意義的,因?yàn)楹蜻x人已經(jīng)嵌入到提議/答案()中。pc.localDescription

TA貢獻(xiàn)1876條經(jīng)驗(yàn) 獲得超7個(gè)贊
最后!幾周后,我已經(jīng)弄清楚了這個(gè)問題,這個(gè)問題在我的問題中包含的代碼中并不明顯,但對(duì)于遇到類似問題的人來說,它可能仍然有用。
我以為在活動(dòng)結(jié)束后,冰上收集正在完成,并且提供了報(bào)價(jià)/答案。onnegotiationneeded
由于這個(gè)不正確的假設(shè),我在這個(gè)階段與冰候選人一起發(fā)出報(bào)價(jià)/答案的信號(hào),但是非常頻繁地(根據(jù)我的經(jīng)驗(yàn),總是在iOS Safari中)此時(shí)尚未創(chuàng)建報(bào)價(jià)/答案。
我通過創(chuàng)建兩個(gè)承諾來解決這個(gè)問題:a)完成冰候選收集,以及b)創(chuàng)建報(bào)價(jià)/答案。我使用了兩個(gè)承諾,當(dāng)它們都完成時(shí),我通過信令服務(wù)器同時(shí)發(fā)送了冰候選者和提供/答案。Promise.all
這是可行的,但是當(dāng)然在未來,我應(yīng)該通過發(fā)送零碎的東西來“涓涓細(xì)流”這些信息,而不是等待一切完全完成。但是我將來會(huì)擔(dān)心這一點(diǎn),因?yàn)槟壳拔艺谑褂肏TTP請(qǐng)求,而且這太麻煩了。
編輯:我的連接仍然總是卡住,所以我創(chuàng)建了一個(gè)新問題。但是,如果沒有本地連接,則現(xiàn)在100%完全可靠:)iceServers
iceServers
添加回答
舉報(bào)