Host/Guest with signal filtering.

pull/25/head
Pontus Persson 2017-12-09 00:44:20 +01:00 committed by Pontus Alexander
parent dcbb8b816f
commit 06b662b4e6
4 changed files with 113 additions and 32 deletions

View File

@ -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>

View File

@ -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);

View File

@ -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) {

View File

@ -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() {