Roderic Day před 5 roky
rodič
revize
efda1bf323
2 změnil soubory, kde provedl 82 přidání a 12 odebrání
  1. +80
    -8
      apps/streams.js
  2. +2
    -4
      pico.js

+ 80
- 8
apps/streams.js Zobrazit soubor

@@ -2,7 +2,8 @@ const VideoConfig = Object.seal({
videoOn: true,
audioOn: true,
get video() {
return VideoConfig.videoOn && {width: {ideal: 320}, facingMode: 'user', frameRate: 26}
return VideoConfig.videoOn
&& {width: {ideal: 320}, facingMode: 'user', frameRate: 26}
},
get audio() {
return VideoConfig.audioOn
@@ -13,19 +14,22 @@ const VideoConfig = Object.seal({
}
})
const VideoSelf = {
update() {
const stream = document.querySelector('video.self').srcObject
stream.getTracks().forEach(track => {
async update() {
const video = document.querySelector('video.self')
video.srcObject.getTracks().forEach(track => {
track.stop()
stream.removeTrack(track)
video.srcObject.removeTrack(track)
delete track
})
stream = new MediaStream()
if(VideoConfig.videoOn || VideoConfig.audioOn) {
navigator.mediaDevices
await navigator.mediaDevices
.getUserMedia(VideoConfig)
.then(s => s.getTracks().forEach(t => stream.addTrack(t)))
.catch(e => console.error(e))
}
video.srcObject = stream
wire({kind: 'peerInfo', value: {type: 'request'}})
},
setUp: ({dom}) => {
dom.playsinline = true
@@ -57,10 +61,73 @@ const VideoSelf = {
},
}
const VideoOther = {
setUp: ({dom}) => {
setUp: (username) => ({dom}) => {
dom.playsinline = true
dom.autoplay = true
dom.srcObject = new MediaStream()
let rpc = null

const rpcConfig = {iceServers: [{urls: 'stun:stun.sipgate.net:3478'}]}

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)
dom.srcObject = new MediaStream()
document.querySelector('video.self').srcObject.getTracks()
.forEach(t => rpc.addTrack(t))

rpc.onicecandidate = ({candidate}) => {
if(candidate && candidate.candidate) {
wire({kind: 'peerInfo', value: {type: 'candidate', candidate}, target: username})
}
}
rpc.ontrack = ({track}) => {
dom.srcObject.addTrack(track)
}
}

const onPeerInfo = async ({detail: {source, value}}) => {
if(source !== username) {
return
}
console.log(source, value.type)
if(value.type === 'request') {
resetRpc()
const localOffer = await rpc.createOffer()
await rpc.setLocalDescription(localOffer)
wire({kind: 'peerInfo', value: localOffer, target: username})
}
else if(value.type === 'offer') {
resetRpc()
const remoteOffer = new RTCSessionDescription(value)
await rpc.setRemoteDescription(remoteOffer)
const localAnswer = await rpc.createAnswer()
await rpc.setLocalDescription(localAnswer)
wire({kind: 'peerInfo', value: localAnswer, target: username})
}
else if(value.type === 'answer') {
const remoteAnswer = new RTCSessionDescription(value)
await rpc.setRemoteDescription(remoteAnswer)
}
else if(value.type === 'candidate') {
const candidate = new RTCIceCandidate(value.candidate)
await rpc.addIceCandidate(candidate)
}
else if(value.type === 'stop') {
stopRpc()
}
}

addEventListener('peerInfo', onPeerInfo)
},
view({attrs: {username}}) {
const styleOuter = {
@@ -80,11 +147,12 @@ const VideoOther = {
m('.video-info', {style: {position: 'absolute', zIndex: 999}},
m('span', {style: {padding: '5px'}}, username),
),
m('video.self', {style: styleInner, oncreate: this.setUp}),
m('video', {style: styleInner, oncreate: this.setUp(username)}),
)
},
}
const StreamContainer = {
// screen.width, screen.height
getColumns() {
const n = State.online.length
if(n > 4) return '1fr 1fr 1fr'
@@ -119,3 +187,7 @@ 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))

+ 2
- 4
pico.js Zobrazit soubor

@@ -15,8 +15,6 @@ const State = Object.seal({
*/
const wire = (message) => State.websocket.send(JSON.stringify(message))
const signal = (message) => dispatchEvent(new CustomEvent(message.kind, {detail: message}))
const signalPeerRequest = () => wire({kind: 'peerInfo', value: {type: 'request'}})
const signalPeerStop = (username) => signal({kind: 'peerInfo', value: {type: 'stop'}, source: username})
const listen = (kind, handler) => {
addEventListener(kind, handler)
}
@@ -94,7 +92,7 @@ const Base = {
),
m('.error', State.info),
),
m(StreamContainer),
State.isConnected ? m(StreamContainer) : null,
)
},
}
@@ -130,7 +128,7 @@ const connect = (username) => {
}

if(!doNotLog.has(message.kind)) {
console.log(message)
console.log('@', message)
}
signal(message)


Načítá se…
Zrušit
Uložit