You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

84 line
2.7KB

  1. addEventListener('rpc-new', ({detail}) => {
  2. const {uid, kind} = detail.value
  3. if(kind === 'screen') {
  4. const sender = ScreenShare.isSelf && ScreenShare.stream
  5. const receiver = !ScreenShare.isSelf && ScreenShare.stream
  6. signal({kind: 'rpc-setup', value: {uid, sender, receiver}})
  7. }
  8. })
  9. const ScreenShareConfig = {
  10. view() {
  11. const start = async () => {
  12. await ScreenShare.getStream()
  13. wire({kind: 'screen-share-start'})
  14. }
  15. const stop = () => wire({kind: 'screen-share-stop'})
  16. if (ScreenShare.source === null) {
  17. return m('button', {onclick: start}, 'start screen sharing')
  18. }
  19. else if (ScreenShare.isSelf) {
  20. return m('button', {onclick: stop}, 'stop screen sharing')
  21. }
  22. else {
  23. return m('button[disabled]', `${ScreenShare.source} is screen sharing`)
  24. }
  25. }
  26. }
  27. const ScreenShare = {
  28. source: null,
  29. stream: new MediaStream(),
  30. get isSelf() {
  31. return ScreenShare.source === State.username
  32. },
  33. async getStream() {
  34. const stream = await navigator.mediaDevices.getDisplayMedia({})
  35. stream.getTracks()
  36. .forEach(tr => ScreenShare.stream.addTrack(tr, stream))
  37. },
  38. async stopStream() {
  39. ScreenShare.stream.getTracks()
  40. .forEach(tr => tr.stop())
  41. ScreenShare.stream = new MediaStream()
  42. },
  43. view() {
  44. const style = {
  45. overflow: 'scroll',
  46. backgroundColor: 'gray',
  47. color: 'white',
  48. fontFamily: 'monospace',
  49. position: 'relative',
  50. }
  51. return m('.screen-share', {style},
  52. ScreenShare.isSelf ? m('span', 'You are sharing your screen') :
  53. ScreenShare.source ? m('video[playsinline][autoplay]', {srcObject: ScreenShare.stream})
  54. : [],
  55. )
  56. },
  57. }
  58. function sendScreen(target, stream) {
  59. signal({kind: 'screen-start', value: {target, stream}})
  60. }
  61. addEventListener('screen-share-start', async ({detail: {source}}) => {
  62. const isNew = ScreenShare.source === null
  63. ScreenShare.source = source
  64. if(isNew && ScreenShare.isSelf) {
  65. State.others.forEach(user => sendScreen(user, ScreenShare.stream))
  66. }
  67. })
  68. addEventListener('screen-share-stop', () => {
  69. ScreenShare.stopStream()
  70. ScreenShare.source = null
  71. })
  72. addEventListener('join', ({detail: {value: user}}) => {
  73. if(ScreenShare.isSelf) {
  74. wire({kind: 'screen-share-start', target: user})
  75. sendScreen(user, ScreenShare.stream)
  76. }
  77. })
  78. addEventListener('load', () => {
  79. doNotLog.add('screen-share-start')
  80. doNotLog.add('screen-share-stop')
  81. Headers.push([ScreenShareConfig])
  82. Apps.push([ScreenShare, {key: 'screen-share-container'}])
  83. })