From 003fca03990111c08e8f0c4bf8d76a812cf1dc4e Mon Sep 17 00:00:00 2001 From: Khush Jammu Date: Mon, 1 Jun 2020 12:45:10 +0800 Subject: [PATCH 1/3] add stub for bitrate downscaling --- public/js/chat.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/public/js/chat.js b/public/js/chat.js index 8634978..49838d9 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -499,6 +499,12 @@ function sendToAllDataChannels(message) { // } // End Fullscreen + +// Downscale own stream +function downscaleStreams() { + // To be implemented +} + // Mute microphone function muteMicrophone() { var audioTrack = null; From f72d77494e2050ffbffc5f007a43018fbb2e3b22 Mon Sep 17 00:00:00 2001 From: Arya Vohra Date: Tue, 2 Jun 2020 10:52:54 +0800 Subject: [PATCH 2/3] Testing bitrate/res downscaling on n>4 --- public/js/chat.js | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/public/js/chat.js b/public/js/chat.js index 49838d9..eb52b4e 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -225,6 +225,15 @@ var VideoChat = { break; } }; + + + // Downscale send resolution and bitrate if num in room > 4 + if (VideoChat.peerConnections.size > 3) { + for (var pc in VideoChat.peerConnections) { + downscaleStream(pc); + } + } + callback(uuid); }; }, @@ -500,9 +509,25 @@ function sendToAllDataChannels(message) { // End Fullscreen -// Downscale own stream -function downscaleStreams() { - // To be implemented +// Downscale single stream +async function downscaleStream(pc) { + height = 480; + rate = 800000; + try { + do { + h = height; + r = rate; + const [sender] = pc.getSenders(); + const ratio = sender.track.getSettings().height / height; + const params = sender.getParameters(); + if (!params.encodings) params.encodings = [{}]; // Firefox workaround! + params.encodings[0].scaleResolutionDownBy = Math.max(ratio, 1); + params.encodings[0].maxBitrate = rate; + await sender.setParameters(params); + } while (h != height); + } catch (e) { + logIt(e); + } } // Mute microphone From 38ead5c785bcdd87cb43338287f3eb31d0a50628 Mon Sep 17 00:00:00 2001 From: Arya Vohra Date: Tue, 2 Jun 2020 11:33:15 +0800 Subject: [PATCH 3/3] Downscaling to 360p for larger calls working --- public/css/chat.css | 2 +- public/js/chat.js | 79 +++++++++++++++++++++++++++------------------ public/landing.html | 15 ++++----- 3 files changed, 55 insertions(+), 41 deletions(-) diff --git a/public/css/chat.css b/public/css/chat.css index cc49ab6..3c80d13 100644 --- a/public/css/chat.css +++ b/public/css/chat.css @@ -145,7 +145,7 @@ a { padding: 10px; } #remote-video:first-child:nth-last-child(1) { -/* -or- li:only-child { */ + /* -or- li:only-child { */ max-height: 80vh; } diff --git a/public/js/chat.js b/public/js/chat.js index eb52b4e..3404d46 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -204,7 +204,9 @@ var VideoChat = { break; case "disconnected": logIt("disconnected - UUID " + uuid); - VideoChat.remoteVideoWrapper.removeChild(document.querySelectorAll(`[uuid="${uuid}"]`)[0]); + VideoChat.remoteVideoWrapper.removeChild( + document.querySelectorAll(`[uuid="${uuid}"]`)[0] + ); VideoChat.connected.delete(uuid); VideoChat.peerConnections.delete(uuid); dataChannel.delete(uuid); @@ -225,15 +227,6 @@ var VideoChat = { break; } }; - - - // Downscale send resolution and bitrate if num in room > 4 - if (VideoChat.peerConnections.size > 3) { - for (var pc in VideoChat.peerConnections) { - downscaleStream(pc); - } - } - callback(uuid); }; }, @@ -370,6 +363,12 @@ var VideoChat = { VideoChat.connected.set(uuid, true); // Hide caption status text captionText.fadeOut(); + // Downscale send resolution and bitrate if num in room > 4 + if (VideoChat.peerConnections.size > 3) { + VideoChat.peerConnections.forEach(function (value, key, map) { + downscaleStream(value); + }); + } // 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); @@ -508,16 +507,18 @@ function sendToAllDataChannels(message) { // } // End Fullscreen - // Downscale single stream -async function downscaleStream(pc) { - height = 480; +async function downscaleStream(pc, applying = false) { + height = 240; rate = 800000; + if (applying) return; try { + applying = true; do { h = height; - r = rate; - const [sender] = pc.getSenders(); + const sender = pc.getSenders().find(function (s) { + return s.track.kind === "video"; + }); const ratio = sender.track.getSettings().height / height; const params = sender.getParameters(); if (!params.encodings) params.encodings = [{}]; // Firefox workaround! @@ -527,6 +528,8 @@ async function downscaleStream(pc) { } while (h != height); } catch (e) { logIt(e); + } finally { + applying = false; } } @@ -542,7 +545,7 @@ function muteMicrophone() { }); audioTrack.enabled = VideoChat.audioEnabled; }); - + // select mic button and mic button text const micButtonIcon = document.getElementById("mic-icon"); const micButtonText = document.getElementById("mic-text"); @@ -894,15 +897,16 @@ function uuidToColor(uuid) { // Using uuid to generate random. unique pastel color var hash = 0; for (var i = 0; i < uuid.length; i++) { - hash = uuid.charCodeAt(i) + ((hash << 5) - hash); - hash = hash & hash; + hash = uuid.charCodeAt(i) + ((hash << 5) - hash); + hash = hash & hash; } var hue = Math.abs(hash % 360); - console.log(hue); // Ensure color is not similar to other colors - var availColors = Array.from({length: 18}, (x,i) => i*20); - VideoChat.peerColors.forEach(function(value, key, map) {availColors[Math.floor(value/20)] = null}); - if (availColors[Math.floor(hue/20)] == null) { + var availColors = Array.from({ length: 18 }, (x, i) => i * 20); + VideoChat.peerColors.forEach(function (value, key, map) { + availColors[Math.floor(value / 20)] = null; + }); + if (availColors[Math.floor(hue / 20)] == null) { for (var i = 0; i < availColors.length; i++) { if (availColors[i] != null) { hue = (hue % 20) + availColors[i]; @@ -917,7 +921,9 @@ function uuidToColor(uuid) { // Sets the border color of uuid's stream function setStreamColor(uuid) { const color = uuidToColor(uuid); - document.querySelectorAll(`[uuid="${uuid}"]`)[0].style.border = `3px solid ${color}`; + document.querySelectorAll( + `[uuid="${uuid}"]` + )[0].style.border = `3px solid ${color}`; VideoChat.peerColors[uuid] = color; } @@ -952,18 +958,27 @@ function togglePictureInPicture() { logIt("Error exiting pip."); logIt(error); }); - } else if (VideoChat.remoteVideoWrapper.lastChild.webkitPresentationMode === "inline") { - VideoChat.remoteVideoWrapper.lastChild.webkitSetPresentationMode("picture-in-picture"); } else if ( - VideoChat.remoteVideoWrapper.lastChild.webkitPresentationMode === "picture-in-picture" + VideoChat.remoteVideoWrapper.lastChild.webkitPresentationMode === "inline" ) { - VideoChat.remoteVideoWrapper.lastChild.webkitSetPresentationMode("inline"); + VideoChat.remoteVideoWrapper.lastChild.webkitSetPresentationMode( + "picture-in-picture" + ); + } else if ( + VideoChat.remoteVideoWrapper.lastChild.webkitPresentationMode === + "picture-in-picture" + ) { + VideoChat.remoteVideoWrapper.lastChild.webkitSetPresentationMode( + "inline" + ); } else { - VideoChat.remoteVideoWrapper.lastChild.requestPictureInPicture().catch((error) => { - alert( - "You must be connected to another person to enter picture in picture." - ); - }); + VideoChat.remoteVideoWrapper.lastChild + .requestPictureInPicture() + .catch((error) => { + alert( + "You must be connected to another person to enter picture in picture." + ); + }); } } else { alert( diff --git a/public/landing.html b/public/landing.html index 7e1b62d..693a094 100755 --- a/public/landing.html +++ b/public/landing.html @@ -67,9 +67,9 @@ class="mt-0 mb-32 reveal-from-bottom" data-reveal-delay="300" > - Simple, Secure, and Fast. Peer to peer group video - calling provides quality and latency simply not - available with traditional technology. + Simple, Secure, and Fast. Peer to peer group video calling + provides quality and latency simply not available with + traditional technology.

@@ -248,8 +247,8 @@

Total Privacy and Security

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. + and end to end state of the art encryption means your + calls are exactly that. Your calls.