Browse Source

Always start by making a data channel.

feature/data-first
Daniel Perelman 1 year ago
parent
commit
a18ccfd393
1 changed files with 51 additions and 15 deletions
  1. +51
    -15
      camera/templates/index.html

+ 51
- 15
camera/templates/index.html View File

@@ -195,16 +195,29 @@ form label {

function sendJson(data) {
const toSend = JSON.stringify(data);
log("Sending message...");
const dcReady = dc && dc.readyState == "open";
const method = dcReady ? "dataConnection" : "webSocket";
log("Sending message via " + method + "...");
logPre(toSend);
webSocket.send(toSend);
(dcReady ? dc : webSocket).send(toSend);
}

var pc = undefined;
var dc = undefined;
function createRTCPeerConnection() {
const pc = new RTCPeerConnection();
log("Created RTCPeerConnection.");

pc.onsignalingstatechange = e => {
log("pc.onsignalingstatechange: " + pc.signalingState);
}
pc.oniceconnectionstatechange = e => {
log("pc.oniceconnectionstatechange: " + pc.iceConnectionState);
}
pc.onicegatheringstatechange = e => {
log("pc.onicegatheringstatechange: " + pc.iceGatheringState);
}

pc.onicecandidate = ({candidate}) => sendJson({candidate});

// let the "negotiationneeded" event trigger offer generation
@@ -232,11 +245,33 @@ form label {
}
};

pc.ondatachannel = e => {
dc = e.channel;
dc.onmessage = e => {
receiveMessage({source: "dataChannel", data: e.data});
}
log('Data channel initialized.');
}

if (isHost) {
dc = pc.createDataChannel('data');
dc.onmessage = e => {
receiveMessage({source: "dataChannel", data: e.data});
}
dc.onopen = e => {
log("Data channel open, sending settings...")
settings = readSettingsForm(true);
sendJson({settings});
startStartingWithErorrHandling(false);
}
}

return pc;
}

// get a local stream, show it in a self-view and add it to be sent
async function startStreaming(fromButton) {
log('In startStreaming(fromButton=' + fromButton + ')...');
const otherAudioSettings = isHost
? settings['client-audio']
: settings['host-audio'];
@@ -259,15 +294,6 @@ form label {
}
start.style.display = 'none';

if (isHost) {
sendJson({
settings: settings
});
}

if (pc !== undefined) return;
pc = createRTCPeerConnection();

const videoConstraints = videoSettings == 'none'
? false
: videoSettings == 'true'
@@ -311,16 +337,20 @@ form label {

async function receiveMessage(e) {
qrcode.style.display = 'none';
log("In webSocket.onmessage...");
log("In receiveMessage from " + e.source + "...");
logPre(e.data);
const data = JSON.parse(e.data);
if (data.requestSettings) {
if (data.ready) {
// Ready message means client is open and ready for connection.
pc = createRTCPeerConnection();
} else if (data.requestSettings) {
settings = readSettingsForm(true);
startStreamingWithErorrHandling(false);
} else if (data.settings) {
settings = data.settings;
startStreamingWithErorrHandling(false);
} else if (data.description) {
if (pc == undefined) pc = createRTCPeerConnection();
await pc.setRemoteDescription(data.description);
if (data.description.type == "offer") {
log("Got an offer...");
@@ -330,6 +360,7 @@ form label {
});
}
} else if (data.candidate) {
if (pc == undefined) pc = createRTCPeerConnection();
log("Adding ice candidate...");
await pc.addIceCandidate(data.candidate);
}
@@ -352,7 +383,9 @@ form label {
log('WebSocket error: ' + e);
};

webSocket.onmessage = receiveMessage;
webSocket.onmessage = e => {
receiveMessage({source: "webSocket", data: e.data});
}

return webSocket;
}
@@ -360,7 +393,10 @@ form label {
webSocket = createWebSocket();

if (!isHost) {
webSocket.onopen = _ => sendJson({requestSettings: true});
// To make serverless and server mode more similar,
// always make the first RTCPeerConnection offer from the host,
// so here just notify the host to start the process.
webSocket.onopen = _ => sendJson({ready: true});
}

log("Finished <script> block.");


Loading…
Cancel
Save