From 09be2806ccbc2606561a8a61479786b3cfa019bb Mon Sep 17 00:00:00 2001 From: Sergiu Toma Date: Tue, 16 Feb 2021 13:33:08 +0200 Subject: [PATCH] update web client --- public/index.html | 11 ++ src/App.js | 372 +++++++++++++++++++--------------------------- 2 files changed, 160 insertions(+), 223 deletions(-) diff --git a/public/index.html b/public/index.html index 914c2b7..cb86bad 100644 --- a/public/index.html +++ b/public/index.html @@ -29,6 +29,17 @@
+ + + LOCAL VIDEO

REMOTE VIDEO diff --git a/src/App.js b/src/App.js index 705145b..6d5e2be 100644 --- a/src/App.js +++ b/src/App.js @@ -4,53 +4,44 @@ import './App.css'; const io = require("socket.io-client"); -let localStream = new MediaStream(); -let remoteStream = new MediaStream(); +var socket, stream; -let rtcPeerConnection = null; -// let navigator = null; +var config = { + iceServers: [{ + urls: [ "stun:dev.linx.safemobil.com:3478" ] + }, { + username: "sergiu ", + credential: "test123", + urls: [ + "turn:dev.linx.safemobil.com:3478" + ] + }], + //FOR CHROME + rtcpMuxPolicy:"negotiate" +} + +// var config = { +// iceServers: [{ +// urls: [ "stun:numb.viagenie.ca" ] +// }, { +// username: "claudiustancu@outlook.com", +// credential: "Parola123", +// urls: [ +// "turn:numb.viagenie.ca" +// ] +// }], + +// //FOR CHROME +// rtcpMuxPolicy:"negotiate" +// } + +var pc = new RTCPeerConnection(config) + +let localStream, remoteStream 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 -}; - class App extends Component { constructor() { super(); @@ -62,7 +53,7 @@ class App extends Component { hubStatus: 0, // 0 uninitialized | 1 connecting | 2 connected | 3 connection error socket: null, arsSent: false, - dest_asset_id: '66', + dest_asset_id: '1', isCaller: false, callId: null, // rtcPeerConnection: null, @@ -73,18 +64,30 @@ class App extends Component { }; } - componentDidMount() { + componentDidMount= async () => { // 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) + stream = await navigator.mediaDevices.getUserMedia({video:true, audio:false}) + localStream = stream + localVideo.srcObject = stream + pc.ontrack = this.onAddStream; + // pc.addTrack(localStream.getTracks()[0], localStream); + pc.addTrack(localStream.getTracks()[0], localStream) + // pc.addTrack(localStream.getTracks()[1], localStream) + } + + onAddStream = (event) => { + console.log('onAddStream', event); + remoteVideo.srcObject = event.streams[0] + remoteStream = event.streams[0] } handleLoginClick = async () => { const loginRequest = await fetch('https://dev.linx.safemobile.com/api/login', { - // const loginRequest = await fetch('http://localhost:41418/login', { method: 'POST', headers: { 'Content-Type': 'application/json' @@ -97,7 +100,6 @@ class App extends Component { const loginResponseJson = await loginRequest.json(); this.setState({ user: loginResponseJson.data }, () => { // 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']}) }, () => { socket = this.state.socket; socket.on('connect', () => { @@ -109,154 +111,56 @@ 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); - if(parseDate.type === 'notify-request') { - // 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) - }) - } + socket.on('video', async (data) => { - // Handler for 'notify-end'(when the video closed) - if(parseDate.type === 'notify-end') { - console.log('notify-end'); - this.cleanVideoStreams(); - } - // Handler for 'notify-answer' - if(parseDate.type === 'notify-answer') { - if(parseDate.answer === 'rejected') { - this.closeVideo() - return - } 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, + const parseData = JSON.parse(data); + console.log('[VIDEO]', parseData); + + if(parseData.type === 'notify-request') { + await pc.setLocalDescription(await pc.createOffer()) + socket.emit('video', JSON.stringify({ + origin_asset_id: this.state.user.asset.id, + dest_asset_id: parseInt(parseData.origin_asset_id), + type: 'offer', + origin_asset_priority: this.state.user.asset.priority, + origin_asset_type_name: this.state.user.user_role.name, + origin_asset_name: this.state.user.asset.name, + video_call_id: parseData.video_call_id, + answer: 'accepted', // answer: 'rejected' + sdp: pc.localDescription + })); + this.setState({ callId: parseInt(parseData.video_call_id), dest_asset_id: parseInt(parseData.origin_asset_id) }) + } + else if(parseData.type === 'offer') { + if(parseData.sdp.type === 'offer') { + console.log('[OFFER]'); + this.setState({ callId: parseInt(parseData.video_call_id) }) + this.offerReceived(parseData) + } else if(parseData.sdp.type === 'answer') { + console.log('[ANSWER]'); + await pc.setRemoteDescription(parseData.sdp) + pc.onicecandidate = ({candidate}) => { + console.log('candidate1', candidate); + this.state.socket.emit('video', JSON.stringify({ + type: 'candidate', + candidate, dest_asset_id: parseInt(this.state.dest_asset_id), - video_call_id: parseDate.video_call_id + test: '222222222222' })); - this.setState({ isCaller: true, callId: parseInt(parseDate.video_call_id) }) - }) - .catch(e => { console.log('[-------------ERROR-------------]', e); }) - }) - .catch(err => { - console.log('An error occured', err); - }) + } + } + } else if(parseData.type === 'candidate') { + console.log('candidate parseData', parseData); + if(parseData.candidate) { + console.log('parseData.candidate', parseData.candidate) + pc.addIceCandidate(parseData.candidate).catch(e => {console.log(e)}) } } - // Handler for 'offer' - if(parseDate.type === 'offer') { - - if(!this.state.isCaller) { - 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 { - rtcPeerConnection.setRemoteDescription(new RTCSessionDescription(parseDate.sdp)); - } - } - - if(parseDate.type === 'candidate') { - if(rtcPeerConnection) { - const candidate = new RTCIceCandidate({ - sdpMLineIndex: parseDate.label, - candidate: parseDate.candidate - }); - rtcPeerConnection.addIceCandidate(candidate); - } - } }); @@ -264,41 +168,63 @@ class App extends Component { }) } - calculateIceServers = () => { - const obj = { - "iceServers": [ - { - "urls": this.state.stunUrl, - "username": "", - "credential": "" - }, - { - "urls": this.state.turnUrl, - "username": this.state.turnUsername, - "credential": this.state.turnCredential, - } - ] - }; - console.log('calculateIceServers-----------------------', obj); - return obj; - } + offerReceived = async (offer) => { - onAddStream = (event) => { - remoteVideo.srcObject = event.streams[0]; - remoteStream = event.streams[0]; - } + console.log('Received offer', offer) - onIceCandidate = (event) => { - if(event.candidate) { - console.log('sending ice candidate', event.candidate); - this.state.socket.emit('video', JSON.stringify({ - type: 'candidate', - label: event.candidate.sdpMLineIndex, - id: event.candidate.sdpMid, - candidate: event.candidate.candidate, - dest_asset_id: this.state.dest_asset_id + await pc.setRemoteDescription(offer.sdp) + + pc.onicecandidate = ({candidate}) => { + this.state.socket.emit('video', JSON.stringify({ + type: 'candidate', + candidate: candidate, + dest_asset_id: parseInt(this.state.dest_asset_id), + test: '1111111111' + })); + } + + await pc.setLocalDescription(await pc.createAnswer()) + + pc.onnegotiationneeded = async () => { + console.log('---------onnegotiationneeded--------'); + try { + await pc.setLocalDescription(await pc.createOffer()); + // socket.emit('signal', {destination:remoteUser, data:pc.localDescription}) + socket.emit('video', JSON.stringify({ + origin_asset_id: this.state.user.asset.id, + dest_asset_id: parseInt(this.state.dest_asset_id), + type: 'offer', + origin_asset_priority: this.state.user.asset.priority, + origin_asset_type_name: this.state.user.user_role.name, + origin_asset_name: this.state.user.asset.name, + video_call_id: this.state.callId, + sdp: pc.localDescription })); + } catch (err) { + console.error(err); } + }; + console.log({ + origin_asset_id: this.state.user.asset.id, + dest_asset_id: parseInt(this.state.dest_asset_id), + type: 'offer', + origin_asset_priority: this.state.user.asset.priority, + origin_asset_type_name: this.state.user.user_role.name, + origin_asset_name: this.state.user.asset.name, + video_call_id: null, + sdp: pc.localDescription + }); + this.state.socket.emit('video', JSON.stringify({ + origin_asset_id: this.state.user.asset.id, + dest_asset_id: parseInt(this.state.dest_asset_id), + type: 'offer', + origin_asset_priority: this.state.user.asset.priority, + origin_asset_type_name: this.state.user.user_role.name, + origin_asset_name: this.state.user.asset.name, + video_call_id: null, + sdp: pc.localDescription + })); + console.log('---------onnegotiationneeded END--------'); } handleChangeLogin = (e) => { @@ -339,6 +265,13 @@ class App extends Component { origin_asset_name: this.state.user.name, video_call_id: null })); + // var userToCall = document.getElementById('calluser').value + // remoteUser = userToCall + // document.getElementById('invitestatus').innerHTML = " INVITATIE TRIMISA" + // document.getElementById('loadingOverlay').style.display = "block" + // var x = document.getElementById('calluser'); + // x.style.display = "none"; + // socket.emit('call', userToCall) } closeVideo = () => { @@ -351,19 +284,12 @@ class App extends Component { this.cleanVideoStreams(); } - cleanVideoStreams = () => { - rtcPeerConnection != null && rtcPeerConnection.close(); - // this.setState({ callId: null, rtcPeerConnection: null }); - localVideo.srcObject = null; - remoteVideo.srcObject = null; - } - render() { const { login, password, user, hubStatus, arsSent, dest_asset_id, isCaller, callId, stunUrl, turnUrl, turnUsername, turnCredential } = { ...this.state }; return (
-

WebRTC Client 0.8

+

WebRTC Client 0.8 - {Math.random()}



STUN and TURN servers