diff --git a/.env b/.env new file mode 100644 index 0000000..a43d6bb --- /dev/null +++ b/.env @@ -0,0 +1 @@ +PORT=3001 \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 1f0a0a6..91f61f3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,17 @@ { - "name": "hub-test", + "name": "hub-tester-webrtc-video", "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { + "name": "hub-tester-webrtc-video", "version": "0.1.0", "dependencies": { "@testing-library/jest-dom": "^5.11.8", "@testing-library/react": "^11.2.3", "@testing-library/user-event": "^12.6.0", + "localtunnel": "^2.0.1", "react": "^17.0.1", "react-dom": "^17.0.1", "react-scripts": "4.0.1", @@ -3906,6 +3908,14 @@ "node": ">=4" } }, + "node_modules/axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "dependencies": { + "follow-redirects": "^1.10.0" + } + }, "node_modules/axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -12517,6 +12527,112 @@ "node": ">=8.9.0" } }, + "node_modules/localtunnel": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.1.tgz", + "integrity": "sha512-LiaI5wZdz0xFkIQpXbNI62ZnNn8IMsVhwxHmhA+h4vj8R9JG/07bQHWwQlyy7b95/5fVOCHJfIHv+a5XnkvaJA==", + "dependencies": { + "axios": "0.21.1", + "debug": "4.3.1", + "openurl": "1.1.1", + "yargs": "16.2.0" + }, + "bin": { + "lt": "bin/lt.js" + }, + "engines": { + "node": ">=8.3.0" + } + }, + "node_modules/localtunnel/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/localtunnel/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/localtunnel/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/localtunnel/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/localtunnel/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/localtunnel/node_modules/y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==", + "engines": { + "node": ">=10" + } + }, + "node_modules/localtunnel/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/localtunnel/node_modules/yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "engines": { + "node": ">=10" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -13611,6 +13727,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openurl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", + "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=" + }, "node_modules/opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", @@ -24367,6 +24488,14 @@ "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.1.1.tgz", "integrity": "sha512-5Kgy8Cz6LPC9DJcNb3yjAXTu3XihQgEdnIg50c//zOC/MyLP0Clg+Y8Sh9ZjjnvBrDZU4DgXS9C3T9r4/scGZQ==" }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "axobject-query": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", @@ -31067,6 +31196,84 @@ "json5": "^2.1.2" } }, + "localtunnel": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-2.0.1.tgz", + "integrity": "sha512-LiaI5wZdz0xFkIQpXbNI62ZnNn8IMsVhwxHmhA+h4vj8R9JG/07bQHWwQlyy7b95/5fVOCHJfIHv+a5XnkvaJA==", + "requires": { + "axios": "0.21.1", + "debug": "4.3.1", + "openurl": "1.1.1", + "yargs": "16.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "requires": { + "color-convert": "^2.0.1" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.5.tgz", + "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==" + } + } + }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -31940,6 +32147,11 @@ "is-wsl": "^2.1.1" } }, + "openurl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/openurl/-/openurl-1.1.1.tgz", + "integrity": "sha1-OHW0sO96UsFW8NtB1GCduw+Us4c=" + }, "opn": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", diff --git a/package.json b/package.json index c7fcaf9..ded30fd 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "@testing-library/jest-dom": "^5.11.8", "@testing-library/react": "^11.2.3", "@testing-library/user-event": "^12.6.0", + "localtunnel": "^2.0.1", "react": "^17.0.1", "react-dom": "^17.0.1", "react-scripts": "4.0.1", diff --git a/src/App.js b/src/App.js index f2e706b..705e85f 100644 --- a/src/App.js +++ b/src/App.js @@ -4,31 +4,48 @@ import './App.css'; const io = require("socket.io-client"); -let localStream = null; -let remoteStream = null; +let localStream = new MediaStream(); +let remoteStream = new MediaStream(); -// const iceServer = { -// 'iceServer': [ -// // { 'urls': 'stun:stun.services.mozilla.com' }, // public -// // { 'urls': 'stun:stun.l.google.com:19302' } // public -// // { 'urls': 'dev.linx.safemobile.com:19302' }, -// // { -// // urls: 'turn:dev.linx.safemobile.com:19302', -// // username: "safemobile", -// // credential: "Safemobile123" -// // } -// // , -// { -// urls: 'turn:numb.viagenie.ca', -// username: "webrtc@live.com", -// credential: "muazkh" -// } -// ] -// } +let rtcPeerConnection = null; +// let navigator = null; let localVideo = document.getElementById("localVideo"); let remoteVideo = document.getElementById("remoteVideo"); +// var windowObjectReference; +// var popupUrl = "file:///C:/projects/safemobile/hub-test/src/PopupWindow.html"; +var socket; + +(() => { + setInterval(() => { + // if(rtcPeerConnection != null) { console.log('1'); } + // if(rtcPeerConnection && rtcPeerConnection.hasOwnProperty('signalingState')) { console.log('[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[2'); } + // if(rtcPeerConnection && rtcPeerConnection.hasOwnProperty('signalingState')) { + if(rtcPeerConnection !== null) { + + console.log('[--------------STATE------------]', rtcPeerConnection.signalingState) + } + // } + }, 100) +})() + + + // rtcPeerConnection.setConfiguration( + // { iceServers: [{ + // urls: "turn:dev.linx.safemobile.com:19302", + // username: "sergiu", + // credential: "test123" + // }] + // } + // ); + + // ({iceRestart: true}) // offer + + // rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream) // audio + + // "urls": "turn:dev.linx.safemobile.com:19302?transport=udp", + const streamConstraints = { audio: false, video: true @@ -39,27 +56,41 @@ class App extends Component { super(); this.state = { - login: '', - password: '', + login: 'AIRWizard-adi', + password: 'Safemobile123', user: null, hubStatus: 0, // 0 uninitialized | 1 connecting | 2 connected | 3 connection error socket: null, arsSent: false, - dest_asset_id: '', + dest_asset_id: '66', isCaller: false, callId: null, - rtcPeerConnection: null, - stunUrl: 'stun:dev.linx.safemobile.com:19302', - turnUrl: 'turn:dev.linx.safemobile.com:19302', + // rtcPeerConnection: null, + stunUrl: 'stun:10.120.1.134:19302', + turnUrl: 'turn:10.120.1.134:19302', turnUsername: 'safemobile', - turnCredential: 'Safemobile123' + turnCredential: 'Safemobile123', + testCount: 0 }; } componentDidMount() { - + // var windowObjectReference; + // var windowFeatures = "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=yes"; + // console.log('11111'); + // setTimeout(() => { + // windowObjectReference = window.open("http://www.cnn.com/", "CNN_WindowName", windowFeatures); + // }, 500) } + // testMessage = async () => { + // window.postMessage('s', popupUrl); + // // console.log(this.state.testCount) + // // this.setState((prevState, props) => ({ + // // testCount: prevState.testCount + 1 + // // })); + // // windowObjectReference.postMessage('[WINDOW] messageeeeeeeeeeeeee', popupUrl) + // } handleLoginClick = async () => { const loginRequest = await fetch('https://dev.linx.safemobile.com/api/login', { @@ -78,7 +109,7 @@ class App extends Component { // Connect to HUB // this.setState({ socket: io("localhost:41414", {reconnect:true, transports: ['websocket']}) }, () => { this.setState({ socket: io("https://hub.dev.linx.safemobile.com/", {reconnect:true, transports: ['websocket']}) }, () => { - const socket = this.state.socket; + socket = this.state.socket; socket.on('connect', () => { this.setState({ hubStatus: 2 }) // Send ARS after connected to HUB @@ -88,26 +119,77 @@ class App extends Component { account_id: this.state.user.account.id })); this.setState({ arsSent: true }); + + // var windowFeatures = "menubar=yes,location=yes,resizable=yes,scrollbars=yes,status=false,resizable=yes,titlebar=false,width=640,height=640"; + // // setTimeout(() => { + // window.socket = socket; + // windowObjectReference = window.open(popupUrl, "TEST", windowFeatures); + + + // windowObjectReference.addEventListener("message", (event) => { + // console.log('[WINDOW] event', event) + // console.log('[WINDOW] event.source.opener', event.source.opener.socket); + + // event.source.opener.socket.emit('ars', JSON.stringify({ + // ars: true, + // asset_id: this.state.user.asset.id, + // account_id: this.state.user.account.id + // })); + + // // console.log('B', B); + // }, false); + + // windowObjectReference.document.close(); + // windowObjectReference.focus(); + + // windowObjectReference.postMessage('[WINDOW] messageeeeeeeeeeeeee', popupUrl) + + // }, 2000) + + // window.addEventListener("message", (event) => { + // console.log('[MAIN] event', event) + // // Do we trust the sender of this message? (might be + // // different from what we originally opened, for example). + // if (event.origin !== popupUrl) + // return; + + // // event.source.postMessage("hi there yourself! the secret response " + "is: rheeeeet!", event.origin); + + // // event.source is popup + // // event.data is "hi there yourself! the secret response is: rheeeeet!" + // }, false); + + + // window.postMessage("hello there!", popupUrl); + + console.log('111111111111111') }); // HUB 'video' event handler socket.on('video', (data) => { const parseDate = JSON.parse(data); - console.log('video', parseDate); - - // The response to the 'notify-request' (hardcoded 'YES') + console.log('[VIDEO]', parseDate); if(parseDate.type === 'notify-request') { - this.setState({ dest_asset_id: parseInt(parseDate.origin_asset_id), callId: parseInt(parseDate.video_call_id) }); - socket.emit('video', JSON.stringify({ - origin_asset_id: this.state.user.asset.id, - dest_asset_id: parseInt(parseDate.origin_asset_id), - type: 'notify-answer', - origin_asset_priority: this.state.user.asset.priority, - origin_asset_type_name: this.state.user.user_role.name, - origin_asset_name: this.state.user.name, - video_call_id: parseDate.video_call_id, - answer: 'accepted' // answer: 'rejected' - })); + // console.error('11111111 navigator', navigator); + navigator.mediaDevices.getUserMedia(streamConstraints) + .then(stream => { + localStream = stream + localVideo.srcObject = stream + this.setState({ dest_asset_id: parseInt(parseDate.origin_asset_id), callId: parseInt(parseDate.video_call_id) }); + socket.emit('video', JSON.stringify({ + origin_asset_id: this.state.user.asset.id, + dest_asset_id: parseInt(parseDate.origin_asset_id), + type: 'notify-answer', + origin_asset_priority: this.state.user.asset.priority, + origin_asset_type_name: this.state.user.user_role.name, + origin_asset_name: this.state.user.name, + video_call_id: parseDate.video_call_id, + answer: 'accepted' // answer: 'rejected' + })); + }) + .catch(err => { + console.log('An error occured', err) + }) } // Handler for 'notify-end'(when the video closed) @@ -118,97 +200,71 @@ class App extends Component { // Handler for 'notify-answer' if(parseDate.type === 'notify-answer') { - if(parseDate.answer === 'rejected') { this.closeVideo() return - } - - // Create media stream - navigator.mediaDevices.getUserMedia(streamConstraints).then(stream => { - console.log('Created getUserMedia', stream); - localStream = stream; - localVideo.srcObject = stream; - console.log('iceServers', this.calculateIceServers()) - // Create SDP - this.setState({ rtcPeerConnection: new RTCPeerConnection(this.calculateIceServers()) }, () => { - this.state.rtcPeerConnection.onicecandidate = this.onIceCandidate; - this.state.rtcPeerConnection.ontrack = this.onAddStream; - this.state.rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); // video - // rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream) // audio - // Create a offer - this.state.rtcPeerConnection.createOffer().then(sessionDescription => { - // Save SDP in state and send it to destination asset_id as offer - this.setState({ isCaller: true, callId: parseInt(parseDate.video_call_id) }, () => { - this.state.rtcPeerConnection.setLocalDescription(sessionDescription); - console.log('Created SDP', sessionDescription); - socket.emit('video', JSON.stringify({ - origin_asset_id: this.state.user.asset.id, - type: 'offer', - sdp: sessionDescription, - dest_asset_id: parseInt(this.state.dest_asset_id), - video_call_id: parseDate.video_call_id - })); - }) + } else if(parseDate.answer === 'accepted') { + navigator.mediaDevices.getUserMedia(streamConstraints).then(stream => { + localStream = stream; + localVideo.srcObject = stream; + rtcPeerConnection = new RTCPeerConnection(this.calculateIceServers()); + + rtcPeerConnection.onicecandidate = this.onIceCandidate; + rtcPeerConnection.ontrack = this.onAddStream; + rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); + rtcPeerConnection.createOffer() + .then(async (sessionDescription) => { + await rtcPeerConnection.setLocalDescription(sessionDescription); + socket.emit('video', JSON.stringify({ + origin_asset_id: this.state.user.asset.id, + type: 'offer', + sdp: sessionDescription, + dest_asset_id: parseInt(this.state.dest_asset_id), + video_call_id: parseDate.video_call_id + })); + this.setState({ isCaller: true, callId: parseInt(parseDate.video_call_id) }) }) - .catch(e => { console.log(e); }) + .catch(e => { console.log('[-------------ERROR-------------]', e); }) }) - }) - .catch(err => { - console.log('An error occured', err); - }) + .catch(err => { + console.log('An error occured', err); + }) + } } // Handler for 'offer' if(parseDate.type === 'offer') { - // When we are NOT the caller + if(!this.state.isCaller) { - // Create media stream - navigator.mediaDevices.getUserMedia(streamConstraints).then(stream => { - console.log('Created getUserMedia', stream); - localStream = stream; - localVideo.srcObject = stream; - console.log('iceServers', this.calculateIceServers()) - // Create SDP - this.setState({ rtcPeerConnection: new RTCPeerConnection(this.calculateIceServers()) }, () => { - this.state.rtcPeerConnection.onicecandidate = this.onIceCandidate; - this.state.rtcPeerConnection.ontrack = this.onAddStream; - this.state.rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); // video - // rtcPeerConnection.addTrack(localStream.getTracks()[1], localStream) // audio - // Set setRemoteDescription to be sender SDP - this.state.rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp)); - // Create an answer - this.state.rtcPeerConnection.createAnswer().then(sessionDescription => { - // Save SDP in state and send it to destination asset_id as offer - this.setState({ sdp: sessionDescription }, () => { - this.state.rtcPeerConnection.setLocalDescription(sessionDescription); - console.log('Created SDP', sessionDescription); - socket.emit('video', JSON.stringify({ - origin_asset_id: this.state.user.asset.id, - type: 'offer', - sdp: sessionDescription, - dest_asset_id: parseInt(this.state.dest_asset_id), - video_call_id: parseDate.video_call_id - })); - }) - }) - .catch(e => { console.log(e); }) - }) + rtcPeerConnection = new RTCPeerConnection(this.calculateIceServers()); + rtcPeerConnection.onicecandidate = this.onIceCandidate; + rtcPeerConnection.ontrack = this.onAddStream; + rtcPeerConnection.addTrack(localStream.getTracks()[0], localStream); + rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp)) + rtcPeerConnection.createAnswer() + .then(async (sessionDescription) => { + rtcPeerConnection.setLocalDescription(sessionDescription); + socket.emit('video', JSON.stringify({ + origin_asset_id: this.state.user.asset.id, + type: 'offer', + sdp: sessionDescription, + dest_asset_id: parseInt(this.state.dest_asset_id), + video_call_id: parseDate.video_call_id + })); }) + .catch(e => { console.log('[-------------ERROR-------------]', e); }) } else { - // When we ARE the caller - console.log('parseDate.sdp', parseDate.sdp); - this.state.rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp)); + rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp)); } } if(parseDate.type === 'candidate') { - if(this.state.rtcPeerConnection) { + if(rtcPeerConnection) { const candidate = new RTCIceCandidate({ sdpMLineIndex: parseDate.label, candidate: parseDate.candidate }); - this.state.rtcPeerConnection.addIceCandidate(candidate); + rtcPeerConnection.addIceCandidate(candidate); } } @@ -219,21 +275,68 @@ class App extends Component { } calculateIceServers = () => { - return { - 'iceServer': [ - { - 'urls': this.state.stunUrl - }, { - urls: this.state.turnUrl, - username: this.state.turnUsername, - credential: this.state.turnCredential + // const obj = { + // "iceServers": [ + // { + // "urls":[this.state.stunUrl], + // "username":"safemobile", + // "credential":"Safemobile123" + // }, + // { + // "urls":[this.state.turnUrl], + // "username":this.state.turnUsername, + // "credential":this.state.turnCredential + // } + // ], + // "iceTransportPolicy":"all", + // "iceCandidatePoolSize":"0" + // }; + // const obj = { + // "iceServers": [ + // { + // "urls": "stun:dev.linx.safemobile.com:19302", + // "username":"", + // "credential":"" + // } + // ], + // }; + + // { + // "urls": "turn:dev.linx.safemobile.com:19302?transport=tcp", + // "username": "sergiu", + // "credential": "test123" + // }, + + const obj = { + "iceServers": [ + { + "urls": this.state.stunUrl, + "username": "", + "credential": "" + }, + { + "urls": this.state.turnUrl, + "username": this.state.turnUsername, + "credential": this.state.turnCredential, } ] - } + }; + // const obj = { + // "iceServers": [ + // { + // "urls":[this.state.turnUrl], + // "username":this.state.turnUsername, + // "credential":this.state.turnCredential + // } + // ], + // "iceTransportPolicy":"relay", + // "iceCandidatePoolSize":"3" + // }; + console.log('obj-----------------------', obj); + return obj; } onAddStream = (event) => { - console.log('onAddStream', event); remoteVideo.srcObject = event.streams[0]; remoteStream = event.streams[0]; } @@ -302,8 +405,8 @@ class App extends Component { } cleanVideoStreams = () => { - this.state.rtcPeerConnection != null && this.state.rtcPeerConnection.close(); - this.setState({ callId: null, rtcPeerConnection: null }); + rtcPeerConnection != null && rtcPeerConnection.close(); + // this.setState({ callId: null, rtcPeerConnection: null }); localVideo.srcObject = null; remoteVideo.srcObject = null; } @@ -313,8 +416,8 @@ class App extends Component { return (
-

HUB TESTER

- +

WebRTC Client 0.7

+ {this.state.testCount}

STUN and TURN servers

@@ -372,11 +475,12 @@ class App extends Component { />

+ {/* */}

isCaller: {isCaller ? 'TRUE' : 'FALSE'}

-

User details:

+

User details:

{ user && (