|
|
@@ -3,10 +3,8 @@ const datachannels = {} |
|
|
|
const streams = {} |
|
|
|
const screen = {} |
|
|
|
|
|
|
|
function setTracks({source, tracks}) { |
|
|
|
streams[source] = streams[source] || new MediaStream() |
|
|
|
streams[source].getTracks().forEach(t => streams[source].removeTrack(t)) |
|
|
|
tracks.forEach(track => streams[source].addTrack(track)) |
|
|
|
function setStream({source, stream}) { |
|
|
|
streams[source] = stream |
|
|
|
m.redraw() |
|
|
|
|
|
|
|
if(source === State.username) { |
|
|
@@ -16,19 +14,14 @@ function setTracks({source, tracks}) { |
|
|
|
|
|
|
|
function reloadAllStreams() { |
|
|
|
State.online.forEach(username => { |
|
|
|
const rpc = connections[username] |
|
|
|
if(rpc) { |
|
|
|
rpc.getSenders().map(s => rpc.removeTrack(s)) |
|
|
|
} |
|
|
|
signal({kind: 'rpc', value: {type: 'request'}, source: username}) |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
function getOwnTracks() { |
|
|
|
if(streams[State.username]) { |
|
|
|
return streams[State.username].getTracks() |
|
|
|
} |
|
|
|
else { |
|
|
|
return [] |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function createConnection(target) { |
|
|
|
const rpc = new RTCPeerConnection(rpcConfig) |
|
|
|
|
|
|
@@ -38,9 +31,8 @@ function createConnection(target) { |
|
|
|
wire({kind: 'rpc', value, target}) |
|
|
|
} |
|
|
|
} |
|
|
|
rpc.ontrack = () => { |
|
|
|
const tracks = rpc.getReceivers().map(t => t.track) |
|
|
|
setTracks({source: target, tracks: tracks}) |
|
|
|
rpc.ontrack = ({streams: [stream]}) => { |
|
|
|
setStream({source: target, stream}) |
|
|
|
} |
|
|
|
rpc.onconnectionstatechange = () => { |
|
|
|
if(rpc.connectionState === 'failed') { |
|
|
@@ -73,10 +65,13 @@ async function handlePeerInfo({source: target, value}) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
const olds = rpc.getSenders().map(t => t.track) |
|
|
|
const news = getOwnTracks() |
|
|
|
rpc.getSenders().filter(s => !news.includes(s.track)).forEach(s => rpc.removeTrack(s)) |
|
|
|
news.filter(track => !olds.includes(track)).forEach(t => t && rpc.addTrack(t)) |
|
|
|
const stream = streams[State.username] |
|
|
|
if(stream) { |
|
|
|
stream.getTracks().forEach(track => { |
|
|
|
try {rpc.addTrack(track, stream) } |
|
|
|
catch { } |
|
|
|
}) |
|
|
|
} |
|
|
|
|
|
|
|
if(value.type === 'request') { |
|
|
|
const localOffer = await rpc.createOffer() |
|
|
@@ -116,8 +111,17 @@ function destroyConnection(username) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
addEventListener('tracks', (e) => setTracks(e.detail.value)) |
|
|
|
function destroyAll() { |
|
|
|
const people = new Set() |
|
|
|
const collect = [connections, datachannels, streams, screen] |
|
|
|
.map(collection => Object.keys(collection)) |
|
|
|
.forEach(keys => keys.forEach(key => people.add(key))) |
|
|
|
people.forEach(destroyConnection) |
|
|
|
} |
|
|
|
|
|
|
|
addEventListener('stream', (e) => setStream(e.detail.value)) |
|
|
|
addEventListener('rpc', (e) => handlePeerInfo(e.detail)) |
|
|
|
addEventListener('join', (e) => createConnection(e.detail.value)) |
|
|
|
addEventListener('leave', (e) => destroyConnection(e.detail.value)) |
|
|
|
addEventListener('logout', () => destroyAll()) |
|
|
|
addEventListener('load', () => doNotLog.add('rpc')) |