Explorar el Código

Working again?

master
Roderic Day hace 4 años
padre
commit
81e1a3f171
Se han modificado 3 ficheros con 61 adiciones y 66 borrados
  1. +55
    -8
      apps/rpc.js
  2. +5
    -56
      apps/streams.js
  3. +1
    -2
      pico.html

+ 55
- 8
apps/rpc.js Ver fichero

@@ -1,5 +1,33 @@
const connections = {}
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))
m.redraw()

if(source === State.username) {
reloadAllStreams()
}
}

function reloadAllStreams() {
State.online.forEach(username => {
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)
@@ -10,8 +38,9 @@ function createConnection(target) {
wire({kind: 'rpc', value, target})
}
}
rpc.ontrack = ({track}) => {
console.log(track)
rpc.ontrack = () => {
const tracks = rpc.getReceivers().map(t => t.track)
setTracks({source: target, tracks: tracks})
}
rpc.onconnectionstatechange = () => {
if(rpc.connectionState === 'failed') {
@@ -39,9 +68,16 @@ function createConnection(target) {

async function handlePeerInfo({source: target, value}) {
const rpc = connections[target]

if(!rpc) {
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))

if(value.type === 'request') {
const localOffer = await rpc.createOffer()
await rpc.setLocalDescription(localOffer)
@@ -56,21 +92,32 @@ async function handlePeerInfo({source: target, value}) {
}
else if(value.type === 'answer') {
const remoteAnswer = new RTCSessionDescription(value)
await rpc.setRemoteDescription(remoteAnswer)
await rpc.setRemoteDescription(remoteAnswer).catch(e => e)
}
else if(value.type === 'candidate') {
const candidate = new RTCIceCandidate(value.candidate)
await rpc.addIceCandidate(candidate)
await rpc.addIceCandidate(candidate).catch(e => e)
}
}

function removeConnection(user) {
const rpc = connections[user]
if(rpc) {
delete connections[user]
function destroyConnection(username) {
if(streams[username]) {
streams[username].getTracks().forEach(t => t.stop())
delete streams[username]
}
if(datachannels[username]) {
datachannels[username].close()
delete datachannels[username]
}
if(connections[username]) {
connections[username].getReceivers().forEach(r => r.track.stop())
connections[username].close()
delete connections[username]
}
}

addEventListener('tracks', (e) => setTracks(e.detail.value))
addEventListener('rpc', (e) => handlePeerInfo(e.detail))
addEventListener('join', (e) => createConnection(e.detail.value))
addEventListener('leave', (e) => destroyConnection(e.detail.value))
addEventListener('load', () => doNotLog.add('rpc'))

+ 5
- 56
apps/streams.js Ver fichero

@@ -2,7 +2,7 @@ const Toggle = {
view({attrs: {label, value}}) {
const onclick = () => {
StreamContainer[value] = !StreamContainer[value]
updateSelfVideo()
requestStream()
}
const checked = StreamContainer[value]
return m('label.styled',
@@ -29,67 +29,21 @@ const VideoConfig = {
]
}
}
const updateSelfVideo = async () => {
const video = document.querySelector('video.self')

video.srcObject.getTracks().forEach(track => {
track.stop()
video.srcObject.removeTrack(track)
delete track
})

const requestStream = async () => {
if(StreamContainer.videoOn || StreamContainer.audioOn) {
await navigator.mediaDevices
.getUserMedia(VideoConfig)
.then(s => s.getTracks().forEach(t => video.srcObject.addTrack(t)))
.then(s => signal({kind: 'tracks', value: {source: State.username, tracks: s.getTracks()}}))
.catch(e => console.error(e))
}
video.srcObject = video.srcObject // safari

wire({kind: 'peerInfo', value: {type: 'request'}})
}
const updateOtherVideo = (target, dom) => {
dom.srcObject = new MediaStream()
let rpc = null

const stopRpc = () => {
rpc && rpc.close()
dom.srcObject.getTracks().forEach(track => {
track.stop()
dom.srcObject.removeTrack(track)
delete track
})
}

const resetRpc = () => {
stopRpc()
rpc = new RTCPeerConnection(rpcConfig)
document.querySelector('video.self').srcObject.getTracks()
.forEach(t => rpc.addTrack(t))
}
}
const Video = {
setUp: (username) => ({dom}) => {
dom.username = username
dom.srcObject = new MediaStream()
if(username === State.username) {
dom.classList.add('self')
dom.muted = true
updateSelfVideo()
}
else {
updateOtherVideo(username, dom)
requestStream()
}
},
tearDown: (username) => ({dom}) => {
removeEventListener('peerInfo', dom.listener)

dom.srcObject.getTracks().forEach(track => {
track.stop()
dom.srcObject.removeTrack(track)
delete track
})
},
view({attrs: {username}}) {
const styleOuter = {
position: 'relative',
@@ -119,8 +73,8 @@ const Video = {
),
m('video[playsinline][autoplay]', {
style: styleVideo,
srcObject: streams[username],
oncreate: this.setUp(username),
onremove: this.tearDown(username),
}),
)
},
@@ -148,11 +102,6 @@ const StreamContainer = {
)
},
}
const signalPeerStop = (username) => {
signal({kind: 'peerInfo', value: {type: 'stop'}, source: username})
}
addEventListener('pagehide', () => State.online.forEach(signalPeerStop))
addEventListener('logout', () => State.online.forEach(signalPeerStop))
addEventListener('load', () => {
Headers.push([VideoConfig])
Apps.push([StreamContainer, {key: 'stream-container'}])

+ 1
- 2
pico.html Ver fichero

@@ -9,11 +9,10 @@
<!-- <script src="/libs/purify.min.js"></script> -->
<script src="/pico.js" defer></script>
<script src="/apps/rpc.js"></script>
<!-- <script src="/apps/streams.js"></script> -->
<script src="/apps/streams.js"></script>
<!-- <script src="/apps/screen.js"></script> -->
<!-- <script src="/apps/chat.js"></script> -->
<!-- <script src="/apps/volume.js"></script> -->
<!-- <script src="/apps/screen.js"></script> -->
</head>
<style>
body {

Cargando…
Cancelar
Guardar