diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/client/views/webcam/DashWebRTC.ts | 596 | ||||
-rw-r--r-- | src/client/views/webcam/DashWebRTCVideo.tsx | 475 | ||||
-rw-r--r-- | src/server/index.ts | 90 |
3 files changed, 596 insertions, 565 deletions
diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts index 7d798754f..ef5ecf0fc 100644 --- a/src/client/views/webcam/DashWebRTC.ts +++ b/src/client/views/webcam/DashWebRTC.ts @@ -1,314 +1,314 @@ -import { DocServer } from '../../DocServer'; -import { Utils } from '../../../Utils'; -import { MessageStore } from '../../../server/Message'; - - - -/** - * This namespace will have the code required to have functionality code for the usage of webRTC. - */ -export class DashWebRTC { - - - private isChannelReady = false; - private isInitiator = false; - private isStarted = false; - localStream: MediaStream | undefined; - private pc: any; - remoteStream: MediaStream | undefined; - private turnReady: boolean | undefined; - localVideo: HTMLVideoElement | undefined; - remoteVideo: HTMLVideoElement | undefined; - curRoom: string = ""; - - - private pcConfig: any; - private sdpConstraints: any; - - constructor() { - this.pcConfig = { - 'iceServers': [{ - 'urls': 'stun:stun.l.google.com:19302' - }] - }; +// import { DocServer } from '../../DocServer'; +// import { Utils } from '../../../Utils'; +// import { MessageStore } from '../../../server/Message'; + + + +// /** +// * This namespace will have the code required to have functionality code for the usage of webRTC. +// */ +// export class DashWebRTC { + + +// private isChannelReady = false; +// private isInitiator = false; +// private isStarted = false; +// localStream: MediaStream | undefined; +// private pc: any; +// remoteStream: MediaStream | undefined; +// private turnReady: boolean | undefined; +// localVideo: HTMLVideoElement | undefined; +// remoteVideo: HTMLVideoElement | undefined; +// curRoom: string = ""; + + +// private pcConfig: any; +// private sdpConstraints: any; + +// constructor() { +// this.pcConfig = { +// 'iceServers': [{ +// 'urls': 'stun:stun.l.google.com:19302' +// }] +// }; - // Set up audio and video regardless of what devices are present. - this.sdpConstraints = { - offerToReceiveAudio: true, - offerToReceiveVideo: true - }; - } +// // Set up audio and video regardless of what devices are present. +// this.sdpConstraints = { +// offerToReceiveAudio: true, +// offerToReceiveVideo: true +// }; +// } - init(room: string) { +// init(room: string) { - this.curRoom = room; - let self = this; +// this.curRoom = room; +// let self = this; - if (room !== '') { - DocServer._socket.emit('create or join', room); - console.log('Attempted to create or join room', room); +// if (room !== '') { +// DocServer._socket.emit('create or join', room); +// console.log('Attempted to create or join room', room); - } +// } - DocServer._socket.on('created', function (room: string) { - console.log('Created room ' + room); - self.isInitiator = true; - }); +// DocServer._socket.on('created', function (room: string) { +// console.log('Created room ' + room); +// self.isInitiator = true; +// }); - DocServer._socket.on('full', function (room: string) { - console.log('Room ' + room + ' is full'); - }); +// DocServer._socket.on('full', function (room: string) { +// console.log('Room ' + room + ' is full'); +// }); - DocServer._socket.on('join', function (room: string) { - console.log('Another peer made a request to join room ' + room); - console.log('This peer is the initiator of room ' + room + '!'); - self.isChannelReady = true; - }); +// DocServer._socket.on('join', function (room: string) { +// console.log('Another peer made a request to join room ' + room); +// console.log('This peer is the initiator of room ' + room + '!'); +// self.isChannelReady = true; +// }); - DocServer._socket.on('joined', function (room: string) { - console.log('joined: ' + room); - self.isChannelReady = true; - }); +// DocServer._socket.on('joined', function (room: string) { +// console.log('joined: ' + room); +// self.isChannelReady = true; +// }); - DocServer._socket.on('log', function (array: any) { - console.log.apply(console, array); - }); +// DocServer._socket.on('log', function (array: any) { +// console.log.apply(console, array); +// }); - // This client receives a message - DocServer._socket.on('message', function (message: any) { - console.log('Client received message:', message); - if (message.message === 'got user media') { - self.maybeStart(); - } else if (message.message.type === 'offer') { - if (!self.isInitiator && !self.isStarted) { - self.maybeStart(); - } - self.pc.setRemoteDescription(new RTCSessionDescription(message.message)); - self.doAnswer(); - } else if (message.message.type === 'answer' && self.isStarted) { - self.pc.setRemoteDescription(new RTCSessionDescription(message.message)); - } else if (message.message.type === 'candidate' && self.isStarted) { - let candidate = new RTCIceCandidate({ - sdpMLineIndex: message.message.label, - candidate: message.message.candidate - }); - self.pc.addIceCandidate(candidate); - } else if (message === 'bye' && self.isStarted) { - self.handleRemoteHangup(); - } - }); +// // This client receives a message +// DocServer._socket.on('message', function (message: any) { +// console.log('Client received message:', message); +// if (message.message === 'got user media') { +// self.maybeStart(); +// } else if (message.message.type === 'offer') { +// if (!self.isInitiator && !self.isStarted) { +// self.maybeStart(); +// } +// self.pc.setRemoteDescription(new RTCSessionDescription(message.message)); +// self.doAnswer(); +// } else if (message.message.type === 'answer' && self.isStarted) { +// self.pc.setRemoteDescription(new RTCSessionDescription(message.message)); +// } else if (message.message.type === 'candidate' && self.isStarted) { +// let candidate = new RTCIceCandidate({ +// sdpMLineIndex: message.message.label, +// candidate: message.message.candidate +// }); +// self.pc.addIceCandidate(candidate); +// } else if (message === 'bye' && self.isStarted) { +// self.handleRemoteHangup(); +// } +// }); - navigator.mediaDevices.getUserMedia({ - audio: false, - video: true - }) - .then(this.gotStream) - .catch(function (e) { - alert('getUserMedia() error: ' + e.name); - }); - - //Trying this one out!!! - console.log('Getting user media with constraints', this.constraints); - - if (location.hostname !== 'localhost') { - this.requestTurn( - 'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913' - ); - } - - - } - - - sendMessage(message: any) { - console.log('Client sending message: ', message); - Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom }); - //DocServer._socket.emit('message', message); - } - - - - - - setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) { - localVideo = localVideo; - remoteVideo = remoteVideo; - } - - setLocalVideoObject(localVideoRef: HTMLVideoElement) { - this.localVideo = localVideoRef; - } - - setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) { - this.remoteVideo = remoteVideoRef; - } - - - - - gotStream(stream: any) { - console.log('Adding local stream.'); - this.localStream = stream; - this.localVideo!.srcObject = stream; - this.sendMessage('got user media'); - if (this.isInitiator) { - this.maybeStart(); - } - } - - constraints = { - video: true, - audio: true - }; - - - - - - maybeStart() { - console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady); - if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) { - console.log('>>>>>> creating peer connection'); - this.createPeerConnection(); - this.pc.addStream(this.localStream); - this.isStarted = true; - console.log('isInitiator', this.isInitiator); - if (this.isInitiator) { - this.doCall(); - } - } - } - - - // //this will need to be changed to our version of hangUp - // window.onbeforeunload = function () { - // sendMessage('bye'); - // }; - - createPeerConnection() { - try { - this.pc = new RTCPeerConnection(undefined); - this.pc.onicecandidate = this.handleIceCandidate; - this.pc.onaddstream = this.handleRemoteStreamAdded; - this.pc.onremovestream = this.handleRemoteStreamRemoved; - console.log('Created RTCPeerConnnection'); - } catch (e) { - console.log('Failed to create PeerConnection, exception: ' + e.message); - alert('Cannot create RTCPeerConnection object.'); - return; - } - } - - handleIceCandidate(event: any) { - console.log('icecandidate event: ', event); - if (event.candidate) { - this.sendMessage({ - type: 'candidate', - label: event.candidate.sdpMLineIndex, - id: event.candidate.sdpMid, - candidate: event.candidate.candidate - }); - } else { - console.log('End of candidates.'); - } - } - - handleCreateOfferError(event: any) { - console.log('createOffer() error: ', event); - } - - doCall() { - console.log('Sending offer to peer'); - this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError); - } - - doAnswer() { - console.log('Sending answer to peer.'); - this.pc.createAnswer().then( - this.setLocalAndSendMessage, - this.onCreateSessionDescriptionError - ); - } - - setLocalAndSendMessage(sessionDescription: any) { - this.pc.setLocalDescription(sessionDescription); - console.log('setLocalAndSendMessage sending message', sessionDescription); - this.sendMessage(sessionDescription); - } - - onCreateSessionDescriptionError(error: any) { - console.log('Failed to create session description: ' + error.toString()); - } - - - requestTurn(turnURL: any) { - var turnExists = false; - let self = this; - for (var i in this.pcConfig.iceServers) { - if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') { - turnExists = true; - this.turnReady = true; - break; - } - } - if (!turnExists) { - console.log('Getting TURN server from ', turnURL); - // No TURN server. Get one from computeengineondemand.appspot.com: - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function () { - if (xhr.readyState === 4 && xhr.status === 200) { - var turnServer = JSON.parse(xhr.responseText); - console.log('Got TURN server: ', turnServer); - self.pcConfig.iceServers.push({ - 'urls': 'turn:' + turnServer.username + '@' + turnServer.turn, - //'credential': turnServer.password - }); - self.turnReady = true; - } - }; - xhr.open('GET', turnURL, true); - xhr.send(); - } - } - - handleRemoteStreamAdded(event: MediaStreamEvent) { - console.log('Remote stream added.'); - this.remoteStream = event.stream!; - this.remoteVideo!.srcObject = this.remoteStream; - } - - handleRemoteStreamRemoved(event: MediaStreamEvent) { - console.log('Remote stream removed. Event: ', event); - } - - hangup() { - console.log('Hanging up.'); - if (this.pc) { - stop(); - this.sendMessage('bye'); - } - - if (this.localStream) { - this.localStream.getTracks().forEach(track => track.stop()); - } - - } - - handleRemoteHangup() { - console.log('Session terminated.'); - stop(); - this.isInitiator = false; - } - - stop() { - this.isStarted = false; - this.pc.close(); - this.pc = null; - } - - -}
\ No newline at end of file +// navigator.mediaDevices.getUserMedia({ +// audio: false, +// video: true +// }) +// .then(this.gotStream) +// .catch(function (e) { +// alert('getUserMedia() error: ' + e.name); +// }); + +// //Trying this one out!!! +// console.log('Getting user media with constraints', this.constraints); + +// if (location.hostname !== 'localhost') { +// this.requestTurn( +// 'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913' +// ); +// } + + +// } + + +// sendMessage(message: any) { +// console.log('Client sending message: ', message); +// Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom }); +// //DocServer._socket.emit('message', message); +// } + + + + + +// setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) { +// this.localVideo = localVideo; +// this.remoteVideo = remoteVideo; +// } + +// setLocalVideoObject(localVideoRef: HTMLVideoElement) { +// this.localVideo = localVideoRef; +// } + +// setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) { +// this.remoteVideo = remoteVideoRef; +// } + + + + +// gotStream(stream: any) { +// console.log('Adding local stream.'); +// this.localStream = stream; +// this.localVideo!.srcObject = stream; +// this.sendMessage('got user media'); +// if (this.isInitiator) { +// this.maybeStart(); +// } +// } + +// constraints = { +// video: true, +// audio: true +// }; + + + + + +// maybeStart() { +// console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady); +// if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) { +// console.log('>>>>>> creating peer connection'); +// this.createPeerConnection(); +// this.pc.addStream(this.localStream); +// this.isStarted = true; +// console.log('isInitiator', this.isInitiator); +// if (this.isInitiator) { +// this.doCall(); +// } +// } +// } + + +// // //this will need to be changed to our version of hangUp +// // window.onbeforeunload = function () { +// // sendMessage('bye'); +// // }; + +// createPeerConnection() { +// try { +// this.pc = new RTCPeerConnection(undefined); +// this.pc.onicecandidate = this.handleIceCandidate; +// this.pc.onaddstream = this.handleRemoteStreamAdded; +// this.pc.onremovestream = this.handleRemoteStreamRemoved; +// console.log('Created RTCPeerConnnection'); +// } catch (e) { +// console.log('Failed to create PeerConnection, exception: ' + e.message); +// alert('Cannot create RTCPeerConnection object.'); +// return; +// } +// } + +// handleIceCandidate(event: any) { +// console.log('icecandidate event: ', event); +// if (event.candidate) { +// this.sendMessage({ +// type: 'candidate', +// label: event.candidate.sdpMLineIndex, +// id: event.candidate.sdpMid, +// candidate: event.candidate.candidate +// }); +// } else { +// console.log('End of candidates.'); +// } +// } + +// handleCreateOfferError(event: any) { +// console.log('createOffer() error: ', event); +// } + +// doCall() { +// console.log('Sending offer to peer'); +// this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError); +// } + +// doAnswer() { +// console.log('Sending answer to peer.'); +// this.pc.createAnswer().then( +// this.setLocalAndSendMessage, +// this.onCreateSessionDescriptionError +// ); +// } + +// setLocalAndSendMessage(sessionDescription: any) { +// this.pc.setLocalDescription(sessionDescription); +// console.log('setLocalAndSendMessage sending message', sessionDescription); +// this.sendMessage(sessionDescription); +// } + +// onCreateSessionDescriptionError(error: any) { +// console.log('Failed to create session description: ' + error.toString()); +// } + + +// requestTurn(turnURL: any) { +// var turnExists = false; +// let self = this; +// for (var i in this.pcConfig.iceServers) { +// if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') { +// turnExists = true; +// this.turnReady = true; +// break; +// } +// } +// if (!turnExists) { +// console.log('Getting TURN server from ', turnURL); +// // No TURN server. Get one from computeengineondemand.appspot.com: +// var xhr = new XMLHttpRequest(); +// xhr.onreadystatechange = function () { +// if (xhr.readyState === 4 && xhr.status === 200) { +// var turnServer = JSON.parse(xhr.responseText); +// console.log('Got TURN server: ', turnServer); +// self.pcConfig.iceServers.push({ +// 'urls': 'turn:' + turnServer.username + '@' + turnServer.turn, +// //'credential': turnServer.password +// }); +// self.turnReady = true; +// } +// }; +// xhr.open('GET', turnURL, true); +// xhr.send(); +// } +// } + +// handleRemoteStreamAdded(event: MediaStreamEvent) { +// console.log('Remote stream added.'); +// this.remoteStream = event.stream!; +// this.remoteVideo!.srcObject = this.remoteStream; +// } + +// handleRemoteStreamRemoved(event: MediaStreamEvent) { +// console.log('Remote stream removed. Event: ', event); +// } + +// hangup() { +// console.log('Hanging up.'); +// if (this.pc) { +// stop(); +// this.sendMessage('bye'); +// } + +// if (this.localStream) { +// this.localStream.getTracks().forEach(track => track.stop()); +// } + +// } + +// handleRemoteHangup() { +// console.log('Session terminated.'); +// stop(); +// this.isInitiator = false; +// } + +// stop() { +// this.isStarted = false; +// this.pc.close(); +// this.pc = null; +// } + + +// }
\ No newline at end of file diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx index 7b091062c..acba95354 100644 --- a/src/client/views/webcam/DashWebRTCVideo.tsx +++ b/src/client/views/webcam/DashWebRTCVideo.tsx @@ -8,7 +8,6 @@ import { InkingControl } from "../InkingControl"; import "../../views/nodes/WebBox.scss"; import "./DashWebRTC.scss"; import adapter from 'webrtc-adapter'; -import { DashWebRTC } from "./DashWebRTC"; import { DocServer } from "../../DocServer"; import { DocumentView } from "../nodes/DocumentView"; import { Utils } from "../../../Utils"; @@ -34,307 +33,337 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV @observable private localVideoEl: HTMLVideoElement | undefined; @observable private peerVideoEl: HTMLVideoElement | undefined; - @observable private localStream: MediaStream | undefined; - @observable private startTime: any = null; - @observable private remoteStream: MediaStream | undefined; - @observable private localPeerConnection: any; - @observable private remotePeerConnection: any; - private callButton: HTMLButtonElement | undefined; - private startButton: HTMLButtonElement | undefined; - private hangupButton: HTMLButtonElement | undefined; private roomText: HTMLInputElement | undefined; private roomOfCam: string = ""; - private webRTCManager: DashWebRTC | undefined; + private isChannelReady = false; + private isInitiator = false; + private isStarted = false; + localStream: MediaStream | undefined; + private pc: any; + remoteStream: MediaStream | undefined; + private turnReady: boolean | undefined; + //localVideo: HTMLVideoElement | undefined; + //remoteVideo: HTMLVideoElement | undefined; + curRoom: string = ""; + + + private pcConfig = { + 'iceServers': [{ + 'urls': 'stun:stun.l.google.com:19302' + }] + }; + + // Set up audio and video regardless of what devices are present. + private sdpConstraints = { + offerToReceiveAudio: true, + offerToReceiveVideo: true + }; componentDidMount() { DocumentDecorations.Instance.addCloseCall(this.closeConnection); - this.webRTCManager = new DashWebRTC(); let self = this; window.onbeforeunload = function () { - self.webRTCManager!.sendMessage('bye'); + self.sendMessage('bye'); }; } closeConnection: CloseCall = () => { - //Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: 'bye', room: this.roomOfCam }); - this.webRTCManager!.hangup(); + this.hangup(); } componentWillUnmount() { - // DocumentDecorations.Instance.removeCloseCall(this.closeConnection); } - // componentDidMount() { - // // DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!); - // //DashWebRTC.init(); - // } - - - // componentDidMount() { - // this.callButton!.disabled = true; - // this.hangupButton!.disabled = true; - // // navigator.mediaDevices.getUserMedia(mediaStreamConstraints).then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError); - // this.localVideoEl!.addEventListener('loadedmetadata', this.logVideoLoaded); - // this.peerVideoEl!.addEventListener('loadedmetadata', this.logVideoLoaded); - // this.peerVideoEl!.addEventListener('onresize', this.logResizedVideo); - // } - - - // gotLocalMediaStream = (mediaStream: MediaStream) => { - // this.localStream = mediaStream; - // if (this.localVideoEl) { - // this.localVideoEl.srcObject = mediaStream; - // } - // this.trace('Received local stream.'); - // this.callButton!.disabled = false; - - // } - - // gotRemoteMediaStream = (event: MediaStreamEvent) => { - // let mediaStream = event.stream; - // this.peerVideoEl!.srcObject = mediaStream; - // this.remoteStream = mediaStream!; + init(room: string) { - // } + this.curRoom = room; + let self = this; - // handleLocalMediaStreamError = (error: string) => { - // //console.log("navigator.getUserMedia error: ", error); - // this.trace(`navigator.getUserMedia error: ${error.toString()}.`); + if (room !== '') { + DocServer._socket.emit('create or join', room); + console.log('Attempted to create or join room', room); - // } - - // logVideoLoaded = (event: any) => { - // let video = event.target; - // this.trace(`${video.id} videoWidth: ${video.videoWidth}px, ` + - // `videoHeight: ${video.videoHeight}px.`); - // } + } - // logResizedVideo = (event: any) => { - // this.logVideoLoaded(event); + DocServer._socket.on('created', function (room: string) { + console.log('Created room ' + room); + self.isInitiator = true; + }); + + DocServer._socket.on('full', function (room: string) { + console.log('Room ' + room + ' is full'); + }); + + DocServer._socket.on('join', function (room: string) { + console.log('Another peer made a request to join room ' + room); + console.log('This peer is the initiator of room ' + room + '!'); + self.isChannelReady = true; + }); + + + DocServer._socket.on('joined', function (room: string) { + console.log('joined: ' + room); + self.isChannelReady = true; + }); + + + DocServer._socket.on('log', function (array: any) { + console.log.apply(console, array); + }); + + // This client receives a message + DocServer._socket.on('message', function (message: any) { + console.log('Client received message:', message); + if (message.message === 'got user media') { + self.maybeStart(); + } else if (message.message.type === 'offer') { + if (!self.isInitiator && !self.isStarted) { + self.maybeStart(); + } + self.pc.setRemoteDescription(new RTCSessionDescription(message.message)); + self.doAnswer(); + } else if (message.message.type === 'answer' && self.isStarted) { + self.pc.setRemoteDescription(new RTCSessionDescription(message.message)); + } else if (message.message.type === 'candidate' && self.isStarted) { + let candidate = new RTCIceCandidate({ + sdpMLineIndex: message.message.label, + candidate: message.message.candidate + }); + self.pc.addIceCandidate(candidate); + } else if (message === 'bye' && self.isStarted) { + self.handleRemoteHangup(); + } + }); + + navigator.mediaDevices.getUserMedia({ + audio: false, + video: true + }) + .then(this.gotStream) + .catch(function (e) { + alert('getUserMedia() error: ' + e.name); + }); + + //Trying this one out!!! + console.log('Getting user media with constraints', this.constraints); + + if (location.hostname !== 'localhost') { + this.requestTurn( + 'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913' + ); + } - // if (this.startTime) { - // let elapsedTime = window.performance.now() - this.startTime; - // this.startTime = null; - // this.trace(`Setup time: ${elapsedTime.toFixed(3)}ms.`); - // } - // } + } - // handleConnection = (event: any) => { - // let peerConnection = event.target; - // let iceCandidate = event.candidate; - // if (iceCandidate) { - // let newIceCandidate: RTCIceCandidate = new RTCIceCandidate(iceCandidate); - // let otherPeer: any = this.getOtherPeer(peerConnection); + private sendMessage = (message: any) => { + console.log('Client sending message: ', message); + Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom }); + //DocServer._socket.emit('message', message); + } - // otherPeer.addIceCandidate(newIceCandidate).then(() => { - // this.handleConnectionSuccess(peerConnection); - // }).catch((error: any) => { - // this.handleConnectionFailure(peerConnection, error); - // }); - // this.trace(`${this.getPeerName(peerConnection)} ICE candidate:\n` + - // `${event.candidate.candidate}.`); - // } - // } - // // Logs that the connection succeeded. - // handleConnectionSuccess = (peerConnection: any) => { - // this.trace(`${this.getPeerName(peerConnection)} addIceCandidate success.`); - // } - // handleConnectionFailure = (peerConnection: any, error: any) => { - // this.trace(`${this.getPeerName(peerConnection)} failed to add ICE Candidate:\n` + - // `${error.toString()}.`); + // setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) { + // this.localVideo = localVideo; + // this.remoteVideo = remoteVideo; // } - // // Logs changes to the connection state. - // handleConnectionChange = (event: any) => { - // let peerConnection = event.target; - // console.log('ICE state change event: ', event); - // this.trace(`${this.getPeerName(peerConnection)} ICE state: ` + - // `${peerConnection.iceConnectionState}.`); - // } + // setLocalVideoObject(localVideoRef: HTMLVideoElement) { + // this.localVideo = localVideoRef; - // // Logs error when setting session description fails. - // setSessionDescriptionError = (error: any) => { - // this.trace(`Failed to create session description: ${error.toString()}.`); // } - // // Logs success when setting session description. - // setDescriptionSuccess = (peerConnection: any, functionName: any) => { - // let peerName = this.getPeerName(peerConnection); - // this.trace(`${peerName} ${functionName} complete.`); + // setRemoteVideoObject(remoteVideoRef: HTMLVideoElement) { + // this.remoteVideo = remoteVideoRef; // } - // // Logs success when localDescription is set. - // setLocalDescriptionSuccess = (peerConnection: any) => { - // this.setDescriptionSuccess(peerConnection, 'setLocalDescription'); - // } - // // Logs success when remoteDescription is set. - // setRemoteDescriptionSuccess = (peerConnection: any) => { - // this.setDescriptionSuccess(peerConnection, 'setRemoteDescription'); - // } - // createdOffer = (description: any) => { - // this.trace(`Offer from localPeerConnection:\n${description.sdp}`); - // this.trace('localPeerConnection setLocalDescription start.'); + private gotStream = (stream: any) => { + console.log('Adding local stream.'); + this.localStream = stream; + this.localVideoEl!.srcObject = stream; + this.sendMessage('got user media'); + if (this.isInitiator) { + this.maybeStart(); + } + } - // this.localPeerConnection.setLocalDescription(description).then(() => { - // this.setLocalDescriptionSuccess(this.localPeerConnection); - // }).catch(this.setSessionDescriptionError); + constraints = { + video: true, + audio: true + }; - // this.trace('remotePeerConnection setRemoteDescription start.'); - // this.remotePeerConnection.setRemoteDescription(description) - // .then(() => { - // this.setRemoteDescriptionSuccess(this.remotePeerConnection); - // }).catch(this.setSessionDescriptionError); - // this.trace('remotePeerConnection createAnswer start.'); - // this.remotePeerConnection.createAnswer() - // .then(this.createdAnswer) - // .catch(this.setSessionDescriptionError); - // } - // createdAnswer = (description: any) => { - // this.trace(`Answer from remotePeerConnection:\n${description.sdp}.`); + private maybeStart = () => { + console.log('>>>>>>> maybeStart() ', this.isStarted, this.localStream, this.isChannelReady); + if (!this.isStarted && typeof this.localStream !== 'undefined' && this.isChannelReady) { + console.log('>>>>>> creating peer connection'); + this.createPeerConnection(); + this.pc.addStream(this.localStream); + this.isStarted = true; + console.log('isInitiator', this.isInitiator); + if (this.isInitiator) { + this.doCall(); + } + } + } - // this.trace('remotePeerConnection setLocalDescription start.'); - // this.remotePeerConnection.setLocalDescription(description) - // .then(() => { - // this.setLocalDescriptionSuccess(this.remotePeerConnection); - // }).catch(this.setSessionDescriptionError); - // this.trace('localPeerConnection setRemoteDescription start.'); - // this.localPeerConnection.setRemoteDescription(description) - // .then(() => { - // this.setRemoteDescriptionSuccess(this.localPeerConnection); - // }).catch(this.setSessionDescriptionError); - // } + // //this will need to be changed to our version of hangUp + // window.onbeforeunload = function () { + // sendMessage('bye'); + // }; + + private createPeerConnection = () => { + try { + this.pc = new RTCPeerConnection(undefined); + this.pc.onicecandidate = this.handleIceCandidate; + this.pc.onaddstream = this.handleRemoteStreamAdded; + this.pc.onremovestream = this.handleRemoteStreamRemoved; + console.log('Created RTCPeerConnnection'); + } catch (e) { + console.log('Failed to create PeerConnection, exception: ' + e.message); + alert('Cannot create RTCPeerConnection object.'); + return; + } + } + private handleIceCandidate = (event: any) => { + console.log('icecandidate event: ', event); + if (event.candidate) { + this.sendMessage({ + type: 'candidate', + label: event.candidate.sdpMLineIndex, + id: event.candidate.sdpMid, + candidate: event.candidate.candidate + }); + } else { + console.log('End of candidates.'); + } + } - // startAction = () => { - // this.startButton!.disabled = true; - // navigator.mediaDevices.getUserMedia(mediaStreamConstraints) - // .then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError); - // this.trace('Requesting local stream.'); - // } + private handleCreateOfferError = (event: any) => { + console.log('createOffer() error: ', event); + } + private doCall = () => { + console.log('Sending offer to peer'); + this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError); + } - // // Handles call button action: creates peer connection. - // callAction = () => { - // this.callButton!.disabled = true; - // this.hangupButton!.disabled = false; + private doAnswer = () => { + console.log('Sending answer to peer.'); + this.pc.createAnswer().then( + this.setLocalAndSendMessage, + this.onCreateSessionDescriptionError + ); + } - // this.trace('Starting call.'); - // this.startTime = window.performance.now(); + private setLocalAndSendMessage = (sessionDescription: any) => { + this.pc.setLocalDescription(sessionDescription); + console.log('setLocalAndSendMessage sending message', sessionDescription); + this.sendMessage(sessionDescription); + } - // // Get local media stream tracks. - // const videoTracks = this.localStream!.getVideoTracks(); - // const audioTracks = this.localStream!.getAudioTracks(); - // if (videoTracks.length > 0) { - // this.trace(`Using video device: ${videoTracks[0].label}.`); - // } - // if (audioTracks.length > 0) { - // this.trace(`Using audio device: ${audioTracks[0].label}.`); - // } + private onCreateSessionDescriptionError = (error: any) => { + console.log('Failed to create session description: ' + error.toString()); + } - // let servers: RTCConfiguration | undefined = undefined; // Allows for RTC server configuration. - // // Create peer connections and add behavior. - // this.localPeerConnection = new RTCPeerConnection(servers); - // this.trace('Created local peer connection object localPeerConnection.'); + private requestTurn = (turnURL: any) => { + var turnExists = false; + let self = this; + for (var i in this.pcConfig.iceServers) { + if (this.pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') { + turnExists = true; + this.turnReady = true; + break; + } + } + if (!turnExists) { + console.log('Getting TURN server from ', turnURL); + // No TURN server. Get one from computeengineondemand.appspot.com: + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4 && xhr.status === 200) { + var turnServer = JSON.parse(xhr.responseText); + console.log('Got TURN server: ', turnServer); + self.pcConfig.iceServers.push({ + 'urls': 'turn:' + turnServer.username + '@' + turnServer.turn, + //'credential': turnServer.password + }); + self.turnReady = true; + } + }; + xhr.open('GET', turnURL, true); + xhr.send(); + } + } - // this.localPeerConnection.addEventListener('icecandidate', this.handleConnection); - // this.localPeerConnection.addEventListener( - // 'iceconnectionstatechange', this.handleConnectionChange); + private handleRemoteStreamAdded = (event: MediaStreamEvent) => { + console.log('Remote stream added.'); + this.remoteStream = event.stream!; + this.peerVideoEl!.srcObject = this.remoteStream; + } - // this.remotePeerConnection = new RTCPeerConnection(servers); - // this.trace('Created remote peer connection object remotePeerConnection.'); + private handleRemoteStreamRemoved = (event: MediaStreamEvent) => { + console.log('Remote stream removed. Event: ', event); + } - // this.remotePeerConnection.addEventListener('icecandidate', this.handleConnection); - // this.remotePeerConnection.addEventListener( - // 'iceconnectionstatechange', this.handleConnectionChange); - // this.remotePeerConnection.addEventListener('addstream', this.gotRemoteMediaStream); + private hangup = () => { + console.log('Hanging up.'); + if (this.pc) { + stop(); + this.sendMessage('bye'); + } - // // Add local stream to connection and create offer to connect. - // this.localPeerConnection.addStream(this.localStream); - // this.trace('Added local stream to localPeerConnection.'); + if (this.localStream) { + this.localStream.getTracks().forEach(track => track.stop()); + } - // this.trace('localPeerConnection createOffer start.'); - // this.localPeerConnection.createOffer(offerOptions) - // .then(this.createdOffer).catch(this.setSessionDescriptionError); - // } + } + private handleRemoteHangup = () => { + console.log('Session terminated.'); + stop(); + this.isInitiator = false; + } - // // Handles hangup action: ends up call, closes connections and resets peers. - // hangupAction = () => { - // this.localPeerConnection.close(); - // this.remotePeerConnection.close(); - // this.localPeerConnection = null; - // this.remotePeerConnection = null; - // this.hangupButton!.disabled = true; - // this.callButton!.disabled = false; - // this.trace('Ending call.'); - // } + private stop = () => { + this.isStarted = false; + this.pc.close(); + this.pc = null; + } - // // Gets the "other" peer connection. - // getOtherPeer = (peerConnection: any) => { - // return (peerConnection === this.localPeerConnection) ? - // this.remotePeerConnection : this.localPeerConnection; - // } - // // Gets the name of a certain peer connection. - // getPeerName = (peerConnection: any) => { - // return (peerConnection === this.localPeerConnection) ? - // 'localPeerConnection' : 'remotePeerConnection'; - // } - // // Logs an action (text) and the time when it happened on the console. - // trace = (text: string) => { - // text = text.trim(); - // const now = (window.performance.now() / 1000).toFixed(3); - // console.log(now, text); - // } /** * Function that submits the title entered by user on enter press. */ - onEnterKeyDown = (e: React.KeyboardEvent) => { + private onEnterKeyDown = (e: React.KeyboardEvent) => { if (e.keyCode === 13) { let submittedTitle = this.roomText!.value; this.roomText!.value = ""; this.roomText!.blur(); this.roomOfCam = submittedTitle; - this.webRTCManager!.init(submittedTitle); + this.init(submittedTitle); } } - - - - - - - - - - - - - - - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebRTCVideo, fieldKey); } @@ -365,11 +394,11 @@ export class DashWebRTCVideo extends React.Component<CollectionFreeFormDocumentV <input type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} /> <video id="localVideo" autoPlay playsInline ref={(e) => { this.localVideoEl = e!; - this.webRTCManager!.setLocalVideoObject(e!); + //this.setLocalVideoObject(e!); }}></video> <video id="remoteVideo" autoPlay playsInline ref={(e) => { this.peerVideoEl = e!; - this.webRTCManager!.setRemoteVideoObject(e!); + //this.setRemoteVideoObject(e!); }}></video> {/* <button id="startButton" ref={(e) => this.startButton = e!} onClick={this.startAction}>Start</button> <button id="callButton" ref={(e) => this.callButton = e!} onClick={this.callAction}>Call</button> diff --git a/src/server/index.ts b/src/server/index.ts index 2b18fc578..72ddb5bd7 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -86,51 +86,7 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }: secureHandler: ({ res }) => res.redirect("/home") }); - // Utils.AddServerHandler(socket, MessageStore.NotifyRoommates, message => HandleRoommateNotification(socket, message)); - // // Utils.AddServerHandler(socket, MessageStore.HangUpCall, message => HandleHangUp(socket, message)); - // // Utils.AddRoomHandler(socket, "create or join", HandleCreateOrJoin); - // function HandleRoommateNotification(socket: Socket, message: RoomMessage) { - // //socket.broadcast.emit('message', message); - // console.log("The room that sent this: ", message.room, " and message is : ", message.message); - // server.sockets.in(message.room).emit('message', message); - - // } - - // function HandleCreateOrJoin(socket: io.Socket, room: string) { - // console.log("Received request to create or join room " + room); - - - // let clientsInRoom = server.sockets.adapter.rooms[room]; - // let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0; - // console.log('Room ' + room + ' now has ' + numClients + ' client(s)'); - - - // if (numClients === 0) { - // socket.join(room); - // console.log('Client ID ' + socket.id + ' created room ' + room); - // socket.emit('created', room, socket.id); - - // } else if (numClients === 1) { - // console.log('Client ID ' + socket.id + ' joined room ' + room); - // server.sockets.in(room).emit('join', room); - // socket.join(room); - // socket.emit('joined', room, socket.id); - // server.sockets.in(room).emit('ready'); - - // } else { - // socket.emit('full', room); - // } - - - - - - // } - - // function HandleHangUp(socket: io.Socket, message: string) { - // console.log("Receive bye from someone"); - // } addSupervisedRoute({ method: Method.GET, subscription: "/serverHeartbeat", @@ -165,6 +121,52 @@ function routeSetter({ isRelease, addSupervisedRoute, logRegistrationOutcome }: WebSocket.start(isRelease); } +// Utils.AddServerHandler(socket, MessageStore.NotifyRoommates, message => HandleRoommateNotification(socket, message)); +// // Utils.AddServerHandler(socket, MessageStore.HangUpCall, message => HandleHangUp(socket, message)); +// // Utils.AddRoomHandler(socket, "create or join", HandleCreateOrJoin); + +// function HandleRoommateNotification(socket: Socket, message: RoomMessage) { +// //socket.broadcast.emit('message', message); +// console.log("The room that sent this: ", message.room, " and message is : ", message.message); +// server.sockets.in(message.room).emit('message', message); + +// } + +// function HandleCreateOrJoin(socket: io.Socket, room: string) { +// console.log("Received request to create or join room " + room); + + +// let clientsInRoom = server.sockets.adapter.rooms[room]; +// let numClients = clientsInRoom ? Object.keys(clientsInRoom.sockets).length : 0; +// console.log('Room ' + room + ' now has ' + numClients + ' client(s)'); + + +// if (numClients === 0) { +// socket.join(room); +// console.log('Client ID ' + socket.id + ' created room ' + room); +// socket.emit('created', room, socket.id); + +// } else if (numClients === 1) { +// console.log('Client ID ' + socket.id + ' joined room ' + room); +// server.sockets.in(room).emit('join', room); +// socket.join(room); +// socket.emit('joined', room, socket.id); +// server.sockets.in(room).emit('ready'); + +// } else { +// socket.emit('full', room); +// } + + + + + +// } + +// function HandleHangUp(socket: io.Socket, message: string) { +// console.log("Receive bye from someone"); +// } + /** * This function can be used in two different ways. If not in release mode, * this is simply the logic that is invoked to start the server. In release mode, |