mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-18 00:55:40 +00:00
Reformat webrtc.js
This commit is contained in:
parent
d42ad68ef3
commit
00b52dde8d
1 changed files with 94 additions and 73 deletions
|
|
@ -4,14 +4,14 @@ import {
|
|||
WEBRTC_CONNECTION_READY,
|
||||
WEBRTC_ICE_CANDIDATE_FOUND,
|
||||
WEBRTC_ICE_CANDIDATES_FLUSH,
|
||||
WEBRTC_SDP_ANSWER
|
||||
} from 'event';
|
||||
import {log} from 'log';
|
||||
WEBRTC_SDP_ANSWER,
|
||||
} from "event";
|
||||
import { log } from "log";
|
||||
|
||||
let connection;
|
||||
let dataChannel
|
||||
let keyboardChannel
|
||||
let mouseChannel
|
||||
let dataChannel;
|
||||
let keyboardChannel;
|
||||
let mouseChannel;
|
||||
let mediaStream;
|
||||
let candidates = [];
|
||||
let isAnswered = false;
|
||||
|
|
@ -27,60 +27,75 @@ const ice = (() => {
|
|||
let timeForIceGathering;
|
||||
|
||||
return {
|
||||
onIceCandidate: data => {
|
||||
onIceCandidate: (data) => {
|
||||
if (!data.candidate) return;
|
||||
log.debug(`[rtc] [ice] local: ${data.candidate?.candidate}`);
|
||||
pub(WEBRTC_ICE_CANDIDATE_FOUND, {candidate: data.candidate})
|
||||
pub(WEBRTC_ICE_CANDIDATE_FOUND, { candidate: data.candidate });
|
||||
},
|
||||
onIceCandidateError: event => {
|
||||
let {address, errorCode, errorText, url} = event;
|
||||
onIceCandidateError: (event) => {
|
||||
let { address, errorCode, errorText, url } = event;
|
||||
|
||||
if (errorCode === 701) {
|
||||
errorText = 'couldn\'t reach the server'
|
||||
errorText = "couldn't reach the server";
|
||||
}
|
||||
|
||||
log.debug(`[rtc] [ice] candidate error: ${address || ''} ${errorCode}: ${errorText} / ${url}`)
|
||||
log.debug(
|
||||
`[rtc] [ice] candidate error: ${address || ""} ${errorCode}: ${errorText} / ${url}`,
|
||||
);
|
||||
},
|
||||
onIceStateChange: event => {
|
||||
onIceStateChange: (event) => {
|
||||
const t = event.target;
|
||||
log.debug(`[rtc] [ice] state: ${t.iceGatheringState}`)
|
||||
log.debug(`[rtc] [ice] state: ${t.iceGatheringState}`);
|
||||
|
||||
switch (event.target.iceGatheringState) {
|
||||
case 'gathering':
|
||||
case "gathering":
|
||||
timeForIceGathering = setTimeout(() => {
|
||||
log.warn(`[rtc] ice gathering was aborted due to timeout ${ICE_TIMEOUT}ms`);
|
||||
log.warn(
|
||||
`[rtc] ice gathering was aborted due to timeout ${ICE_TIMEOUT}ms`,
|
||||
);
|
||||
// sendCandidates();
|
||||
}, ICE_TIMEOUT);
|
||||
break;
|
||||
case 'complete':
|
||||
case "complete":
|
||||
if (timeForIceGathering) {
|
||||
clearTimeout(timeForIceGathering);
|
||||
}
|
||||
}
|
||||
},
|
||||
onIceConnectionStateChange: () => {
|
||||
log.debug(`[rtc] [ice] connection state: ${connection.iceConnectionState}`);
|
||||
log.debug(
|
||||
`[rtc] [ice] connection state: ${connection.iceConnectionState}`,
|
||||
);
|
||||
switch (connection.iceConnectionState) {
|
||||
case 'connected':
|
||||
case "connected":
|
||||
connected = true;
|
||||
break;
|
||||
case 'disconnected':
|
||||
log.info(`[rtc] [ice] disconnected... ` +
|
||||
`connection: ${connection.connectionState}, ice: ${connection.iceConnectionState}, ` +
|
||||
`gathering: ${connection.iceGatheringState}, signalling: ${connection.signalingState}`)
|
||||
case "disconnected":
|
||||
log.info(
|
||||
`[rtc] [ice] disconnected... ` +
|
||||
`connection: ${connection.connectionState}, ice: ${connection.iceConnectionState}, ` +
|
||||
`gathering: ${connection.iceGatheringState}, signalling: ${connection.signalingState}`,
|
||||
);
|
||||
connected = false;
|
||||
pub(WEBRTC_CONNECTION_CLOSED);
|
||||
break;
|
||||
case 'failed':
|
||||
log.error('[rtc] [ice] failed establish connection, retry...');
|
||||
case "failed":
|
||||
log.error(
|
||||
"[rtc] [ice] failed establish connection, retry...",
|
||||
);
|
||||
connected = false;
|
||||
connection.createOffer({iceRestart: true})
|
||||
.then(description => connection.setLocalDescription(description).catch(log.error))
|
||||
connection
|
||||
.createOffer({ iceRestart: true })
|
||||
.then((description) =>
|
||||
connection
|
||||
.setLocalDescription(description)
|
||||
.catch(log.error),
|
||||
)
|
||||
.catch(log.error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
|
|
@ -88,80 +103,84 @@ const ice = (() => {
|
|||
*/
|
||||
export const webrtc = {
|
||||
start: (iceServers = []) => {
|
||||
log.debug('[rtc] got remote ICE servers', iceServers);
|
||||
connection = new RTCPeerConnection({iceServers: iceServers});
|
||||
log.debug("[rtc] got remote ICE servers", iceServers);
|
||||
connection = new RTCPeerConnection({ iceServers: iceServers });
|
||||
mediaStream = new MediaStream();
|
||||
|
||||
connection.ondatachannel = e => {
|
||||
log.debug(`[rtc] [data-ch] push: ${e.channel.label}`)
|
||||
connection.ondatachannel = (e) => {
|
||||
log.debug(`[rtc] [data-ch] push: ${e.channel.label}`);
|
||||
e.channel.binaryType = "arraybuffer";
|
||||
|
||||
if (e.channel.label === 'keyboard') {
|
||||
keyboardChannel = e.channel
|
||||
return
|
||||
if (e.channel.label === "keyboard") {
|
||||
keyboardChannel = e.channel;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.channel.label === 'mouse') {
|
||||
mouseChannel = e.channel
|
||||
return
|
||||
if (e.channel.label === "mouse") {
|
||||
mouseChannel = e.channel;
|
||||
return;
|
||||
}
|
||||
|
||||
dataChannel = e.channel;
|
||||
dataChannel.onopen = () => {
|
||||
log.debug('[rtc] [data-ch] input channel has been opened');
|
||||
log.debug("[rtc] [data-ch] input channel has been opened");
|
||||
inputReady = true;
|
||||
pub(WEBRTC_CONNECTION_READY)
|
||||
pub(WEBRTC_CONNECTION_READY);
|
||||
};
|
||||
if (onData) {
|
||||
dataChannel.onmessage = onData;
|
||||
}
|
||||
dataChannel.onclose = () => {
|
||||
inputReady = false
|
||||
log.debug('[rtc] [data-ch] input channel has been closed')
|
||||
}
|
||||
}
|
||||
inputReady = false;
|
||||
log.debug("[rtc] [data-ch] input channel has been closed");
|
||||
};
|
||||
};
|
||||
connection.oniceconnectionstatechange = ice.onIceConnectionStateChange;
|
||||
connection.onicegatheringstatechange = ice.onIceStateChange;
|
||||
connection.onicecandidate = ice.onIceCandidate;
|
||||
connection.onicecandidateerror = ice.onIceCandidateError;
|
||||
connection.onconnectionstatechange = _ => {
|
||||
console.debug(`[rtc] connection state: ${connection.connectionState}`)
|
||||
}
|
||||
connection.ontrack = event => {
|
||||
connection.onconnectionstatechange = (_) => {
|
||||
console.debug(
|
||||
`[rtc] connection state: ${connection.connectionState}`,
|
||||
);
|
||||
};
|
||||
connection.ontrack = (event) => {
|
||||
mediaStream.addTrack(event.track);
|
||||
}
|
||||
};
|
||||
},
|
||||
setRemoteDescription: async (sdp, media) => {
|
||||
log.debug('[rtc] [sdp] remote offer', sdp)
|
||||
log.debug("[rtc] [sdp] remote offer", sdp);
|
||||
|
||||
try {
|
||||
const offer = new RTCSessionDescription(sdp);
|
||||
await connection.setRemoteDescription(offer);
|
||||
} catch (e) {
|
||||
log.error(`[rtc] [sdp] remote offer error: ${e}`)
|
||||
log.error(`[rtc] [sdp] remote offer error: ${e}`);
|
||||
}
|
||||
|
||||
log.debug(`[rtc] [sdp] remote Trickle ICE support: ${connection.canTrickleIceCandidates}`)
|
||||
log.debug(
|
||||
`[rtc] [sdp] remote Trickle ICE support: ${connection.canTrickleIceCandidates}`,
|
||||
);
|
||||
|
||||
try {
|
||||
const answer = await connection.createAnswer();
|
||||
// Chrome bug https://bugs.chromium.org/p/chromium/issues/detail?id=818180 workaround
|
||||
// force stereo params for Opus tracks (a=fmtp:111 ...)
|
||||
answer.sdp = answer.sdp.replace(/(a=fmtp:111 .*)/g, '$1;stereo=1');
|
||||
answer.sdp = answer.sdp.replace(/(a=fmtp:111 .*)/g, "$1;stereo=1");
|
||||
await connection.setLocalDescription(answer);
|
||||
log.debug("[rtc] [sdp] local answer", answer)
|
||||
log.debug("[rtc] [sdp] local answer", answer);
|
||||
|
||||
isAnswered = true;
|
||||
pub(WEBRTC_ICE_CANDIDATES_FLUSH);
|
||||
pub(WEBRTC_SDP_ANSWER, {sdp: answer});
|
||||
pub(WEBRTC_SDP_ANSWER, { sdp: answer });
|
||||
} catch (e) {
|
||||
log.error(`[rtc] [sdp] local answer error: ${e}`)
|
||||
log.error(`[rtc] [sdp] local answer error: ${e}`);
|
||||
}
|
||||
|
||||
media.srcObject = mediaStream;
|
||||
},
|
||||
addCandidate: (data) => {
|
||||
if (data === '') {
|
||||
if (data === "") {
|
||||
pub(WEBRTC_ICE_CANDIDATES_FLUSH);
|
||||
} else {
|
||||
candidates.push(data);
|
||||
|
|
@ -171,12 +190,14 @@ export const webrtc = {
|
|||
if (isFlushing || !isAnswered) return;
|
||||
isFlushing = true;
|
||||
if (log.level >= log.DEBUG) {
|
||||
log.debug(`[rtc] [ice] set local candidates (${candidates.length}): ${candidates.map(c => c.candidate)}`)
|
||||
log.debug(
|
||||
`[rtc] [ice] set local candidates (${candidates.length}): ${candidates.map((c) => c.candidate)}`,
|
||||
);
|
||||
}
|
||||
let data = undefined;
|
||||
while (typeof (data = candidates.shift()) !== "undefined") {
|
||||
connection.addIceCandidate(new RTCIceCandidate(data)).catch(e => {
|
||||
log.error('[rtc] candidate add failed', e.name);
|
||||
connection.addIceCandidate(new RTCIceCandidate(data)).catch((e) => {
|
||||
log.error("[rtc] candidate add failed", e.name);
|
||||
});
|
||||
}
|
||||
isFlushing = false;
|
||||
|
|
@ -188,11 +209,11 @@ export const webrtc = {
|
|||
isInputReady: () => inputReady,
|
||||
stats: async () => {
|
||||
if (!connected) return Promise.resolve();
|
||||
return await connection.getStats()
|
||||
return await connection.getStats();
|
||||
},
|
||||
stop: () => {
|
||||
if (mediaStream) {
|
||||
mediaStream.getTracks().forEach(t => {
|
||||
mediaStream.getTracks().forEach((t) => {
|
||||
t.stop();
|
||||
mediaStream.removeTrack(t);
|
||||
});
|
||||
|
|
@ -203,21 +224,21 @@ export const webrtc = {
|
|||
connection = null;
|
||||
}
|
||||
if (dataChannel) {
|
||||
dataChannel.close()
|
||||
dataChannel = null
|
||||
dataChannel.close();
|
||||
dataChannel = null;
|
||||
}
|
||||
if (keyboardChannel) {
|
||||
keyboardChannel?.close()
|
||||
keyboardChannel = null
|
||||
keyboardChannel?.close();
|
||||
keyboardChannel = null;
|
||||
}
|
||||
if (mouseChannel) {
|
||||
mouseChannel?.close()
|
||||
mouseChannel = null
|
||||
mouseChannel?.close();
|
||||
mouseChannel = null;
|
||||
}
|
||||
candidates = [];
|
||||
log.info('[rtc] WebRTC has been closed');
|
||||
log.info("[rtc] WebRTC has been closed");
|
||||
},
|
||||
set onData(fn) {
|
||||
onData = fn
|
||||
}
|
||||
}
|
||||
onData = fn;
|
||||
},
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue