From ee03fa6e04dd9dba3099f75154de6ffab566ff5c Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Fri, 13 Sep 2019 16:43:09 -0400 Subject: Trial 5(Most succesful yet) --- src/client/documents/DocumentTypes.ts | 1 + src/client/documents/Documents.ts | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/client/documents') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 381981e1b..4430ffd62 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -17,6 +17,7 @@ export enum DocumentType { TEMPLATE = "template", EXTENSION = "extension", YOUTUBE = "youtube", + WEBCAM = "webcam", DRAGBOX = "dragbox", PRES = "presentation", LINKFOLLOW = "linkfollow", diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 602a7f9ad..036cc75a0 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -22,7 +22,7 @@ import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; import { IconBox } from "../views/nodes/IconBox"; import { Field, Doc, Opt } from "../../new_fields/Doc"; import { OmitKeys, JSONUtils } from "../../Utils"; -import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField } from "../../new_fields/URLField"; +import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField, WebCamField } from "../../new_fields/URLField"; import { HtmlField } from "../../new_fields/HtmlField"; import { List } from "../../new_fields/List"; import { Cast, NumCast } from "../../new_fields/Types"; @@ -46,6 +46,7 @@ import { ComputedField } from "../../new_fields/ScriptField"; import { ProxyField } from "../../new_fields/Proxy"; import { DocumentType } from "./DocumentTypes"; import { LinkFollowBox } from "../views/linking/LinkFollowBox"; +import { DashWebCam } from "../views/webcam/DashWebCam"; //import { PresBox } from "../views/nodes/PresBox"; //import { PresField } from "../../new_fields/PresField"; var requestImageSize = require('../util/request-image-size'); @@ -176,6 +177,9 @@ export namespace Docs { }], [DocumentType.LINKFOLLOW, { layout: { view: LinkFollowBox } + }], + [DocumentType.WEBCAM, { + layout: { view: DashWebCam } }] ]); @@ -357,6 +361,10 @@ export namespace Docs { return InstanceFromProto(Prototypes.get(DocumentType.YOUTUBE), new YoutubeField(new URL(url)), options); } + export function WebCamDocument(url: string, options: DocumentOptions = {}) { + return InstanceFromProto(Prototypes.get(DocumentType.WEBCAM), "", options); + } + export function AudioDocument(url: string, options: DocumentOptions = {}) { return InstanceFromProto(Prototypes.get(DocumentType.AUDIO), new AudioField(new URL(url)), options); } -- cgit v1.2.3-70-g09d2 From 45b9f489033cd323614463ca9c36f41900bf1965 Mon Sep 17 00:00:00 2001 From: andrewdkim Date: Tue, 1 Oct 2019 18:14:04 -0400 Subject: trials 2 --- package.json | 1 + src/client/documents/Documents.ts | 3 ++- src/client/views/nodes/DocumentContentsView.tsx | 3 ++- src/client/views/webcam/DashWebRTC.tsx | 9 +++++++-- 4 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/client/documents') diff --git a/package.json b/package.json index d0718345f..7ae8c3399 100644 --- a/package.json +++ b/package.json @@ -216,6 +216,7 @@ "typescript-collections": "^1.3.2", "url-loader": "^1.1.2", "uuid": "^3.3.2", + "webrtc-adapter": "^7.3.0", "words-to-numbers": "^1.5.1", "xoauth2": "^1.2.0", "youtube": "^0.1.0" diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 036cc75a0..1f9b575a4 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -47,6 +47,7 @@ import { ProxyField } from "../../new_fields/Proxy"; import { DocumentType } from "./DocumentTypes"; import { LinkFollowBox } from "../views/linking/LinkFollowBox"; import { DashWebCam } from "../views/webcam/DashWebCam"; +import { DashWebRTC } from "../views/webcam/DashWebRTC"; //import { PresBox } from "../views/nodes/PresBox"; //import { PresField } from "../../new_fields/PresField"; var requestImageSize = require('../util/request-image-size'); @@ -179,7 +180,7 @@ export namespace Docs { layout: { view: LinkFollowBox } }], [DocumentType.WEBCAM, { - layout: { view: DashWebCam } + layout: { view: DashWebRTC } }] ]); diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index df5ff04dd..2b797eeca 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -33,6 +33,7 @@ import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox"; import { ScriptField } from "../../../new_fields/ScriptField"; import { fromPromise } from "mobx-utils"; import { DashWebCam } from "../../views/webcam/DashWebCam"; +import { DashWebRTC } from "../webcam/DashWebRTC"; const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? @@ -112,7 +113,7 @@ export class DocumentContentsView extends React.Component - + + + + + ; let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting; @@ -77,7 +83,6 @@ export class DashWebRTC extends React.Component {!frozen ? (null) :
} ); - ); } -- cgit v1.2.3-70-g09d2 From a8f14c501cf676f6a2697b73d7f2a162d4100a9e Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Wed, 2 Oct 2019 16:52:57 -0400 Subject: Merge conflicts fixed --- src/client/documents/Documents.ts | 16 +- src/client/views/MainView.tsx | 4 - src/client/views/nodes/DocumentContentsView.tsx | 16 +- src/client/views/webcam/DashWebRTC.tsx | 225 ++++++++++++++++++++++-- 4 files changed, 214 insertions(+), 47 deletions(-) (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 3482033d5..6bd91c3b9 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -20,12 +20,8 @@ import { AggregateFunction } from "../northstar/model/idea/idea"; import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; import { IconBox } from "../views/nodes/IconBox"; import { OmitKeys, JSONUtils } from "../../Utils"; -<<<<<<< HEAD -import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField, WebCamField } from "../../new_fields/URLField"; -======= import { Field, Doc, Opt, DocListCastAsync } from "../../new_fields/Doc"; -import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField } from "../../new_fields/URLField"; ->>>>>>> 69e4a936c4eb0cc2e35e4e7f3258aed1f72b8da7 +import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField, WebCamField } from "../../new_fields/URLField"; import { HtmlField } from "../../new_fields/HtmlField"; import { List } from "../../new_fields/List"; import { Cast, NumCast } from "../../new_fields/Types"; @@ -49,14 +45,9 @@ import { ComputedField } from "../../new_fields/ScriptField"; import { ProxyField } from "../../new_fields/Proxy"; import { DocumentType } from "./DocumentTypes"; import { LinkFollowBox } from "../views/linking/LinkFollowBox"; -<<<<<<< HEAD import { DashWebCam } from "../views/webcam/DashWebCam"; import { DashWebRTC } from "../views/webcam/DashWebRTC"; -//import { PresBox } from "../views/nodes/PresBox"; -//import { PresField } from "../../new_fields/PresField"; -======= import { PresElementBox } from "../views/presentationview/PresElementBox"; ->>>>>>> 69e4a936c4eb0cc2e35e4e7f3258aed1f72b8da7 var requestImageSize = require('../util/request-image-size'); var path = require('path'); @@ -186,15 +177,12 @@ export namespace Docs { [DocumentType.LINKFOLLOW, { layout: { view: LinkFollowBox } }], -<<<<<<< HEAD [DocumentType.WEBCAM, { layout: { view: DashWebRTC } - }] -======= + }], [DocumentType.PRESELEMENT, { layout: { view: PresElementBox } }], ->>>>>>> 69e4a936c4eb0cc2e35e4e7f3258aed1f72b8da7 ]); // All document prototypes are initialized with at least these values diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 22d8171c0..7e2b4fa3a 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -1,9 +1,5 @@ import { IconName, library } from '@fortawesome/fontawesome-svg-core'; -<<<<<<< HEAD import { faLink, faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faClone, faCloudUploadAlt, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, faMusic, faObjectGroup, faPause, faPenNib, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faUndoAlt, faTv, faVideo } from '@fortawesome/free-solid-svg-icons'; -======= -import { faArrowDown, faArrowUp, faBolt, faCaretUp, faCat, faCheck, faClone, faCloudUploadAlt, faCommentAlt, faCut, faExclamation, faFilePdf, faFilm, faFont, faGlobeAsia, faLongArrowAltRight, faMusic, faObjectGroup, faPause, faPenNib, faPlay, faPortrait, faRedoAlt, faThumbtack, faTree, faTv, faUndoAlt } from '@fortawesome/free-solid-svg-icons'; ->>>>>>> 69e4a936c4eb0cc2e35e4e7f3258aed1f72b8da7 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { action, computed, configure, observable, reaction, runInAction } from 'mobx'; import { observer } from 'mobx-react'; diff --git a/src/client/views/nodes/DocumentContentsView.tsx b/src/client/views/nodes/DocumentContentsView.tsx index f1c10f2f2..f1678d4f9 100644 --- a/src/client/views/nodes/DocumentContentsView.tsx +++ b/src/client/views/nodes/DocumentContentsView.tsx @@ -30,20 +30,12 @@ import { PresElementBox } from "../presentationview/PresElementBox"; import { VideoBox } from "./VideoBox"; import { WebBox } from "./WebBox"; import React = require("react"); -<<<<<<< HEAD -import { FieldViewProps } from "./FieldView"; -import { Without, OmitKeys } from "../../../Utils"; -import { Cast, StrCast, NumCast } from "../../../new_fields/Types"; +import { StrCast, NumCast } from "../../../new_fields/Types"; import { List } from "../../../new_fields/List"; -import { Doc } from "../../../new_fields/Doc"; -import DirectoryImportBox from "../../util/Import & Export/DirectoryImportBox"; -import { ScriptField } from "../../../new_fields/ScriptField"; import { fromPromise } from "mobx-utils"; import { DashWebCam } from "../../views/webcam/DashWebCam"; import { DashWebRTC } from "../webcam/DashWebRTC"; -======= ->>>>>>> 69e4a936c4eb0cc2e35e4e7f3258aed1f72b8da7 const JsxParser = require('react-jsx-parser').default; //TODO Why does this need to be imported like this? type BindingProps = Without; @@ -115,11 +107,7 @@ export class DocumentContentsView extends React.Component>>>>>> 69e4a936c4eb0cc2e35e4e7f3258aed1f72b8da7 + components={{ FormattedTextBox, ImageBox, IconBox, DirectoryImportBox, DragBox, ButtonBox, FieldView, CollectionFreeFormView, CollectionDockingView, CollectionSchemaView, CollectionView, CollectionPDFView, CollectionVideoView, WebBox, KeyValueBox, PDFBox, VideoBox, AudioBox, HistogramBox, PresBox, YoutubeBox, LinkFollowBox, PresElementBox, DashWebCam, DashWebRTC }} bindings={this.CreateBindings()} jsx={this.finalLayout} showWarnings={true} diff --git a/src/client/views/webcam/DashWebRTC.tsx b/src/client/views/webcam/DashWebRTC.tsx index 9c289b40f..64ddb318f 100644 --- a/src/client/views/webcam/DashWebRTC.tsx +++ b/src/client/views/webcam/DashWebRTC.tsx @@ -2,7 +2,7 @@ import { observer } from "mobx-react"; import React = require("react"); import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView"; import { FieldViewProps, FieldView } from "../nodes/FieldView"; -import { observable, trace } from "mobx"; +import { observable } from "mobx"; import { DocumentDecorations } from "../DocumentDecorations"; import { InkingControl } from "../InkingControl"; import "../../views/nodes/WebBox.scss"; @@ -11,7 +11,7 @@ import adapter from 'webrtc-adapter'; -const mediaStreamConstaints = { +const mediaStreamConstraints = { video: true, }; @@ -26,7 +26,7 @@ export class DashWebRTC extends React.Component { //console.log("navigator.getUserMedia error: ", error); - trace(`navigator.getUserMedia error: ${error.toString()}.`); + this.trace(`navigator.getUserMedia error: ${error.toString()}.`); } - logVideoLoaded(event: any) { + logVideoLoaded = (event: any) => { let video = event.target; - trace(`${video!.id} videoWidth: ${video!.videoWidth}px, ` + - `videoHeight: ${video!.videoHeight}px.`); + this.trace(`${video.id} videoWidth: ${video.videoWidth}px, ` + + `videoHeight: ${video.videoHeight}px.`); } - logResizedVideo(event: any) { + logResizedVideo = (event: any) => { this.logVideoLoaded(event); if (this.startTime) { - let elapsedTime = window.performance.now() - this.startTime!; + let elapsedTime = window.performance.now() - this.startTime; this.startTime = null; - trace(`Setup time: ${elapsedTime.toFixed(3)}ms.`); + 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); + + 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()}.`); + } + + // 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}.`); + } + + // 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.`); + } + + + // 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.'); + + this.localPeerConnection.setLocalDescription(description).then(() => { + this.setLocalDescriptionSuccess(this.localPeerConnection); + }).catch(this.setSessionDescriptionError); + + + 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}.`); + + 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); + } + + + startAction = () => { + this.startButton!.disabled = true; + navigator.mediaDevices.getUserMedia(mediaStreamConstraints) + .then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError); + this.trace('Requesting local stream.'); + } + + + // Handles call button action: creates peer connection. + callAction = () => { + this.callButton!.disabled = true; + this.hangupButton!.disabled = false; + + this.trace('Starting call.'); + this.startTime = window.performance.now(); + + // 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}.`); + } + + 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.'); + + this.localPeerConnection.addEventListener('icecandidate', this.handleConnection); + this.localPeerConnection.addEventListener( + 'iceconnectionstatechange', this.handleConnectionChange); + + this.remotePeerConnection = new RTCPeerConnection(servers); + this.trace('Created remote peer connection object remotePeerConnection.'); + + this.remotePeerConnection.addEventListener('icecandidate', this.handleConnection); + this.remotePeerConnection.addEventListener( + 'iceconnectionstatechange', this.handleConnectionChange); + this.remotePeerConnection.addEventListener('addstream', this.gotRemoteMediaStream); + + // Add local stream to connection and create offer to connect. + this.localPeerConnection.addStream(this.localStream); + this.trace('Added local stream to localPeerConnection.'); + + this.trace('localPeerConnection createOffer start.'); + this.localPeerConnection.createOffer(offerOptions) + .then(this.createdOffer).catch(this.setSessionDescriptionError); + } + + + // 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.'); + } + + // 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); + } + + + + + + + + + + + + @@ -116,9 +311,9 @@ export class DashWebRTC extends React.Component - - - + + +
; let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting; -- cgit v1.2.3-70-g09d2 From 6dab9e4067b2763d23e41085b263fed811d71a86 Mon Sep 17 00:00:00 2001 From: kimdahey Date: Wed, 2 Oct 2019 17:31:25 -0400 Subject: Unused field removed --- src/client/documents/Documents.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 90028fc43..8b3c03866 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -21,7 +21,7 @@ import { MINIMIZED_ICON_SIZE } from "../views/globalCssVariables.scss"; import { IconBox } from "../views/nodes/IconBox"; import { OmitKeys, JSONUtils } from "../../Utils"; import { Field, Doc, Opt, DocListCastAsync } from "../../new_fields/Doc"; -import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField, WebCamField } from "../../new_fields/URLField"; +import { ImageField, VideoField, AudioField, PdfField, WebField, YoutubeField } from "../../new_fields/URLField"; import { HtmlField } from "../../new_fields/HtmlField"; import { List } from "../../new_fields/List"; import { Cast, NumCast } from "../../new_fields/Types"; -- cgit v1.2.3-70-g09d2 From 9c7521a36f67b3a69ac40f8a55e66638ed96bf04 Mon Sep 17 00:00:00 2001 From: Mohammad Amoush Date: Tue, 29 Oct 2019 18:29:57 -0400 Subject: Client Side Namespace --- src/client/DocServer.ts | 2 +- src/client/documents/Documents.ts | 4 +- src/client/views/webcam/DashWebRTC.ts | 306 +++++++++++++++++++++++++ src/client/views/webcam/DashWebRTC.tsx | 334 --------------------------- src/client/views/webcam/DashWebRTCVideo.tsx | 339 ++++++++++++++++++++++++++++ 5 files changed, 648 insertions(+), 337 deletions(-) create mode 100644 src/client/views/webcam/DashWebRTC.ts delete mode 100644 src/client/views/webcam/DashWebRTC.tsx create mode 100644 src/client/views/webcam/DashWebRTCVideo.tsx (limited to 'src/client/documents') diff --git a/src/client/DocServer.ts b/src/client/DocServer.ts index 2cec1046b..7ffb43684 100644 --- a/src/client/DocServer.ts +++ b/src/client/DocServer.ts @@ -21,7 +21,7 @@ import { Id, HandleUpdate } from '../new_fields/FieldSymbols'; */ export namespace DocServer { let _cache: { [id: string]: RefField | Promise> } = {}; - let _socket: SocketIOClient.Socket; + export let _socket: SocketIOClient.Socket; // this client's distinct GUID created at initialization let GUID: string; // indicates whether or not a document is currently being udpated, and, if so, its id diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index 8b3c03866..3df1e0e9a 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -46,8 +46,8 @@ import { ProxyField } from "../../new_fields/Proxy"; import { DocumentType } from "./DocumentTypes"; import { LinkFollowBox } from "../views/linking/LinkFollowBox"; import { DashWebCam } from "../views/webcam/DashWebCam"; -import { DashWebRTC } from "../views/webcam/DashWebRTC"; import { PresElementBox } from "../views/presentationview/PresElementBox"; +import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; var requestImageSize = require('../util/request-image-size'); var path = require('path'); @@ -178,7 +178,7 @@ export namespace Docs { layout: { view: LinkFollowBox } }], [DocumentType.WEBCAM, { - layout: { view: DashWebRTC } + layout: { view: DashWebRTCVideo } }], [DocumentType.PRESELEMENT, { layout: { view: PresElementBox } diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts new file mode 100644 index 000000000..4472f5ba5 --- /dev/null +++ b/src/client/views/webcam/DashWebRTC.ts @@ -0,0 +1,306 @@ +import { DocServer } from '../../DocServer'; + + + +export namespace DashWebRTC { + + + let isChannelReady = false; + let isInitiator = false; + let isStarted = false; + let localStream: MediaStream | undefined; + let pc: any; + let remoteStream: MediaStream | undefined; + let turnReady; + + let pcConfig = { + 'iceServers': [{ + 'urls': 'stun:stun.l.google.com:19302' + }] + }; + + // Set up audio and video regardless of what devices are present. + let sdpConstraints = { + offerToReceiveAudio: true, + offerToReceiveVideo: true + }; + + + let room = 'test'; + + //let socket = io.connect(); + + 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); + 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 + '!'); + isChannelReady = true; + }); + + + DocServer._socket.on('joined', function (room: string) { + console.log('joined: ' + room); + isChannelReady = true; + }); + + + DocServer._socket.on('log', function (array: any) { + console.log.apply(console, array); + }); + + + function sendMessage(message: any) { + console.log('Client sending message: ', message); + DocServer._socket.emit('message', message); + } + + + // This client receives a message + DocServer._socket.on('message', function (message: any) { + console.log('Client received message:', message); + if (message === 'got user media') { + maybeStart(); + } else if (message.type === 'offer') { + if (!isInitiator && !isStarted) { + maybeStart(); + } + pc.setRemoteDescription(new RTCSessionDescription(message)); + doAnswer(); + } else if (message.type === 'answer' && isStarted) { + pc.setRemoteDescription(new RTCSessionDescription(message)); + } else if (message.type === 'candidate' && isStarted) { + var candidate = new RTCIceCandidate({ + sdpMLineIndex: message.label, + candidate: message.candidate + }); + pc.addIceCandidate(candidate); + } else if (message === 'bye' && isStarted) { + handleRemoteHangup(); + } + }); + + let localVideo: HTMLVideoElement; + let remoteVideo: HTMLVideoElement; + + export function setVideoObjects(localVideo: HTMLVideoElement, remoteVideo: HTMLVideoElement) { + localVideo = localVideo; + remoteVideo = remoteVideo; + } + + navigator.mediaDevices.getUserMedia({ + audio: false, + video: true + }) + .then(gotStream) + .catch(function (e) { + alert('getUserMedia() error: ' + e.name); + }); + + + function gotStream(stream: any) { + console.log('Adding local stream.'); + localStream = stream; + localVideo.srcObject = stream; + sendMessage('got user media'); + if (isInitiator) { + maybeStart(); + } + } + + let constraints = { + video: true, + audio: true + }; + + + //Trying this one out!!! + console.log('Getting user media with constraints', constraints); + + if (location.hostname !== 'localhost') { + requestTurn( + 'https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913' + ); + } + + + function maybeStart() { + console.log('>>>>>>> maybeStart() ', isStarted, localStream, isChannelReady); + if (!isStarted && typeof localStream !== 'undefined' && isChannelReady) { + console.log('>>>>>> creating peer connection'); + createPeerConnection(); + pc.addStream(localStream); + isStarted = true; + console.log('isInitiator', isInitiator); + if (isInitiator) { + doCall(); + } + } + } + + + //this will need to be changed to our version of hangUp + window.onbeforeunload = function () { + sendMessage('bye'); + }; + + function createPeerConnection() { + try { + pc = new RTCPeerConnection(undefined); + pc.onicecandidate = handleIceCandidate; + pc.onaddstream = handleRemoteStreamAdded; + pc.onremovestream = handleRemoteStreamRemoved; + console.log('Created RTCPeerConnnection'); + } catch (e) { + console.log('Failed to create PeerConnection, exception: ' + e.message); + alert('Cannot create RTCPeerConnection object.'); + return; + } + } + + function handleIceCandidate(event: any) { + console.log('icecandidate event: ', event); + if (event.candidate) { + sendMessage({ + type: 'candidate', + label: event.candidate.sdpMLineIndex, + id: event.candidate.sdpMid, + candidate: event.candidate.candidate + }); + } else { + console.log('End of candidates.'); + } + } + + function handleCreateOfferError(event: any) { + console.log('createOffer() error: ', event); + } + + function doCall() { + console.log('Sending offer to peer'); + pc.createOffer(setLocalAndSendMessage, handleCreateOfferError); + } + + function doAnswer() { + console.log('Sending answer to peer.'); + pc.createAnswer().then( + setLocalAndSendMessage, + onCreateSessionDescriptionError + ); + } + + function setLocalAndSendMessage(sessionDescription: any) { + pc.setLocalDescription(sessionDescription); + console.log('setLocalAndSendMessage sending message', sessionDescription); + sendMessage(sessionDescription); + } + + function onCreateSessionDescriptionError(error: any) { + console.log('Failed to create session description: ' + error.toString()); + } + + + function requestTurn(turnURL: any) { + var turnExists = false; + for (var i in pcConfig.iceServers) { + if (pcConfig.iceServers[i].urls.substr(0, 5) === 'turn:') { + turnExists = true; + 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); + pcConfig.iceServers.push({ + 'urls': 'turn:' + turnServer.username + '@' + turnServer.turn, + //'credential': turnServer.password + }); + turnReady = true; + } + }; + xhr.open('GET', turnURL, true); + xhr.send(); + } + } + + function handleRemoteStreamAdded(event: MediaStreamEvent) { + console.log('Remote stream added.'); + remoteStream = event.stream!; + remoteVideo.srcObject = remoteStream; + } + + function handleRemoteStreamRemoved(event: MediaStreamEvent) { + console.log('Remote stream removed. Event: ', event); + } + + function hangup() { + console.log('Hanging up.'); + stop(); + sendMessage('bye'); + } + + function handleRemoteHangup() { + console.log('Session terminated.'); + stop(); + isInitiator = false; + } + + function stop() { + isStarted = false; + pc.close(); + pc = null; + } + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +} \ No newline at end of file diff --git a/src/client/views/webcam/DashWebRTC.tsx b/src/client/views/webcam/DashWebRTC.tsx deleted file mode 100644 index 9c93fb4cf..000000000 --- a/src/client/views/webcam/DashWebRTC.tsx +++ /dev/null @@ -1,334 +0,0 @@ -import { observer } from "mobx-react"; -import React = require("react"); -import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView"; -import { FieldViewProps, FieldView } from "../nodes/FieldView"; -import { observable } from "mobx"; -import { DocumentDecorations } from "../DocumentDecorations"; -import { InkingControl } from "../InkingControl"; -import "../../views/nodes/WebBox.scss"; -import "./DashWebRTC.scss" -import adapter from 'webrtc-adapter'; - - - - -const mediaStreamConstraints = { - video: true, -}; - -const offerOptions = { - offerToReceiveVideo: 1, -}; - - -@observer -export class DashWebRTC extends React.Component { - - @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; - - - 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!; - - } - - handleLocalMediaStreamError = (error: string) => { - //console.log("navigator.getUserMedia error: ", error); - this.trace(`navigator.getUserMedia error: ${error.toString()}.`); - - } - - 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); - - 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); - - 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()}.`); - } - - // 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}.`); - } - - // 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.`); - } - - - // 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.'); - - this.localPeerConnection.setLocalDescription(description).then(() => { - this.setLocalDescriptionSuccess(this.localPeerConnection); - }).catch(this.setSessionDescriptionError); - - - 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}.`); - - 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); - } - - - startAction = () => { - this.startButton!.disabled = true; - navigator.mediaDevices.getUserMedia(mediaStreamConstraints) - .then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError); - this.trace('Requesting local stream.'); - } - - - // Handles call button action: creates peer connection. - callAction = () => { - this.callButton!.disabled = true; - this.hangupButton!.disabled = false; - - this.trace('Starting call.'); - this.startTime = window.performance.now(); - - // 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}.`); - } - - 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.'); - - this.localPeerConnection.addEventListener('icecandidate', this.handleConnection); - this.localPeerConnection.addEventListener( - 'iceconnectionstatechange', this.handleConnectionChange); - - this.remotePeerConnection = new RTCPeerConnection(servers); - this.trace('Created remote peer connection object remotePeerConnection.'); - - this.remotePeerConnection.addEventListener('icecandidate', this.handleConnection); - this.remotePeerConnection.addEventListener( - 'iceconnectionstatechange', this.handleConnectionChange); - this.remotePeerConnection.addEventListener('addstream', this.gotRemoteMediaStream); - - // Add local stream to connection and create offer to connect. - this.localPeerConnection.addStream(this.localStream); - this.trace('Added local stream to localPeerConnection.'); - - this.trace('localPeerConnection createOffer start.'); - this.localPeerConnection.createOffer(offerOptions) - .then(this.createdOffer).catch(this.setSessionDescriptionError); - } - - - // 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.'); - } - - // 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); - } - - - - - - - - - - - - - - - - public static LayoutString() { return FieldView.LayoutString(DashWebRTC); } - - - _ignore = 0; - onPreWheel = (e: React.WheelEvent) => { - this._ignore = e.timeStamp; - } - onPrePointer = (e: React.PointerEvent) => { - this._ignore = e.timeStamp; - } - onPostPointer = (e: React.PointerEvent) => { - if (this._ignore !== e.timeStamp) { - e.stopPropagation(); - } - } - onPostWheel = (e: React.WheelEvent) => { - if (this._ignore !== e.timeStamp) { - e.stopPropagation(); - } - } - - - - render() { - let content = -
- - - - - -
; - - let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting; - let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : ""); - - - return ( - <> -
- {content} -
- {!frozen ? (null) :
} - ); - } - - -} \ No newline at end of file diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx new file mode 100644 index 000000000..db9c922fc --- /dev/null +++ b/src/client/views/webcam/DashWebRTCVideo.tsx @@ -0,0 +1,339 @@ +import { observer } from "mobx-react"; +import React = require("react"); +import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView"; +import { FieldViewProps, FieldView } from "../nodes/FieldView"; +import { observable } from "mobx"; +import { DocumentDecorations } from "../DocumentDecorations"; +import { InkingControl } from "../InkingControl"; +import "../../views/nodes/WebBox.scss"; +import "./DashWebRTC.scss"; +import adapter from 'webrtc-adapter'; +import { DashWebRTC } from "./DashWebRTC"; + + + + +const mediaStreamConstraints = { + video: true, +}; + +const offerOptions = { + offerToReceiveVideo: 1, +}; + + +@observer +export class DashWebRTCVideo extends React.Component { + + @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; + + componentDidMount() { + DashWebRTC.setVideoObjects(this.localVideoEl!, this.peerVideoEl!); + } + + + // 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!; + + // } + + // handleLocalMediaStreamError = (error: string) => { + // //console.log("navigator.getUserMedia error: ", error); + // this.trace(`navigator.getUserMedia error: ${error.toString()}.`); + + // } + + // 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); + + // 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); + + // 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()}.`); + // } + + // // 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}.`); + // } + + // // 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.`); + // } + + + // // 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.'); + + // this.localPeerConnection.setLocalDescription(description).then(() => { + // this.setLocalDescriptionSuccess(this.localPeerConnection); + // }).catch(this.setSessionDescriptionError); + + + // 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}.`); + + // 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); + // } + + + // startAction = () => { + // this.startButton!.disabled = true; + // navigator.mediaDevices.getUserMedia(mediaStreamConstraints) + // .then(this.gotLocalMediaStream).catch(this.handleLocalMediaStreamError); + // this.trace('Requesting local stream.'); + // } + + + // // Handles call button action: creates peer connection. + // callAction = () => { + // this.callButton!.disabled = true; + // this.hangupButton!.disabled = false; + + // this.trace('Starting call.'); + // this.startTime = window.performance.now(); + + // // 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}.`); + // } + + // 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.'); + + // this.localPeerConnection.addEventListener('icecandidate', this.handleConnection); + // this.localPeerConnection.addEventListener( + // 'iceconnectionstatechange', this.handleConnectionChange); + + // this.remotePeerConnection = new RTCPeerConnection(servers); + // this.trace('Created remote peer connection object remotePeerConnection.'); + + // this.remotePeerConnection.addEventListener('icecandidate', this.handleConnection); + // this.remotePeerConnection.addEventListener( + // 'iceconnectionstatechange', this.handleConnectionChange); + // this.remotePeerConnection.addEventListener('addstream', this.gotRemoteMediaStream); + + // // Add local stream to connection and create offer to connect. + // this.localPeerConnection.addStream(this.localStream); + // this.trace('Added local stream to localPeerConnection.'); + + // this.trace('localPeerConnection createOffer start.'); + // this.localPeerConnection.createOffer(offerOptions) + // .then(this.createdOffer).catch(this.setSessionDescriptionError); + // } + + + // // 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.'); + // } + + // // 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); + // } + + + + + + + + + + + + + + + + public static LayoutString() { return FieldView.LayoutString(DashWebRTCVideo); } + + + _ignore = 0; + onPreWheel = (e: React.WheelEvent) => { + this._ignore = e.timeStamp; + } + onPrePointer = (e: React.PointerEvent) => { + this._ignore = e.timeStamp; + } + onPostPointer = (e: React.PointerEvent) => { + if (this._ignore !== e.timeStamp) { + e.stopPropagation(); + } + } + onPostWheel = (e: React.WheelEvent) => { + if (this._ignore !== e.timeStamp) { + e.stopPropagation(); + } + } + + + + render() { + let content = +
+ + + {/* + + */} +
; + + let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting; + let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : ""); + + + return ( + <> +
+ {content} +
+ {!frozen ? (null) :
} + ); + } + + +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From 91f7f9a737092c2912c78fa0abb15b29298bcff1 Mon Sep 17 00:00:00 2001 From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com> Date: Sun, 9 Feb 2020 14:23:26 -0500 Subject: cleanup quick --- src/client/documents/DocumentTypes.ts | 1 - src/client/northstar/utils/Utils.ts | 6 ------ 2 files changed, 7 deletions(-) (limited to 'src/client/documents') diff --git a/src/client/documents/DocumentTypes.ts b/src/client/documents/DocumentTypes.ts index 46f27f958..df0a33821 100644 --- a/src/client/documents/DocumentTypes.ts +++ b/src/client/documents/DocumentTypes.ts @@ -18,7 +18,6 @@ export enum DocumentType { EXTENSION = "extension", YOUTUBE = "youtube", WEBCAM = "webcam", - DRAGBOX = "dragbox", FONTICON = "fonticonbox", PRES = "presentation", LINKFOLLOW = "linkfollow", diff --git a/src/client/northstar/utils/Utils.ts b/src/client/northstar/utils/Utils.ts index 09f83ce80..d071dec62 100644 --- a/src/client/northstar/utils/Utils.ts +++ b/src/client/northstar/utils/Utils.ts @@ -4,12 +4,6 @@ import { IBaseFilterProvider } from '../core/filter/IBaseFilterProvider'; import { AggregateFunction } from '../model/idea/idea'; export class Utils { - static Emit() { - throw new Error("Method not implemented."); - } - static EmitCallback() { - throw new Error("Method not implemented."); - } public static EqualityHelper(a: Object, b: Object): boolean { if (a === b) return true; -- cgit v1.2.3-70-g09d2 From dac1b07c4b5ed42d50531e66ea3a1561f62ed11e Mon Sep 17 00:00:00 2001 From: Mohammad Amoush <47069173+mamoush34@users.noreply.github.com> Date: Sun, 9 Feb 2020 14:33:51 -0500 Subject: CleanUp --- src/client/documents/Documents.ts | 1 - src/client/views/webcam/DashWebCam.tsx | 396 --------------------------- src/client/views/webcam/DashWebRTC.scss | 23 -- src/client/views/webcam/DashWebRTC.ts | 314 --------------------- src/client/views/webcam/DashWebRTCVideo.scss | 18 -- src/client/views/webcam/DashWebRTCVideo.tsx | 312 +-------------------- src/client/views/webcam/WebCamLogic.js | 6 - src/server/Message.ts | 2 - src/server/Websocket/Websocket.ts | 47 ---- 9 files changed, 1 insertion(+), 1118 deletions(-) delete mode 100644 src/client/views/webcam/DashWebCam.tsx delete mode 100644 src/client/views/webcam/DashWebRTC.scss delete mode 100644 src/client/views/webcam/DashWebRTC.ts (limited to 'src/client/documents') diff --git a/src/client/documents/Documents.ts b/src/client/documents/Documents.ts index ba0f69846..7233fbea5 100644 --- a/src/client/documents/Documents.ts +++ b/src/client/documents/Documents.ts @@ -44,7 +44,6 @@ import { ComputedField, ScriptField } from "../../new_fields/ScriptField"; import { ProxyField } from "../../new_fields/Proxy"; import { DocumentType } from "./DocumentTypes"; import { LinkFollowBox } from "../views/linking/LinkFollowBox"; -import { DashWebCam } from "../views/webcam/DashWebCam"; import { PresElementBox } from "../views/presentationview/PresElementBox"; import { DashWebRTCVideo } from "../views/webcam/DashWebRTCVideo"; import { QueryBox } from "../views/nodes/QueryBox"; diff --git a/src/client/views/webcam/DashWebCam.tsx b/src/client/views/webcam/DashWebCam.tsx deleted file mode 100644 index a9669750f..000000000 --- a/src/client/views/webcam/DashWebCam.tsx +++ /dev/null @@ -1,396 +0,0 @@ -import React = require("react"); -import { observer } from "mobx-react"; -import { FieldViewProps, FieldView } from "../nodes/FieldView"; -import { observable, action } from "mobx"; -import { DocumentDecorations } from "../DocumentDecorations"; -import { InkingControl } from "../InkingControl"; -import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView"; -import "../../views/nodes/WebBox.scss"; - - -//https://github.com/mozmorris/react-webcam is the source code used for the bigger part of this implementation. It's only modified to fit our current system. - - -function hasGetUserMedia() { - return !!( - (navigator.mediaDevices && navigator.mediaDevices.getUserMedia)); -} - -interface WebcamProps { - audio: boolean; - audioConstraints?: MediaStreamConstraints["audio"]; - imageSmoothing: boolean; - minScreenshotHeight?: number; - minScreenshotWidth?: number; - onUserMedia: () => void; - onUserMediaError: (error: string) => void; - screenshotFormat: "image/webp" | "image/png" | "image/jpeg"; - screenshotQuality: number; - videoConstraints?: MediaStreamConstraints["video"]; -} - -interface WebcamState { - hasUserMedia: boolean; - src?: string; -} - -@observer -export class DashWebCam extends React.Component & { - layoutKey: string, -}, WebcamState> { - static defaultProps = { - audio: true, - imageSmoothing: true, - onUserMedia: () => { }, - onUserMediaError: () => { }, - screenshotFormat: "image/webp", - screenshotQuality: 0.92 - }; - - private static mountedInstances: DashWebCam[] = []; - private static userMediaRequested = false; - private canvas: HTMLCanvasElement | undefined; - private ctx: CanvasRenderingContext2D | null = null; - private stream: MediaStream | undefined; - private video: HTMLVideoElement | null | undefined; - - // @observable private hasUserMedia: boolean | undefined; - // @observable private src: string | undefined; - - constructor(props: any) { - super(props); - this.state = { - hasUserMedia: false - }; - } - - componentDidMount() { - if (!hasGetUserMedia()) return; - - const { state } = this; - - DashWebCam.mountedInstances.push(this); - - if (!state.hasUserMedia && !DashWebCam.userMediaRequested) { - this.requestUserMedia(); - } - } - - componentDidUpdate(nextProps: WebcamProps) { - const { props } = this; - if ( - JSON.stringify(nextProps.audioConstraints) !== - JSON.stringify(props.audioConstraints) || - JSON.stringify(nextProps.videoConstraints) !== - JSON.stringify(props.videoConstraints) - ) { - this.requestUserMedia(); - } - } - - componentWillUnmount() { - const { state } = this; - const index = DashWebCam.mountedInstances.indexOf(this); - DashWebCam.mountedInstances.splice(index, 1); - - DashWebCam.userMediaRequested = false; - if (DashWebCam.mountedInstances.length === 0 && state.hasUserMedia) { - if (this.stream!.getVideoTracks && this.stream!.getAudioTracks) { - this.stream!.getVideoTracks().map(track => track.stop()); - this.stream!.getAudioTracks().map(track => track.stop()); - } else { - ((this.stream as unknown) as MediaStreamTrack).stop(); - } - - if (state.src) { - window.URL.revokeObjectURL(state.src); - } - } - } - - //These are for screenshot if wanted. - - // getScreenshot() { - // const { state, props } = this; - - // if (!state.hasUserMedia) return null; - - // const canvas = this.getCanvas(); - // return ( - // canvas && - // canvas.toDataURL(props.screenshotFormat, props.screenshotQuality) - // ); - // } - - // getCanvas() { - // const { state, props } = this; - - // if (!this.video) { - // return null; - // } - - // if (!state.hasUserMedia || !this.video.videoHeight) return null; - - // if (!this.ctx) { - // const canvas = document.createElement("canvas"); - // const aspectRatio = this.video.videoWidth / this.video.videoHeight; - - // let canvasWidth = props.minScreenshotWidth || this.video.clientWidth; - // let canvasHeight = canvasWidth / aspectRatio; - - // if ( - // props.minScreenshotHeight && - // canvasHeight < props.minScreenshotHeight - // ) { - // canvasHeight = props.minScreenshotHeight; - // canvasWidth = canvasHeight * aspectRatio; - // } - - // canvas.width = canvasWidth; - // canvas.height = canvasHeight; - - // this.canvas = canvas; - // this.ctx = canvas.getContext("2d"); - // } - - // const { ctx, canvas } = this; - - // if (ctx) { - // ctx.imageSmoothingEnabled = props.imageSmoothing; - // ctx.drawImage(this.video, 0, 0, canvas!.width, canvas!.height); - // } - - // return canvas; - // } - - requestUserMedia() { - const { props } = this; - - navigator.getUserMedia = - navigator.mediaDevices.getUserMedia; - - const sourceSelected = (audioConstraints: any, videoConstraints: any) => { - const constraints: MediaStreamConstraints = { - video: typeof videoConstraints !== "undefined" ? videoConstraints : true - }; - - if (props.audio) { - constraints.audio = - typeof audioConstraints !== "undefined" ? audioConstraints : true; - } - - navigator.mediaDevices - .getUserMedia(constraints) - .then(stream => { - DashWebCam.mountedInstances.forEach(instance => - instance.handleUserMedia(null, stream) - ); - }) - .catch(e => { - DashWebCam.mountedInstances.forEach(instance => - instance.handleUserMedia(e) - ); - }); - }; - - if ("mediaDevices" in navigator) { - sourceSelected(props.audioConstraints, props.videoConstraints); - } else { - const optionalSource = (id: any) => ({ optional: [{ sourceId: id }] }); - - const constraintToSourceId = (constraint: any) => { - const { deviceId } = constraint; - - if (typeof deviceId === "string") { - return deviceId; - } - - if (Array.isArray(deviceId) && deviceId.length > 0) { - return deviceId[0]; - } - - if (typeof deviceId === "object" && deviceId.ideal) { - return deviceId.ideal; - } - - return null; - }; - - // @ts-ignore: deprecated api - MediaStreamTrack.getSources(sources => { - let audioSource = null; - let videoSource = null; - - sources.forEach((source: { kind: string; id: any; }) => { - if (source.kind === "audio") { - audioSource = source.id; - } else if (source.kind === "video") { - videoSource = source.id; - } - }); - - const audioSourceId = constraintToSourceId(props.audioConstraints); - if (audioSourceId) { - audioSource = audioSourceId; - } - - const videoSourceId = constraintToSourceId(props.videoConstraints); - if (videoSourceId) { - videoSource = videoSourceId; - } - - sourceSelected( - optionalSource(audioSource), - optionalSource(videoSource) - ); - }); - } - - DashWebCam.userMediaRequested = true; - } - - handleUserMedia(err: string | null, stream?: MediaStream) { - const { props } = this; - - if (err || !stream) { - this.setState({ hasUserMedia: false }); - // action(() => this.hasUserMedia = false); - props.onUserMediaError(err!); - - return; - } - - this.stream = stream; - - console.log("Stream done: ", stream); - - try { - if (this.video) { - this.video.srcObject = stream; - console.log("Source object: ", stream); - - } - this.setState({ hasUserMedia: true }); - // action(() => this.hasUserMedia = true); - - } catch (error) { - this.setState({ - hasUserMedia: true, - src: window.URL.createObjectURL(stream) - }); - console.log("State src set: ", this.state.src); - - // action(() => this.hasUserMedia = true); - // action(() => this.src = window.URL.createObjectURL(stream)); - } - - props.onUserMedia(); - } - - _ignore = 0; - onPreWheel = (e: React.WheelEvent) => { - this._ignore = e.timeStamp; - } - onPrePointer = (e: React.PointerEvent) => { - this._ignore = e.timeStamp; - } - onPostPointer = (e: React.PointerEvent) => { - if (this._ignore !== e.timeStamp) { - e.stopPropagation(); - } - } - onPostWheel = (e: React.WheelEvent) => { - if (this._ignore !== e.timeStamp) { - e.stopPropagation(); - } - } - - - - - public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebCam, fieldKey); } - - render() { - const { state, props } = this; - - - - const { - audio, - onUserMedia, - onUserMediaError, - screenshotFormat, - screenshotQuality, - minScreenshotWidth, - minScreenshotHeight, - audioConstraints, - videoConstraints, - imageSmoothing, - fieldKey, - fitToBox, - ContainingCollectionView, - Document, - DataDoc, - onClick, - isSelected, - select, - renderDepth, - addDocument, - addDocTab, - pinToPres, - removeDocument, - moveDocument, - ScreenToLocalTransform, - active, - whenActiveChanged, - focus, - PanelWidth, - PanelHeight, - setVideoBox, - ContentScaling, - ChromeHeight, - jitterRotation, - backgroundColor, - bringToFront, - zoomToScale, - getScale, - animateBetweenIcon, - layoutKey, - ...rest - } = props; - - console.log("Source produced: ", state.src); - - - - let content = -
-
; - - - let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting; - let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : ""); - - return ( - <> -
- {content} -
- {!frozen ? (null) :
} - ); - - } -} \ No newline at end of file diff --git a/src/client/views/webcam/DashWebRTC.scss b/src/client/views/webcam/DashWebRTC.scss deleted file mode 100644 index ddf4777a8..000000000 --- a/src/client/views/webcam/DashWebRTC.scss +++ /dev/null @@ -1,23 +0,0 @@ -.webcam-cont { - button { - margin: 10px; - position: relative; - top: 20%; - left: -60%; - } - - #localVideo { - margin: 10px; - position: relative; - width: 300px; - max-height: 300px; - } - - #remoteVideo { - margin: 10px; - position: relative; - width: 300px; - max-height: 300px; - - } -} \ No newline at end of file diff --git a/src/client/views/webcam/DashWebRTC.ts b/src/client/views/webcam/DashWebRTC.ts deleted file mode 100644 index ef5ecf0fc..000000000 --- a/src/client/views/webcam/DashWebRTC.ts +++ /dev/null @@ -1,314 +0,0 @@ -// 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 -// }; -// } - - - -// init(room: string) { - -// this.curRoom = room; -// let self = this; - -// 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('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' -// ); -// } - - -// } - - -// 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.scss b/src/client/views/webcam/DashWebRTCVideo.scss index 052832db5..2f35eeca2 100644 --- a/src/client/views/webcam/DashWebRTCVideo.scss +++ b/src/client/views/webcam/DashWebRTCVideo.scss @@ -1,7 +1,6 @@ @import "../globalCssVariables"; .webcam-cont { - // position: absolute; background: whitesmoke; color: grey; border-radius: 15px; @@ -27,15 +26,6 @@ border: 1px solid #BBBBBBBB; } - // #localVideo { - // width: 50%; - // height: 50%; - // position: relative; - // // top: 65%; - // // z-index: 2; - // // right: 5%; - // } - .side { width: 25%; height: 20%; @@ -53,12 +43,4 @@ align-self: center; } - // #remoteVideo { - // position: relative; - // width: 50%; - // height: 50%; - // // top: 20%; - // // align-self: center; - // } - } \ No newline at end of file diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx index f93d4a662..0eefbbc91 100644 --- a/src/client/views/webcam/DashWebRTCVideo.tsx +++ b/src/client/views/webcam/DashWebRTCVideo.tsx @@ -8,60 +8,19 @@ import { InkingControl } from "../InkingControl"; import "../../views/nodes/WebBox.scss"; import "./DashWebRTCVideo.scss"; import adapter from 'webrtc-adapter'; -import { DocServer } from "../../DocServer"; -import { DocumentView } from "../nodes/DocumentView"; -import { Utils } from "../../../Utils"; -import { MessageStore } from "../../../server/Message"; import { initialize, hangup } from "./WebCamLogic"; -const mediaStreamConstraints = { - video: true, -}; - -const offerOptions = { - offerToReceiveVideo: 1, -}; - /** * This models the component that will be rendered, that can be used as a doc that will reflect the video cams. */ @observer export class DashWebRTCVideo extends React.Component { - @observable private localVideoEl: HTMLVideoElement | undefined; - @observable private peerVideoEl: HTMLVideoElement | undefined; + private roomText: HTMLInputElement | undefined; - // private roomOfCam: string = ""; - // private isChannelReady = false; - // private isInitiator = false; - // private isStarted = false; @observable remoteVideoAdded: boolean = 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); - // setTimeout(() => initialize(), 10000); - // let self = this; - // window.onbeforeunload = function () { - // self.sendMessage('bye'); - // }; } closeConnection: CloseCall = () => { @@ -73,273 +32,6 @@ export class DashWebRTCVideo extends React.Component { - // console.log('Client sending message: ', message); - // Utils.Emit(DocServer._socket, MessageStore.NotifyRoommates, { message: message, room: this.curRoom }); - // //DocServer._socket.emit('message', message); - // } - - - - // 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(); - // } - // } - - // constraints = { - // video: true, - // audio: true - // }; - - - - - - // 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 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.'); - // } - // } - - // private handleCreateOfferError = (event: any) => { - // console.log('createOffer() error: ', event); - // } - - // private doCall = () => { - // console.log('Sending offer to peer'); - // this.pc.createOffer(this.setLocalAndSendMessage, this.handleCreateOfferError); - // } - - // private doAnswer = () => { - // console.log('Sending answer to peer.'); - // this.pc.createAnswer().then( - // this.setLocalAndSendMessage, - // this.onCreateSessionDescriptionError - // ); - // } - - // private setLocalAndSendMessage = (sessionDescription: any) => { - // this.pc.setLocalDescription(sessionDescription); - // console.log('setLocalAndSendMessage sending message', sessionDescription); - // this.sendMessage(sessionDescription); - // } - - // private onCreateSessionDescriptionError = (error: any) => { - // console.log('Failed to create session description: ' + error.toString()); - // } - - - // 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(); - // } - // } - // @action - // private handleRemoteStreamAdded = (event: MediaStreamEvent) => { - // console.log('Remote stream added.'); - // this.remoteStream = event.stream!; - // this.peerVideoEl!.srcObject = this.remoteStream; - // this.remoteVideoAdded = true; - // } - - // private handleRemoteStreamRemoved = (event: MediaStreamEvent) => { - // console.log('Remote stream removed. Event: ', event); - // } - - // private hangup = () => { - // console.log('Hanging up.'); - // if (this.pc) { - // stop(); - // this.sendMessage('bye'); - // } - - // if (this.localStream) { - // this.localStream.getTracks().forEach(track => track.stop()); - // } - - // } - - // private handleRemoteHangup = () => { - // console.log('Session terminated.'); - // this.stop(); - // this.isInitiator = false; - - // if (this.localStream) { - // this.localStream.getTracks().forEach(track => track.stop()); - // } - - - // } - - // private stop = () => { - // this.isStarted = false; - // this.pc.close(); - // this.pc = null; - // } - - - - - - /** * Function that submits the title entered by user on enter press. */ @@ -379,10 +71,8 @@ export class DashWebRTCVideo extends React.ComponentDashWebRTC
this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
; diff --git a/src/client/views/webcam/WebCamLogic.js b/src/client/views/webcam/WebCamLogic.js index ec8b2e8bf..a7af9c2c4 100644 --- a/src/client/views/webcam/WebCamLogic.js +++ b/src/client/views/webcam/WebCamLogic.js @@ -28,8 +28,6 @@ export function initialize(roomName, handlerUI) { ///////////////////////////////////////////// room = roomName; - // Could prompt for room name: - // room = prompt('Enter room name:'); socket = io.connect(`${window.location.protocol}//${window.location.hostname}:${4321}`); @@ -94,10 +92,6 @@ export function initialize(roomName, handlerUI) { var localVideo = document.querySelector('#localVideo'); var remoteVideo = document.querySelector('#remoteVideo'); - - console.log("Local Video: ", localVideo); - console.log("Remote Video: ", remoteVideo); - const gotStream = (stream) => { console.log('Adding local stream.'); localStream = stream; diff --git a/src/server/Message.ts b/src/server/Message.ts index 6ce5cd96a..79b6fa1e0 100644 --- a/src/server/Message.ts +++ b/src/server/Message.ts @@ -64,8 +64,6 @@ export namespace MessageStore { export const YoutubeApiQuery = new Message("Youtube Api Query"); export const DeleteField = new Message("Delete field"); export const DeleteFields = new Message("Delete fields"); - export const NotifyRoommates = new Message("message"); - export const HangUpCall = new Message("bye"); } diff --git a/src/server/Websocket/Websocket.ts b/src/server/Websocket/Websocket.ts index b4cd2dbe2..ba7ca8f35 100644 --- a/src/server/Websocket/Websocket.ts +++ b/src/server/Websocket/Websocket.ts @@ -19,7 +19,6 @@ export namespace WebSocket { const clients: { [key: string]: Client } = {}; export const socketMap = new Map(); export let disconnect: Function; - let endpoint: io.Server; export async function start(isRelease: boolean) { @@ -107,9 +106,6 @@ export namespace WebSocket { Utils.AddServerHandler(socket, MessageStore.DeleteFields, ids => DeleteFields(socket, ids)); Utils.AddServerHandlerCallback(socket, MessageStore.GetRefField, GetRefField); Utils.AddServerHandlerCallback(socket, MessageStore.GetRefFields, GetRefFields); - //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); disconnect = () => { socket.broadcast.emit("connection_terminated", Date.now()); @@ -122,49 +118,6 @@ export namespace WebSocket { logPort("websocket", socketPort); } - - 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); - endpoint.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 = endpoint.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); - endpoint.sockets.in(room).emit('join', room); - socket.join(room); - socket.emit('joined', room, socket.id); - endpoint.sockets.in(room).emit('ready'); - - } else { - socket.emit('full', room); - } - - - - - - } - - function HandleHangUp(socket: io.Socket, message: string) { - console.log("Receive bye from someone"); - } - function HandleYoutubeQuery([query, callback]: [YoutubeQueryInput, (result?: any[]) => void]) { const { ProjectCredentials } = GoogleCredentialsLoader; switch (query.type) { -- cgit v1.2.3-70-g09d2