From 27876b32ae3a15ed3723294aefea6d7c59c1dad1 Mon Sep 17 00:00:00 2001 From: Taichi Kato Date: Sat, 30 May 2020 18:31:56 +0800 Subject: [PATCH 01/10] removed https --- server.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server.js b/server.js index 7e8407c..f7f0a8e 100644 --- a/server.js +++ b/server.js @@ -9,11 +9,11 @@ var twilio = require("twilio")(twillioAccountSID, twillioAuthToken); var express = require("express"); var app = express(); const fs = require('fs'); -var http = require("https").createServer({ - key: fs.readFileSync('/Users/khushjammu/certs/privkey.pem'), - cert: fs.readFileSync('/Users/khushjammu/certs/cert.pem') -}, app); -// var http = require("http").createServer(app); +// var http = require("https").createServer({ +// key: fs.readFileSync('/Users/khushjammu/certs/privkey.pem'), +// cert: fs.readFileSync('/Users/khushjammu/certs/cert.pem') +// }, app); +var http = require("http").createServer(app); var io = require("socket.io")(http); var path = require("path"); var public = path.join(__dirname, "public"); From 88444d86c0e77e67bb19b17298c4af2c4e604857 Mon Sep 17 00:00:00 2001 From: Taichi Kato Date: Sat, 30 May 2020 18:33:41 +0800 Subject: [PATCH 02/10] reverted tto the default port number --- server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server.js b/server.js index f7f0a8e..39c4d84 100644 --- a/server.js +++ b/server.js @@ -145,7 +145,7 @@ io.on("connection", function (socket) { }); // Listen for Heroku port, otherwise just use 3000 -var port = process.env.PORT || 443; +var port = process.env.PORT || 3000; http.listen(port, function () { console.log("http://localhost:" + port); }); From 58bc2858eaf34143044badf6516dc490c367d0fb Mon Sep 17 00:00:00 2001 From: Taichi Kato Date: Sat, 30 May 2020 18:54:57 +0800 Subject: [PATCH 03/10] ran prettify --- public/chat.html | 3 +- public/js/chat.js | 107 ++++++++++++++++++++++++++++++++-------------- server.js | 21 ++++++--- 3 files changed, 91 insertions(+), 40 deletions(-) diff --git a/public/chat.html b/public/chat.html index d15c4ce..db77f8a 100644 --- a/public/chat.html +++ b/public/chat.html @@ -46,8 +46,7 @@

-
-
+

No webcam input

diff --git a/public/js/chat.js b/public/js/chat.js index 8d627c5..32f5567 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -35,7 +35,6 @@ var VideoChat = { localVideo: document.getElementById("local-video"), peerConnections: {}, recognition: undefined, - answerCreatedUUIDs: [], // HACKY workaround: currently, onAnswer seems to be triggering twice and we don't know why // Call to getUserMedia (provided by adapter.js for cross browser compatibility) // asking for access to both the video and audio streams. If the request is @@ -116,23 +115,27 @@ var VideoChat = { logIt("readyToCall"); }, call: function (uuid, room) { - logIt("Initiating call"); - VideoChat.startCall(uuid); + logIt("Initiating call"); + VideoChat.startCall(uuid); }, // Set up a callback to run when we have the ephemeral token to use Twilio's TURN server. startCall: function (uuid) { - VideoChat.socket.on("token", VideoChat.establishConnection(uuid, function(a) {VideoChat.createOffer(a);})); + VideoChat.socket.on( + "token", + VideoChat.establishConnection(uuid, function (a) { + VideoChat.createOffer(a); + }) + ); VideoChat.socket.emit("token", roomHash, uuid); }, establishConnection: function (correctUuid, callback) { - return function(token, uuid) { + return function (token, uuid) { if (correctUuid != uuid) { return; } console.log("establishing connection to", uuid); - VideoChat.localICECandidates[uuid] = []; // initialise uuid with empty array VideoChat.connected[uuid] = false; @@ -173,12 +176,17 @@ var VideoChat = { // Set up callbacks for the connection generating iceCandidates or // receiving the remote media stream. - VideoChat.peerConnections[uuid].onicecandidate = function(u) {VideoChat.onIceCandidate(u, uuid)}; - VideoChat.peerConnections[uuid].onaddstream = function(u) {VideoChat.onAddStream(u, uuid)}; - + VideoChat.peerConnections[uuid].onicecandidate = function (u) { + VideoChat.onIceCandidate(u, uuid); + }; + VideoChat.peerConnections[uuid].onaddstream = function (u) { + VideoChat.onAddStream(u, uuid); + }; // Called when there is a change in connection state - VideoChat.peerConnections[uuid].oniceconnectionstatechange = function (event) { + VideoChat.peerConnections[uuid].oniceconnectionstatechange = function ( + event + ) { switch (VideoChat.peerConnections[uuid].iceConnectionState) { case "connected": logIt("connected"); @@ -201,7 +209,7 @@ var VideoChat = { } }; callback(uuid); - } + }; }, // When the peerConnection generates an ice candidate, send it over the socket to the peer. @@ -225,7 +233,6 @@ var VideoChat = { // The peer may not have created the RTCPeerConnection yet, so we are waiting for the 'answer' // to arrive. This will signal that the peer is ready to receive signaling. VideoChat.localICECandidates[uuid].push(event.candidate); - } } }, @@ -244,7 +251,12 @@ var VideoChat = { // Create an offer that contains the media capabilities of the browser. createOffer: function (uuid) { - console.log(">>> Creating offer to UUID: ", uuid, ". my UUID is", VideoChat.socket.id); + console.log( + ">>> Creating offer to UUID: ", + uuid, + ". my UUID is", + VideoChat.socket.id + ); VideoChat.peerConnections[uuid].createOffer( function (offer) { // If the offer is created successfully, set it as the local description @@ -268,12 +280,22 @@ var VideoChat = { createAnswer: function (offer, uuid) { logIt("createAnswer"); rtcOffer = new RTCSessionDescription(JSON.parse(offer)); - console.log("createAnswer: setting remote description of " + uuid + " on " + VideoChat.socket.id); + console.log( + "createAnswer: setting remote description of " + + uuid + + " on " + + VideoChat.socket.id + ); VideoChat.peerConnections[uuid].setRemoteDescription(rtcOffer); VideoChat.peerConnections[uuid].createAnswer( function (answer) { VideoChat.peerConnections[uuid].setLocalDescription(answer); - console.log(">>> Creating answer to UUID: ", uuid, ". my UUID is", VideoChat.socket.id); + console.log( + ">>> Creating answer to UUID: ", + uuid, + ". my UUID is", + VideoChat.socket.id + ); VideoChat.socket.emit("answer", JSON.stringify(answer), roomHash, uuid); }, function (err) { @@ -288,27 +310,45 @@ var VideoChat = { onOffer: function (offer, uuid) { logIt("onOffer <<< Received offer"); // VideoChat.socket.on("token", VideoChat.establishConnection(uuid, function(a) {VideoChat.createOffer(a);})); - VideoChat.socket.on("token", VideoChat.establishConnection(uuid, function(a) {VideoChat.createAnswer(offer, a);})); + VideoChat.socket.on( + "token", + VideoChat.establishConnection(uuid, function (a) { + VideoChat.createAnswer(offer, a); + }) + ); VideoChat.socket.emit("token", roomHash, uuid); }, // When an answer is received, add it to the peerConnection as the remote description. onAnswer: function (answer, uuid) { - console.log("onAnswer <<< Received answer", uuid, ". my UUID is", VideoChat.socket.id); + console.log( + "onAnswer <<< Received answer", + uuid, + ". my UUID is", + VideoChat.socket.id + ); - // if (!VideoChat.answerCreatedUUIDs.includes(uuid)) { - VideoChat.answerCreatedUUIDs.push(uuid); - // logIt("onAnswer <<< Received answer" + ""); - var rtcAnswer = new RTCSessionDescription(JSON.parse(answer)); - // Set remote description of RTCSession - console.log("onAnswer: setting remote description of " + uuid + " on " + VideoChat.socket.id); - VideoChat.peerConnections[uuid].setRemoteDescription(rtcAnswer); - // The caller now knows that the callee is ready to accept new ICE candidates, so sending the buffer over - VideoChat.localICECandidates[uuid].forEach((candidate) => { - logIt(`>>> Sending local ICE candidate (${candidate.address})`); - // Send ice candidate over websocket - VideoChat.socket.emit("candidate", JSON.stringify(candidate), roomHash, uuid); - }); + // logIt("onAnswer <<< Received answer" + ""); + var rtcAnswer = new RTCSessionDescription(JSON.parse(answer)); + // Set remote description of RTCSession + console.log( + "onAnswer: setting remote description of " + + uuid + + " on " + + VideoChat.socket.id + ); + VideoChat.peerConnections[uuid].setRemoteDescription(rtcAnswer); + // The caller now knows that the callee is ready to accept new ICE candidates, so sending the buffer over + VideoChat.localICECandidates[uuid].forEach((candidate) => { + logIt(`>>> Sending local ICE candidate (${candidate.address})`); + // Send ice candidate over websocket + VideoChat.socket.emit( + "candidate", + JSON.stringify(candidate), + roomHash, + uuid + ); + }); }, // Called when a stream is added to the peer connection @@ -318,7 +358,9 @@ var VideoChat = { // }else{ // VideoChat.counter++; // } - logIt("onAddStream <<< Received new stream from remote. Adding it..." + event); + logIt( + "onAddStream <<< Received new stream from remote. Adding it..." + event + ); // Create new remote video source in wrapper // Create a

-
-
+

No webcam input

diff --git a/public/js/chat.js b/public/js/chat.js index 91d2f85..092d173 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -28,11 +28,10 @@ const chatZone = $("#chat-zone"); var dataChannel = new Map(); - var VideoChat = { nickname: undefined, - videoEnabled: true, - audioEnabled: true, + videoEnabled: true, + audioEnabled: true, connected: new Map(), localICECandidates: {}, socket: io(), @@ -101,7 +100,10 @@ var VideoChat = { VideoChat.nickname = prompt("Please enter a nickname", ""); while (VideoChat.nickname == null || VideoChat.nickname.trim() === "") { - VideoChat.nickname = prompt("Nickname cannot be empty. Please enter a nickname", ""); + VideoChat.nickname = prompt( + "Nickname cannot be empty. Please enter a nickname", + "" + ); } VideoChat.localVideo.srcObject = stream; @@ -128,42 +130,54 @@ var VideoChat = { logIt("readyToCall"); }, call: function (uuid, room) { - logIt("Initiating call"); - VideoChat.startCall(uuid); + logIt("Initiating call"); + VideoChat.startCall(uuid); }, // Set up a callback to run when we have the ephemeral token to use Twilio's TURN server. startCall: function (uuid) { - VideoChat.socket.on("token", VideoChat.establishConnection(uuid, function(a) {VideoChat.createOffer(a);})); + VideoChat.socket.on( + "token", + VideoChat.establishConnection(uuid, function (a) { + VideoChat.createOffer(a); + }) + ); VideoChat.socket.emit("token", roomHash, uuid); }, establishConnection: function (correctUuid, callback) { - return function(token, uuid) { + return function (token, uuid) { if (correctUuid != uuid) { return; } console.log("establishing connection to", uuid); - VideoChat.localICECandidates[uuid] = []; // initialise uuid with empty array VideoChat.connected.set(uuid, false); // Set up a new RTCPeerConnection using the token's iceServers. - VideoChat.peerConnections.set(uuid, new RTCPeerConnection({ - iceServers: token.iceServers, - })) + VideoChat.peerConnections.set( + uuid, + new RTCPeerConnection({ + iceServers: token.iceServers, + }) + ); // Add the local video stream to the peerConnection. VideoChat.localStream.getTracks().forEach(function (track) { - VideoChat.peerConnections.get(uuid).addTrack(track, VideoChat.localStream); + VideoChat.peerConnections + .get(uuid) + .addTrack(track, VideoChat.localStream); }); // Add general purpose data channel to peer connection, // used for text chats, captions, and toggling sending captions - dataChannel.set(uuid, VideoChat.peerConnections.get(uuid).createDataChannel("chat", { - negotiated: true, - // both peers must have same id - id: 0, - })); + dataChannel.set( + uuid, + VideoChat.peerConnections.get(uuid).createDataChannel("chat", { + negotiated: true, + // both peers must have same id + id: 0, + }) + ); // Called when dataChannel is successfully opened dataChannel.get(uuid).onopen = function (event) { logIt("dataChannel opened"); @@ -185,12 +199,17 @@ var VideoChat = { // Set up callbacks for the connection generating iceCandidates or // receiving the remote media stream. - VideoChat.peerConnections.get(uuid).onicecandidate = function(u) {VideoChat.onIceCandidate(u, uuid)}; - VideoChat.peerConnections.get(uuid).onaddstream = function(u) {VideoChat.onAddStream(u, uuid)}; - + VideoChat.peerConnections.get(uuid).onicecandidate = function (u) { + VideoChat.onIceCandidate(u, uuid); + }; + VideoChat.peerConnections.get(uuid).onaddstream = function (u) { + VideoChat.onAddStream(u, uuid); + }; // Called when there is a change in connection state - VideoChat.peerConnections.get(uuid).oniceconnectionstatechange = function (event) { + VideoChat.peerConnections.get( + uuid + ).oniceconnectionstatechange = function (event) { switch (VideoChat.peerConnections.get(uuid).iceConnectionState) { case "connected": logIt("connected"); @@ -213,7 +232,7 @@ var VideoChat = { } }; callback(uuid); - } + }; }, // When the peerConnection generates an ice candidate, send it over the socket to the peer. @@ -237,7 +256,6 @@ var VideoChat = { // The peer may not have created the RTCPeerConnection yet, so we are waiting for the 'answer' // to arrive. This will signal that the peer is ready to receive signaling. VideoChat.localICECandidates[uuid].push(event.candidate); - } } }, @@ -256,7 +274,12 @@ var VideoChat = { // Create an offer that contains the media capabilities of the browser. createOffer: function (uuid) { - console.log(">>> Creating offer to UUID: ", uuid, ". my UUID is", VideoChat.socket.id); + console.log( + ">>> Creating offer to UUID: ", + uuid, + ". my UUID is", + VideoChat.socket.id + ); VideoChat.peerConnections.get(uuid).createOffer( function (offer) { // If the offer is created successfully, set it as the local description @@ -280,12 +303,22 @@ var VideoChat = { createAnswer: function (offer, uuid) { logIt("createAnswer"); rtcOffer = new RTCSessionDescription(JSON.parse(offer)); - console.log("createAnswer: setting remote description of " + uuid + " on " + VideoChat.socket.id); + console.log( + "createAnswer: setting remote description of " + + uuid + + " on " + + VideoChat.socket.id + ); VideoChat.peerConnections.get(uuid).setRemoteDescription(rtcOffer); VideoChat.peerConnections.get(uuid).createAnswer( function (answer) { VideoChat.peerConnections.get(uuid).setLocalDescription(answer); - console.log(">>> Creating answer to UUID: ", uuid, ". my UUID is", VideoChat.socket.id); + console.log( + ">>> Creating answer to UUID: ", + uuid, + ". my UUID is", + VideoChat.socket.id + ); VideoChat.socket.emit("answer", JSON.stringify(answer), roomHash, uuid); }, function (err) { @@ -300,32 +333,54 @@ var VideoChat = { onOffer: function (offer, uuid) { logIt("onOffer <<< Received offer"); // VideoChat.socket.on("token", VideoChat.establishConnection(uuid, function(a) {VideoChat.createOffer(a);})); - VideoChat.socket.on("token", VideoChat.establishConnection(uuid, function(a) {VideoChat.createAnswer(offer, a);})); + VideoChat.socket.on( + "token", + VideoChat.establishConnection(uuid, function (a) { + VideoChat.createAnswer(offer, a); + }) + ); VideoChat.socket.emit("token", roomHash, uuid); }, // When an answer is received, add it to the peerConnection as the remote description. onAnswer: function (answer, uuid) { - console.log("onAnswer <<< Received answer", uuid, ". my UUID is", VideoChat.socket.id); + console.log( + "onAnswer <<< Received answer", + uuid, + ". my UUID is", + VideoChat.socket.id + ); // if (!VideoChat.answerCreatedUUIDs.includes(uuid)) { - VideoChat.answerCreatedUUIDs.push(uuid); - // logIt("onAnswer <<< Received answer" + ""); - var rtcAnswer = new RTCSessionDescription(JSON.parse(answer)); - // Set remote description of RTCSession - console.log("onAnswer: setting remote description of " + uuid + " on " + VideoChat.socket.id); - VideoChat.peerConnections.get(uuid).setRemoteDescription(rtcAnswer); - // The caller now knows that the callee is ready to accept new ICE candidates, so sending the buffer over - VideoChat.localICECandidates[uuid].forEach((candidate) => { - logIt(`>>> Sending local ICE candidate (${candidate.address})`); - // Send ice candidate over websocket - VideoChat.socket.emit("candidate", JSON.stringify(candidate), roomHash, uuid); - }); + VideoChat.answerCreatedUUIDs.push(uuid); + // logIt("onAnswer <<< Received answer" + ""); + var rtcAnswer = new RTCSessionDescription(JSON.parse(answer)); + // Set remote description of RTCSession + console.log( + "onAnswer: setting remote description of " + + uuid + + " on " + + VideoChat.socket.id + ); + VideoChat.peerConnections.get(uuid).setRemoteDescription(rtcAnswer); + // The caller now knows that the callee is ready to accept new ICE candidates, so sending the buffer over + VideoChat.localICECandidates[uuid].forEach((candidate) => { + logIt(`>>> Sending local ICE candidate (${candidate.address})`); + // Send ice candidate over websocket + VideoChat.socket.emit( + "candidate", + JSON.stringify(candidate), + roomHash, + uuid + ); + }); }, // Called when a stream is added to the peer connection onAddStream: function (event, uuid) { - logIt("onAddStream <<< Received new stream from remote. Adding it..." + event); + logIt( + "onAddStream <<< Received new stream from remote. Adding it..." + event + ); // Create new remote video source in wrapper // Create a
@@ -236,17 +237,18 @@
Feature tile icon 06
-

Maximum Security

+

Total Privacy and Security

- End to end state of the art encryption means your calls + Zipcall is built privacy first. Each chat is single use, + and end to end state of the art encryption means your calls are exactly that. Your calls.

From 13ea32192faa57ef48d372d1612280f6822cf2ed Mon Sep 17 00:00:00 2001 From: Arya Vohra Date: Sun, 31 May 2020 12:51:58 +0800 Subject: [PATCH 09/10] Cleaned up and commented chat.js --- public/js/chat.js | 49 +++++++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/public/js/chat.js b/public/js/chat.js index dc50958..a944755 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -26,6 +26,7 @@ const captionButtontext = $("#caption-button-text"); const entireChat = $("#entire-chat"); const chatZone = $("#chat-zone"); +// Need a Map to keep track of dataChannel connecting with each peer var dataChannel = new Map(); var VideoChat = { @@ -96,6 +97,7 @@ var VideoChat = { }, }); + // Used to identify client to other peers in chats, captions etc. VideoChat.nickname = prompt("Please enter a nickname", ""); while (VideoChat.nickname == null || VideoChat.nickname.trim() === "") { @@ -106,12 +108,15 @@ var VideoChat = { } VideoChat.localVideo.srcObject = stream; + // Now we're ready to join the chat room. VideoChat.socket.emit("join", roomHash); + // Add listeners to the websocket VideoChat.socket.on("full", chatRoomFull); VideoChat.socket.on("offer", VideoChat.onOffer); VideoChat.socket.on("willInitiateCall", VideoChat.call); + // Set up listeners on the socket VideoChat.socket.on("candidate", VideoChat.onCandidate); VideoChat.socket.on("answer", VideoChat.onAnswer); @@ -122,7 +127,7 @@ var VideoChat = { }, call: function (uuid, room) { - logIt("Initiating call with " + uuid); + logIt(`call >>> Initiating call with ${uuid}...`); VideoChat.socket.on( "token", VideoChat.establishConnection(uuid, function (a) { @@ -137,9 +142,10 @@ var VideoChat = { if (correctUuid != uuid) { return; } - console.log("establishing connection to", uuid); - // Initialise localICEcandidates for node uuid with empty array + logIt(`<<< Received token, connecting to ${uuid}`); + // Initialise localICEcandidates for peer uuid to empty array VideoChat.localICECandidates[uuid] = []; + // Initialise connection status with peer uuid to false VideoChat.connected.set(uuid, false); // Set up a new RTCPeerConnection using the token's iceServers. VideoChat.peerConnections.set( @@ -182,16 +188,15 @@ var VideoChat = { toggleSendCaptions(); } }; - // Set up callbacks for the connection generating iceCandidates or - // receiving the remote media stream. - VideoChat.peerConnections.get(uuid).onicecandidate = function (u) { - VideoChat.onIceCandidate(u, uuid); + // receiving the remote media stream. Wrapping callback functions + // to pass in the peer uuids. + VideoChat.peerConnections.get(uuid).onicecandidate = function (event) { + VideoChat.onIceCandidate(event, uuid); }; - VideoChat.peerConnections.get(uuid).onaddstream = function (u) { - VideoChat.onAddStream(u, uuid); + VideoChat.peerConnections.get(uuid).onaddstream = function (event) { + VideoChat.onAddStream(event, uuid); }; - // Called when there is a change in connection state VideoChat.peerConnections.get( uuid @@ -199,7 +204,6 @@ var VideoChat = { switch (VideoChat.peerConnections.get(uuid).iceConnectionState) { case "connected": logIt("connected"); - // Once connected we no longer have a need for the signaling server, so disconnect break; case "disconnected": logIt("disconnected"); @@ -224,7 +228,7 @@ var VideoChat = { logIt("onIceCandidate"); if (event.candidate) { logIt( - `<<< Received local ICE candidate from STUN/TURN server (${event.candidate.address}) associated with UUID (${uuid})` + `<<< Received local ICE candidate from STUN/TURN server (${event.candidate.address}) for connection with ${uuid}` ); if (VideoChat.connected.get(uuid)) { logIt(`>>> Sending local ICE candidate (${event.candidate.address})`); @@ -274,7 +278,7 @@ var VideoChat = { ); }, - // Create an answer with the media capabilities that both browsers share. + // Create an answer with the media capabilities that the client and peer browsers share. // This function is called with the offer from the originating browser, which // needs to be parsed into an RTCSessionDescription and added as the remote // description to the peerConnection object. Then the answer is created in the @@ -300,7 +304,6 @@ var VideoChat = { // ephemeral token is returned from Twilio. onOffer: function (offer, uuid) { logIt("onOffer <<< Received offer"); - // VideoChat.socket.on("token", VideoChat.establishConnection(uuid, function(a) {VideoChat.createOffer(a);})); VideoChat.socket.on( "token", VideoChat.establishConnection(uuid, function (a) { @@ -327,6 +330,8 @@ var VideoChat = { uuid ); }); + // Reset the buffer of local ICE candidates. This is not really needed, but it's good practice + // VideoChat.localICECandidates[uuid] = []; // TESTING }, // Called when a stream is added to the peer connection @@ -352,14 +357,6 @@ var VideoChat = { // Reposition local video after a second, as there is often a delay // between adding a stream and the height of the video div changing setTimeout(() => rePositionLocalVideo(), 500); - // var timesRun = 0; - // var interval = setInterval(function () { - // timesRun += 1; - // if (timesRun === 10) { - // clearInterval(interval); - // } - // rePositionLocalVideo(); - // }, 300); }, }; @@ -418,8 +415,7 @@ function rePositionCaptions() { // Get remote video position var bounds = remoteVideosWrapper.position(); bounds.top -= 10; - bounds.top = - bounds.top + remoteVideosWrapper.height() - 1 * captionText.height(); + bounds.top += remoteVideosWrapper.height() - 1 * captionText.height(); // Reposition captions captionText.css(bounds); } @@ -498,7 +494,6 @@ function sendToAllDataChannels(message) { // Mute microphone function muteMicrophone() { - VideoChat.audioEnabled = !VideoChat.audioEnabled; var audioTrack = null; VideoChat.peerConnections.forEach(function (value, key, map) { @@ -510,6 +505,8 @@ function muteMicrophone() { audioTrack.enabled = VideoChat.audioEnabled; }); + VideoChat.audioEnabled = !VideoChat.audioEnabled; + // select mic button and mic button text const micButtonIcon = document.getElementById("mic-icon"); const micButtonText = document.getElementById("mic-text"); @@ -637,7 +634,6 @@ function switchStreamHelper(stream) { videoTrack.onended = function () { swap(); }; - // Swap video for every peer connection VideoChat.connected.forEach(function (value, key, map) { // Just to be safe, check if connected before swapping video channel @@ -651,7 +647,6 @@ function switchStreamHelper(stream) { sender.replaceTrack(videoTrack); } }); - // Update local video stream VideoChat.localStream = videoTrack; // Update local video object From 77188ead7b3bb115f1077a9f3157eb62ce8cdf42 Mon Sep 17 00:00:00 2001 From: Taichi Kato Date: Sun, 31 May 2020 13:06:18 +0800 Subject: [PATCH 10/10] Updated UI to display 4 users nicely --- public/css/chat.css | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/public/css/chat.css b/public/css/chat.css index 6c6799b..aef5584 100644 --- a/public/css/chat.css +++ b/public/css/chat.css @@ -110,8 +110,10 @@ a { } #wrapper { - display: grid; - grid-gap: 10px; + display: flex; + flex-direction: column; + align-items: center; + flex-wrap: wrap; justify-content: center; padding: 0; margin: 0; @@ -142,12 +144,33 @@ a { border-radius: 0 0 10px 10px; padding: 10px; } +#remote-video:first-child:nth-last-child(1) { +/* -or- li:only-child { */ + max-height: 80vh; +} + +/* two items */ +#remote-video:first-child:nth-last-child(2), +#remote-video:first-child:nth-last-child(2) ~ #remote-video { + max-height: 40vh; +} + +/* three items */ +#remote-video:first-child:nth-last-child(3), +#remote-video:first-child:nth-last-child(3) ~ #remote-video { + max-height: 40vh; +} + +/* four items */ +#remote-video:first-child:nth-last-child(4), +#remote-video:first-child:nth-last-child(4) ~ #remote-video { + max-height: 40vh; +} #remote-video { padding: 0; - margin: 0; - width: 100%; - height: auto; + margin: 10px; + width: auto; border-radius: 10px; background-image: url(../images/loader.gif); background-size: 400px auto;