Host/Guest with signal filtering.
parent
dcbb8b816f
commit
06b662b4e6
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<button id="start">Start Video</button>
|
<button id="host">Host</button>
|
||||||
|
<button id="connect">Connect</button>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,10 @@
|
||||||
import { createUUID } from './random.js';
|
|
||||||
|
|
||||||
export async function createPeerExchange(address) {
|
export async function createPeerExchange(address) {
|
||||||
const uuid = createUUID();
|
|
||||||
|
|
||||||
const server = new WebSocket(address);
|
const server = new WebSocket(address);
|
||||||
const listeners = new Set();
|
const listeners = new Set();
|
||||||
|
|
||||||
function onMessage(message) {
|
function onMessage(message) {
|
||||||
const data = JSON.parse(message.data);
|
const data = JSON.parse(message.data);
|
||||||
|
listeners.forEach(callback => callback(data));
|
||||||
if (data.uuid === uuid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
listeners.forEach(callback => callback(data, send));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function listen(callback) {
|
function listen(callback) {
|
||||||
|
|
@ -21,7 +12,7 @@ export async function createPeerExchange(address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function send(data) {
|
function send(data) {
|
||||||
server.send(JSON.stringify(Object.assign({uuid}, data)));
|
server.send(JSON.stringify(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
server.addEventListener('message', onMessage);
|
server.addEventListener('message', onMessage);
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,46 @@
|
||||||
|
import { createUUID } from './random.js';
|
||||||
|
|
||||||
function errorHandler(error) {
|
function errorHandler(error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filter(uuid) {
|
||||||
|
return function filterSignal(callback) {
|
||||||
|
return function(signal) {
|
||||||
|
if (signal.uuid === uuid) {
|
||||||
|
console.log(`${uuid} ours, filtering`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callback(signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function createHost(peerExchange, peerConnectionConfig) {
|
export function createHost(peerExchange, peerConnectionConfig) {
|
||||||
const listeners = new Set();
|
const listeners = new Set();
|
||||||
|
|
||||||
function onConnection(callback) {
|
function onConnection(callback) {
|
||||||
listeners.push(callback);
|
listeners.add(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
function emitConnection(conn) {
|
function emitConnection(conn) {
|
||||||
listeners.forEach(callback => callback(conn));
|
listeners.forEach(callback => callback(conn));
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleSDP(sdp) {
|
peerExchange.listen(async signal => {
|
||||||
host.setRemoteDescription(new RTCSessionDescription(signal.sdp));
|
console.log("Host signal", signal);
|
||||||
}
|
|
||||||
|
|
||||||
peerExchange.listen(async (signal, send) => {
|
|
||||||
if (signal.sdp && signal.sdp.type === "offer") {
|
if (signal.sdp && signal.sdp.type === "offer") {
|
||||||
const host = createConn(peerExchange, peerConnectionConfig);
|
const {conn, send} = createConn(peerExchange, peerConnectionConfig);
|
||||||
|
|
||||||
const remoteDesc = new RTCSessionDescription(signal.sdp);
|
const remoteDesc = new RTCSessionDescription(signal.sdp);
|
||||||
await host.setRemoteDescription(remoteDesc);
|
await conn.setRemoteDescription(remoteDesc);
|
||||||
|
|
||||||
const localDesc = await conn.createAnswer();
|
const localDesc = await conn.createAnswer();
|
||||||
await host.setLocalDescription(localDesc);
|
await conn.setLocalDescription(localDesc);
|
||||||
|
|
||||||
send({'sdp': desc});
|
send({sdp: localDesc});
|
||||||
|
|
||||||
|
emitConnection(conn);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -36,22 +49,69 @@ export function createHost(peerExchange, peerConnectionConfig) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createConn(peerExchange, peerConnectionConfig) {
|
export function createGuest(peerExchange, peerConnectionConfig) {
|
||||||
const conn = new RTCPeerConnection(peerConnectionConfig);
|
const {conn, onSignal, send} = createConn(peerExchange, peerConnectionConfig);
|
||||||
|
|
||||||
conn.addEventListener('icecandidate', event => {
|
onSignal(async signal => {
|
||||||
if(event.candidate != null) {
|
console.log("Guest signal", signal);
|
||||||
peerExchange.send({ice: event.candidate});
|
if (signal.sdp && signal.sdp.type === "answer") {
|
||||||
|
const remoteDesc = new RTCSessionDescription(signal.sdp);
|
||||||
|
await conn.setRemoteDescription(remoteDesc);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function connect() {
|
||||||
|
const localDesc = await conn.createOffer();
|
||||||
|
await conn.setLocalDescription(localDesc);
|
||||||
|
send({sdp: localDesc});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
conn,
|
||||||
|
connect,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function createConn(peerExchange, peerConnectionConfig) {
|
||||||
|
const conn = new RTCPeerConnection(peerConnectionConfig);
|
||||||
|
const uuid = createUUID();
|
||||||
|
|
||||||
|
conn.addEventListener('icecandidate', event => {
|
||||||
|
if(event.candidate != null) {
|
||||||
|
send({ice: event.candidate});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const listeners = new Set();
|
||||||
|
|
||||||
|
function onSignal(callback) {
|
||||||
|
listeners.add(callback);
|
||||||
|
}
|
||||||
|
|
||||||
peerExchange.listen(signal => {
|
peerExchange.listen(signal => {
|
||||||
|
if (signal.uuid === uuid) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
listeners.forEach(callback => callback(signal));
|
||||||
|
});
|
||||||
|
|
||||||
|
onSignal(signal => {
|
||||||
if(signal.ice) {
|
if(signal.ice) {
|
||||||
conn.addIceCandidate(new RTCIceCandidate(signal.ice)).catch(errorHandler);
|
conn.addIceCandidate(new RTCIceCandidate(signal.ice)).catch(errorHandler);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return conn;
|
function send(data) {
|
||||||
|
peerExchange.send(Object.assign({}, data, {uuid}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
conn,
|
||||||
|
onSignal,
|
||||||
|
send,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createPeer(peerExchange, peerConnectionConfig) {
|
export function createPeer(peerExchange, peerConnectionConfig) {
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,46 @@
|
||||||
import { dataChannelConfig, peerConnectionConfig } from './config.js';
|
import { dataChannelConfig, peerConnectionConfig } from './config.js';
|
||||||
import { createPeerExchange } from './peer-exchange.js';
|
import { createPeerExchange } from './peer-exchange.js';
|
||||||
import { createPeer } from './peer.js';
|
import { createPeer, createHost, createGuest} from './peer.js';
|
||||||
|
|
||||||
var peerConnection;
|
var peerConnection;
|
||||||
var serverConnection;
|
var serverConnection;
|
||||||
|
|
||||||
async function pageReady() {
|
async function pageReady() {
|
||||||
document.querySelector("button#start")
|
document.querySelector("button#host")
|
||||||
.addEventListener("click", extendOffer);
|
.addEventListener("click", host);
|
||||||
|
|
||||||
|
document.querySelector("button#connect")
|
||||||
|
.addEventListener("click", connect);
|
||||||
|
|
||||||
serverConnection = await createPeerExchange('wss://' + window.location.hostname + ':8443');
|
serverConnection = await createPeerExchange('wss://' + window.location.hostname + ':8443');
|
||||||
|
}
|
||||||
|
|
||||||
setup();
|
function host() {
|
||||||
|
const host = createHost(serverConnection, peerConnectionConfig);
|
||||||
|
host.onConnection(conn => {
|
||||||
|
console.log("Host Received Connection", conn);
|
||||||
|
|
||||||
|
conn.addEventListener('addstream', stream => {
|
||||||
|
console.log("Host received stream", stream);
|
||||||
|
document.getElementById('remoteVideo').srcObject = event.stream;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
console.log("Host waiting for connections");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function connect() {
|
||||||
|
var constraints = {
|
||||||
|
video: true,
|
||||||
|
audio: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
||||||
|
|
||||||
|
const guest = createGuest(serverConnection, peerConnectionConfig);
|
||||||
|
guest.conn.addStream(stream);
|
||||||
|
|
||||||
|
console.log("Connecting");
|
||||||
|
guest.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setup() {
|
async function setup() {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue