aboutsummaryrefslogtreecommitdiff
path: root/src/client/views/webcam/DashWebRTCVideo.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/views/webcam/DashWebRTCVideo.tsx')
-rw-r--r--src/client/views/webcam/DashWebRTCVideo.tsx404
1 files changed, 404 insertions, 0 deletions
diff --git a/src/client/views/webcam/DashWebRTCVideo.tsx b/src/client/views/webcam/DashWebRTCVideo.tsx
new file mode 100644
index 000000000..f93d4a662
--- /dev/null
+++ b/src/client/views/webcam/DashWebRTCVideo.tsx
@@ -0,0 +1,404 @@
+import { observer } from "mobx-react";
+import React = require("react");
+import { CollectionFreeFormDocumentViewProps } from "../nodes/CollectionFreeFormDocumentView";
+import { FieldViewProps, FieldView } from "../nodes/FieldView";
+import { observable, action } from "mobx";
+import { DocumentDecorations, CloseCall } from "../DocumentDecorations";
+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<CollectionFreeFormDocumentViewProps & FieldViewProps> {
+ @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 = () => {
+ hangup();
+ }
+
+ @action
+ changeUILook = () => {
+ this.remoteVideoAdded = true;
+ }
+
+ // componentWillUnmount() {
+ // }
+
+
+ // 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', async 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();
+ // }
+ // await self.pc.setRemoteDescription(new RTCSessionDescription(message.message));
+ // self.doAnswer();
+ // } else if (message.message.type === 'answer' && self.isStarted) {
+ // await 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.message === 'bye' && self.isStarted) {
+ // self.handleRemoteHangup();
+ // }
+ // });
+
+ // navigator.mediaDevices.getUserMedia({
+ // audio: true,
+ // 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'
+ // );
+ // }
+
+
+ // }
+
+
+ // 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);
+ // }
+
+
+
+ // 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.
+ */
+ private onEnterKeyDown = (e: React.KeyboardEvent) => {
+ if (e.keyCode === 13) {
+ let submittedTitle = this.roomText!.value;
+ this.roomText!.value = "";
+ this.roomText!.blur();
+ initialize(submittedTitle, this.changeUILook);
+ }
+ }
+
+
+ public static LayoutString(fieldKey: string) { return FieldView.LayoutString(DashWebRTCVideo, fieldKey); }
+
+ _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 =
+ <div className="webcam-cont" style={{ width: "100%", height: "100%" }} onWheel={this.onPostWheel} onPointerDown={this.onPostPointer} onPointerMove={this.onPostPointer} onPointerUp={this.onPostPointer}>
+ <div className="webcam-header">DashWebRTC</div>
+ <input id="roomName" type="text" placeholder="Enter room name" ref={(e) => this.roomText = e!} onKeyDown={this.onEnterKeyDown} />
+ <video id="localVideo" className={"RTCVideo" + (this.remoteVideoAdded ? " side" : " main")} autoPlay playsInline ref={(e) => {
+ this.localVideoEl = e!;
+ }}></video>
+ <video id="remoteVideo" className="RTCVideo main" autoPlay playsInline ref={(e) => {
+ this.peerVideoEl = e!;
+ }}></video>
+
+ </div >;
+
+ let frozen = !this.props.isSelected() || DocumentDecorations.Instance.Interacting;
+ let classname = "webBox-cont" + (this.props.isSelected() && !InkingControl.Instance.selectedTool && !DocumentDecorations.Instance.Interacting ? "-interactive" : "");
+
+
+ return (
+ <>
+ <div className={classname} >
+ {content}
+ </div>
+ {!frozen ? (null) : <div className="webBox-overlay" onWheel={this.onPreWheel} onPointerDown={this.onPrePointer} onPointerMove={this.onPrePointer} onPointerUp={this.onPrePointer} />}
+ </>);
+ }
+
+
+} \ No newline at end of file