getUserMedia problem in firefox
[henge/kiak.git] / host.js
1 document.title = "Strapp.io Host"
2
3
4 const conf = {"iceServers": [{ "urls": "stun:stun.1.google.com:19302" }] }
5 const clients = new Map([])
6 const iceCandidates = []
7 let dataChannel
8
9
10 /* TODO: duplicate in both client.js and host.jhs */
11 function getPublicKey() {
12 return new Promise( (resolve, reject) => {
13 /* Check local storage for public key */
14 if (!window.localStorage.getItem('public-key')) {
15 console.log('public key is undefined')
16 /* If doesn't exist, generate public and private key pair, store in
17 local storage */
18 crypto.subtle.generateKey(
19 { name:'RSA-OAEP',
20 modulusLength: 2048,
21 publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
22 hash: {name: "SHA-256"}
23 },
24 true,
25 ['encrypt', 'decrypt']
26 ).then((keyPair) => {
27 /* TODO: Do we need to store the private key as well? */
28 crypto.subtle.exportKey('jwk', keyPair.publicKey)
29 .then((exportedKey) => {
30 window.localStorage.setItem('publicKey', exportedKey)
31 console.log('public key is' + window.localStorage.getItem('publicKey'))
32 resolve(exportedKey)
33 })
34
35 })
36 }
37 else {
38 resolve(window.localStorage.getItem('publicKey'))
39 }
40 })
41 }
42
43 function handleNewClientConnection(offer) {
44 /* New Client Connection*/
45 hpc = new RTCPeerConnection(conf)
46 //console.log(offer)
47 clients.set(offer.pubKey, hpc)
48 hpc.setRemoteDescription(offer.sdp)
49 .then(() => {
50 hpc.createAnswer().then((answer) => {
51 return hpc.setLocalDescription(answer)
52 })
53 .then(() => {
54 getPublicKey().then((hpk) => {
55 hpc.onicecandidate = (event) => {
56 if (event.candidate) {
57 console.log('Host: Allocating ice candidate for client')
58 iceCandidates.push(JSON.stringify({
59 cmd: "< ice pubKey",
60 ice: event.candidate,
61 hostPubKey: hpk.n, /* TODO: do we need to send this? */
62 clientPubKey: offer.pubKey,
63 iceState: "a"
64 }))
65 }
66 else {
67 console.log('Host: Finished sending ICE candidates')
68 console.log(hpc)
69 }
70 }
71 console.log('Host: Sending answer to Client')
72 wsock.send(JSON.stringify({
73 cmd: '< sdp pubKey',
74 sdp: hpc.localDescription,
75 hostPubKey: hpk.n,
76 clientPubKey: offer.pubKey
77 }))
78 hpc.ondatachannel = (evt) => {
79 dataChannel = evt.channel
80 console.log(evt)
81 dataChannel.onmessage = (msg) => {
82 console.log(msg.data)
83 }
84 dataChannel.onopen = () => {
85 dataChannel.send(`Hi ${offer.pubKey} -host`)
86 }
87 }
88 hpc.oniceconnectionstatechange = () => {
89 console.log('iceConnectionState = ' + hpc.iceConnectionState)
90 }
91 })
92 }).catch((err) => {
93 console.log(`error in host answer ${err}`)
94 })
95 })
96
97 }
98
99 function handleNewIceSubmission(msg) {
100 console.log('Host: Adding new ice candidate')
101 const hpc = clients.get(msg.pubKey)
102 let candidate = new RTCIceCandidate(msg.ice)
103 hpc.addIceCandidate(candidate)
104 }
105
106 function handleIceRequest(msg) {
107 console.log('Host: Handling ice candidate request')
108 console.log(iceCandidates)
109 const hpc = clients.get(msg.pubKey)
110 const iceCandidate = iceCandidates.pop()
111 if (iceCandidate !== undefined) {
112 wsock.send(iceCandidate)
113 } else {
114 if (hpc.iceGatheringState.localeCompare('gathering') === 0) {
115 wsock.send(`{"cmd" : "< ice pubKey", "clientPubKey":"${msg.pubKey}", "iceState": "g"}`)
116 }
117 else if (hpc.iceGatheringState.localeCompare('complete') === 0) {
118 wsock.send(`{"cmd" : "< ice pubKey", "clientPubKey":"${msg.pubKey}", "iceState": "c"}`)
119 }
120
121 }
122
123 }
124 if ("WebSocket" in window) {
125 document.addEventListener('DOMContentLoaded', (event) => {
126 wsock = new WebSocket(`${_strapp_protocol}://${window.location.hostname}:${_strapp_port}`)
127 wsock.onopen = () => {
128 console.log(`Strapped to ${_strapp_protocol}://${window.location.hostname}:${_strapp_port}`)
129 }
130
131 wsock.onmessage = (serverMsg) => {
132 /* msg is either offer or ice candidate or ice candidate request*/
133
134 /* What if data null? */
135 let msg = JSON.parse(serverMsg.data)
136
137 const clientID = msg.pubKey
138
139 /* TODO: redo this trash */
140 if (clients.has(clientID)) {
141 if (msg.ice) {
142 handleNewIceSubmission(msg)
143 } else if (msg.sdp) {
144 //handleRepeatedOffer
145 } else {
146 handleIceRequest(msg)
147 }
148 }
149 else {
150 if (msg.ice) {
151 console.log('Host: Client that doesnt exist is sending ice submissions')
152 } else if (msg.sdp) {
153 handleNewClientConnection(msg)
154 } else {
155 console.log('Host: Client that doesnt exist is sending ice requests')
156 }
157 }
158 }
159 document.body.innerHTML = '<div>Choose options for client</div> <video autoplay></video>'
160
161 navigator.mediaDevices.getUserMedia({ video : { mediaSource: "screen", // whole screen sharing
162 // mediaSource: "window", // choose a window to share
163 // mediaSource: "application", // choose a window to share
164 width: {max: '1920'},
165 height: {max: '1080'},
166 frameRate: {max: '10'}} })
167 .then(function(mediaStream) {
168 let video = document.querySelector('video')
169 video.srcObject = mediaStream
170 video.onloadedmetadata = function(e) {
171 video.play()
172 }
173 })
174 .catch(function(err) { console.log(err); }); // always check for errors at the end.
175 })
176 }
177 else {
178 document.addEventListener('DOMContentLoaded', () => {
179 document.body.innerHTML = 'Websockets not supported in your browser'
180 })
181 }