浏览代码

Hot swap streams

master
Roderic Day 5 年前
父节点
当前提交
21c67fd215
共有 1 个文件被更改,包括 32 次插入13 次删除
  1. +32
    -13
      pico.js

+ 32
- 13
pico.js 查看文件

if(State.username === username) { if(State.username === username) {
return return
} }
const myStream = State.streams[State.username]
if(!State.rpcs[username] && myStream) {
if(!State.rpcs[username]) {
const rpc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.sipgate.net:3478'}]}) const rpc = new RTCPeerConnection({iceServers: [{urls: 'stun:stun.sipgate.net:3478'}]})
myStream.getTracks().forEach(track => rpc.addTrack(track, myStream))
rpc.onicecandidate = ({candidate}) => { rpc.onicecandidate = ({candidate}) => {
if(candidate) { if(candidate) {
wire({kind: 'peerInfo', value: {type: 'candidate', candidate}}) wire({kind: 'peerInfo', value: {type: 'candidate', candidate}})
} }
return State.rpcs[username] return State.rpcs[username]
} }
const getSelectedMedia = async () => {
const stream = new MediaStream()
const addTrack = stream.addTrack.bind(stream)
const setSelectedMedia = async () => {
const localStream = State.streams[State.username]
if(!localStream) {
return
}

localStream.getTracks().forEach(track => {
track.stop()
localStream.removeTrack(track)
})

const addTrack = localStream.addTrack.bind(localStream)


const muted = document.querySelector('#mute-check').checked const muted = document.querySelector('#mute-check').checked
if(!muted) { if(!muted) {
.catch(e => console.error(e)) .catch(e => console.error(e))
} }


return stream
document.querySelectorAll('video').forEach(video => video.srcObject = video.srcObject)
wire({kind: 'peerInfo', value: {type: 'request'}})
} }
const onPeerInfo = async ({detail: message}) => { const onPeerInfo = async ({detail: message}) => {
const rpc = getOrCreateRpc(message.source)
const localStream = State.streams[State.username]
const rpc = localStream && getOrCreateRpc(message.source)
const resetStreams = () => {
rpc.getSenders().forEach(sender => rpc.removeTrack(sender))
localStream.getTracks().forEach(track => rpc.addTrack(track, localStream))
}
if(rpc && message.value.type === 'request') { if(rpc && message.value.type === 'request') {
resetStreams()
const localOffer = await rpc.createOffer() const localOffer = await rpc.createOffer()
await rpc.setLocalDescription(localOffer) await rpc.setLocalDescription(localOffer)
wire({kind: 'peerInfo', value: localOffer, target: message.source}) wire({kind: 'peerInfo', value: localOffer, target: message.source})
} }
else if(rpc && message.value.type === 'offer') { else if(rpc && message.value.type === 'offer') {
resetStreams()
const remoteOffer = new RTCSessionDescription(message.value) const remoteOffer = new RTCSessionDescription(message.value)
await rpc.setRemoteDescription(remoteOffer) await rpc.setRemoteDescription(remoteOffer)
const localAnswer = await rpc.createAnswer() const localAnswer = await rpc.createAnswer()
echoCancellation: true, echoCancellation: true,
}, },
turnOn: async () => { turnOn: async () => {
const media = await getSelectedMedia()
State.streams[State.username] = media
wire({kind: 'peerInfo', value: {type: 'request'}})
State.streams[State.username] = new MediaStream()
await setSelectedMedia()
m.redraw() m.redraw()
}, },
turnOff: () => { turnOff: () => {
? m('button', {onclick: Media.turnOff}, 'turn off') ? m('button', {onclick: Media.turnOff}, 'turn off')
: m('button', {onclick: Media.turnOn}, 'turn on') : m('button', {onclick: Media.turnOn}, 'turn on')
, ,
m('select#media-source', Media.videoSources.map(option => m('option', option))),
m('label', m('input#mute-check', {type: 'checkbox'}), 'mute'),
m('select#media-source', {onchange: setSelectedMedia},
Media.videoSources.map(option => m('option', option))
),
m('label',
m('input#mute-check', {onchange: setSelectedMedia, type: 'checkbox'}),
'mute'
),
), ),
m('.videos', m('.videos',
Object.keys(State.streams).map((username) => Object.keys(State.streams).map((username) =>

正在加载...
取消
保存