Explorar el Código

screen-share

master
Roderic Day hace 4 años
padre
commit
215a987c20
Se han modificado 3 ficheros con 59 adiciones y 54 borrados
  1. +29
    -12
      apps/rpc.js
  2. +29
    -41
      apps/screen.js
  3. +1
    -1
      pico.html

+ 29
- 12
apps/rpc.js Ver fichero

@@ -20,9 +20,18 @@ function rpcStatusCheck() {

function rpcCleanUp(kind, target) {
for([uid, info] of Object.entries(allRPCs)) {
if(info.kind === kind && info.target === target) {
const sameKind = info.kind === kind
const sameTarget = info.target === target

let shouldClose = false
shouldClose ||= !State.online.includes(info.target)
shouldClose ||= (sameKind && kind === 'screen')
shouldClose ||= (sameKind && kind === 'video' && sameTarget)

if(shouldClose) {
info.rpc.close()
delete allRPCs[uid]
console.log(`${info.target} ${info.kind} closed`)
}
}
}
@@ -60,18 +69,18 @@ addEventListener('rpc-needed', ({detail}) => {

addEventListener('rpc-setup', async ({detail}) => {
const {uid, sender, receiver} = detail.value
const {rpc, isInitiatedLocally, hasOffer} = allRPCs[uid]
const {rpc, isInitiatedLocally} = allRPCs[uid]
allRPCs[uid].sender = sender
allRPCs[uid].receiver = receiver
if(sender) {
sender.getTracks().forEach(tr => rpc.addTrack(tr, sender))
}
allRPCs[uid].isSetup = true
allRPCs[uid].loadedMedia = true

if(isInitiatedLocally) {
signal({kind: 'rpc-initiate', value: {uid}})
}
else if(hasOffer) {
else {
signal({kind: 'rpc-respond', value: {uid}})
}
})
@@ -88,24 +97,24 @@ addEventListener('rpc-initiate', async({detail}) => {

addEventListener('rpc-offer', async ({detail}) => {
const {uid} = detail.value
const {rpc, isSetup} = allRPCs[uid]
const {rpc} = allRPCs[uid]

await rpc.setRemoteDescription(detail.value)
allRPCs[uid].hasOffer = true

if(isSetup) {
signal({kind: 'rpc-respond', value: {uid}})
}
signal({kind: 'rpc-respond', value: {uid}})
})

addEventListener('rpc-respond', async({detail}) => {
const {uid} = detail.value
const {rpc, target} = allRPCs[uid]
const {rpc, target, loadedMedia, hasOffer} = allRPCs[uid]

const localAnswer = await rpc.createAnswer()
await rpc.setLocalDescription(localAnswer)
if(loadedMedia && hasOffer) {
const localAnswer = await rpc.createAnswer()
await rpc.setLocalDescription(localAnswer)

wire({kind: 'rpc-answer', value: {...K(localAnswer), uid}, target})
wire({kind: 'rpc-answer', value: {...K(localAnswer), uid}, target})
}
})

addEventListener('rpc-answer', async ({detail}) => {
@@ -118,6 +127,14 @@ addEventListener('ice-candidate', async ({detail}) => {
await allRPCs[uid].rpc.addIceCandidate(detail.value)
})

addEventListener('leave', () => {
rpcCleanUp()
})

addEventListener('screen-stop', () => {
rpcCleanUp('screen')
})

addEventListener('load', () => {
doNotLog.add('rpc-needed')
doNotLog.add('rpc-offer')

+ 29
- 41
apps/screen.js Ver fichero

@@ -1,44 +1,47 @@
addEventListener('rpc-new', ({detail}) => {
const {uid, kind} = detail.value
if(kind === 'screen') {
const sender = ScreenShare.isSelf && ScreenShare.stream
const receiver = !ScreenShare.isSelf && ScreenShare.stream
const sender = ScreenShare.isSource && ScreenShare.stream
const receiver = !ScreenShare.isSource && ScreenShare.stream
signal({kind: 'rpc-setup', value: {uid, sender, receiver}})
}
})
const ScreenShareConfig = {
view() {
const start = async () => {
await ScreenShare.getStream()
wire({kind: 'screen-share-start'})
}
const stop = () => wire({kind: 'screen-share-stop'})
if (ScreenShare.source === null) {
return m('button', {onclick: start}, 'start screen sharing')
}
else if (ScreenShare.isSelf) {
return m('button', {onclick: stop}, 'stop screen sharing')
if (ScreenShare.isOff) {
const onclick = ScreenShare.getStream
return m('button', {onclick}, 'start screen sharing')
}
else {
return m('button[disabled]', `${ScreenShare.source} is screen sharing`)
const onclick = () => wire({kind: 'screen-stop'})
return m('button', {onclick}, 'stop screen sharing')
}
}
}
const ScreenShare = {
source: null,
isSource: false,
stream: new MediaStream(),
get isSelf() {
return ScreenShare.source === State.username
get isOff() {
return ScreenShare.stream.getTracks().length === 0
},
async getStream() {
const stream = await navigator.mediaDevices.getDisplayMedia({})
stream.getTracks()
await navigator.mediaDevices
.getDisplayMedia({})
.then(stream => stream
.getTracks()
.forEach(tr => ScreenShare.stream.addTrack(tr, stream))
)
ScreenShare.isSource = true
State.others.forEach(target => {
signal({kind: 'rpc-needed', value: {kind: 'screen', target}})
})
m.redraw()
},
async stopStream() {
ScreenShare.stream.getTracks()
.forEach(tr => tr.stop())
ScreenShare.stream.getTracks().forEach(tr => tr.stop())
ScreenShare.stream = new MediaStream()
ScreenShare.isSource = false
m.redraw()
},
view() {
const style = {
@@ -48,36 +51,21 @@ const ScreenShare = {
fontFamily: 'monospace',
position: 'relative',
}
return m('.screen-share', {style},
ScreenShare.isSelf ? m('span', 'You are sharing your screen') :
ScreenShare.source ? m('video[playsinline][autoplay]', {srcObject: ScreenShare.stream})
: [],
return ScreenShare.isOff ? [] : m('.screen-share', {style},
m('video[playsinline][autoplay]', {srcObject: ScreenShare.stream})
)
},
}
function sendScreen(target, stream) {
signal({kind: 'screen-start', value: {target, stream}})
}
addEventListener('screen-share-start', async ({detail: {source}}) => {
const isNew = ScreenShare.source === null
ScreenShare.source = source
if(isNew && ScreenShare.isSelf) {
State.others.forEach(user => sendScreen(user, ScreenShare.stream))
}
})
addEventListener('screen-share-stop', () => {
addEventListener('screen-stop', () => {
ScreenShare.stopStream()
ScreenShare.source = null
})
addEventListener('join', ({detail: {value: user}}) => {
if(ScreenShare.isSelf) {
wire({kind: 'screen-share-start', target: user})
sendScreen(user, ScreenShare.stream)
if(ScreenShare.isSource) {
signal({kind: 'rpc-needed', value: {kind: 'screen', target: user}})
}
})
addEventListener('load', () => {
doNotLog.add('screen-share-start')
doNotLog.add('screen-share-stop')
doNotLog.add('screen-stop')
Headers.push([ScreenShareConfig])
Apps.push([ScreenShare, {key: 'screen-share-container'}])
})

+ 1
- 1
pico.html Ver fichero

@@ -10,7 +10,7 @@
<script src="/pico.js" defer></script>
<script src="/apps/rpc.js"></script>
<script src="/apps/video.js"></script>
<!-- <script src="/apps/screen.js"></script> -->
<script src="/apps/screen.js"></script>
<!-- <script src="/apps/chat.js"></script> -->
<!-- <script src="/apps/volume.js"></script> -->
</head>

Cargando…
Cancelar
Guardar