From 5f7c947268a76a6eaa1c4e1d4b3152a8dbf4cff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20D=C3=B6ring?= <simon.doering@stud.hs-bochum.de> Date: Sat, 6 Feb 2021 16:56:11 +0100 Subject: [PATCH] Add bitrate limiting by controller to frontend --- camera-server/src/janus/handlers.ts | 13 ++++--- .../src/socket-io/handlers/sender-handlers.ts | 16 ++++++++- sender/camera-sender.css | 18 ++++++++++ sender/camera-sender.html | 5 +-- sender/camera-sender.js | 34 +++++++++++++------ 5 files changed, 68 insertions(+), 18 deletions(-) diff --git a/camera-server/src/janus/handlers.ts b/camera-server/src/janus/handlers.ts index 0cbc889..0000fd6 100644 --- a/camera-server/src/janus/handlers.ts +++ b/camera-server/src/janus/handlers.ts @@ -7,9 +7,12 @@ export const setBitrate = async ( ): Promise<boolean> => { const currentSlotState = cameraSlotState[slot]; if (!currentSlotState.feedActive) { - console.log(`Tried to set bitrate for inactive slot ${slot}`); + console.log( + `Error: Tried to set bitrate of feed on slot ${slot} which has no active feed` + ); return false; } + console.log(`Setting bitrate of feed on slot ${slot} to ${newBitrate}`); try { const response = await janusAPI.configureVideoroomBitrate( currentSlotState.sessionId!, @@ -17,15 +20,17 @@ export const setBitrate = async ( newBitrate ); if (response.data?.janus === 'ack') { - console.log('Set new bitrate for slot ' + slot); + console.log(`Successfully set new bitrate of feed on slot ${slot}`); return true; } else { - console.log(`Error: Could not set new bitrate for slot ${slot}`); + console.log( + `Error: Could not set new bitrate of feed on slot ${slot}` + ); return false; } } catch (err) { console.log( - `Error: An unknown error occurred while setting the bitrate of slot ${slot}:`, + `Error: An unknown error occurred while setting the bitrate of the feed on slot ${slot}:`, err ); return false; diff --git a/camera-server/src/socket-io/handlers/sender-handlers.ts b/camera-server/src/socket-io/handlers/sender-handlers.ts index 691b1a4..0426a6b 100644 --- a/camera-server/src/socket-io/handlers/sender-handlers.ts +++ b/camera-server/src/socket-io/handlers/sender-handlers.ts @@ -38,6 +38,7 @@ const handleSetFeedId = ( ) => { let success = true; let message = ''; + let controllerBitrateLimit = null; try { const slot = socket.cameraSlot; @@ -138,6 +139,7 @@ const handleSetFeedId = ( console.log('Setting feed id of slot ' + slot + ' to ' + feedId); message = 'Successfully set feed id - you are now using this slot'; + controllerBitrateLimit = currentSlotState.controllerBitrateLimit; currentSlotState.feedActive = true; currentSlotState.feedId = feedId; @@ -161,7 +163,15 @@ const handleSetFeedId = ( } } - fn({ success, message }); + const response: { + success: boolean; + message: string; + controllerBitrateLimit?: number; + } = { success, message }; + if (controllerBitrateLimit != null) { + response.controllerBitrateLimit = controllerBitrateLimit; + } + fn(response); }; const handleChangeName = ( @@ -275,6 +285,10 @@ const handleSetBitrateLimit = async ( bitrateLimit = 0; } + console.log( + `Setting user bitrate limit of slot ${slot} to ${bitrateLimit}` + ); + const prevBitrate = currentSlotState.getCurrentBitrate(); currentSlotState.userBitrateLimit = bitrateLimit; const newBitrate = currentSlotState.getCurrentBitrate(); diff --git a/sender/camera-sender.css b/sender/camera-sender.css index 04653ed..57635a6 100644 --- a/sender/camera-sender.css +++ b/sender/camera-sender.css @@ -177,12 +177,30 @@ body { .bandwidth-form__input { flex: 2 0 50px; + padding: 4px; min-width: 0; + border: 2px solid transparent; + border-radius: 4px; margin-right: 4px; + outline: none; + box-shadow: none; +} + +.bandwidth-form__input:focus { + border-color: var(--light-blue-3); } .bandwidth-form__button { flex: 1 0 0; + padding: 4px; + border-radius: 4px; + outline: none; + border: none; + background: var(--light-blue-2); +} + +.bandwidth-form__button:hover { + background: var(--light-blue-3); } .main__controls { diff --git a/sender/camera-sender.html b/sender/camera-sender.html index 54f4af9..0a25bf5 100644 --- a/sender/camera-sender.html +++ b/sender/camera-sender.html @@ -58,10 +58,11 @@ <section id="options-container" class="main__options hidden"> <button id="options-toggle" class="options__toggle">Advanced options</button> <div id="options" class="options__body hidden"> + <p class="options__hint">Controller bitrate limit: <span id="controller-bitrate-limit">128</span> kbit/s</p> + <p class="options__hint">Your bitrate limit (0 means no limit): <span id="user-bitrate-limit">0</span> kbit/s</p> <form id="bandwidth-form"> - <p class="options__hint">While the camera is running, a bandwidth cap can be set here. 0 or negative means no cap.</p> <div class="bandwidth-form__control"> - <input type="text" placeholder="Bitrate [in kbit/s]" id="bandwidth-input" class="bandwidth-form__input" /> + <input type="number" min="0" required placeholder="Bitrate [in kbit/s]" id="bandwidth-input" class="bandwidth-form__input" /> <button type="submit" id="bandwidth-submit" class="bandwidth-form__button" disabled>Change</button> </div> </form> diff --git a/sender/camera-sender.js b/sender/camera-sender.js index 00bd473..91c9e07 100644 --- a/sender/camera-sender.js +++ b/sender/camera-sender.js @@ -74,6 +74,9 @@ document.addEventListener('DOMContentLoaded', function() { } }); socket.on('disconnect', handleUnexpectedSocketDisconnect); + socket.on('new_controller_bitrate_limit', function(data) { + setControllerBitrateLimit(Math.floor(data.bitrateLimit / 1000)); + }); }; function handleSenderInitResponse(data) { @@ -105,6 +108,7 @@ document.addEventListener('DOMContentLoaded', function() { showVideo(); showOptions(); + setControllerBitrateLimit(Math.floor(data.controllerBitrateLimit / 1000)); if (customNameAllowed) { var nameForm = document.getElementById('name-form'); nameForm.onsubmit = function(event) { @@ -221,18 +225,18 @@ document.addEventListener('DOMContentLoaded', function() { function handleBandwidthFormSubmit(event) { event.preventDefault(); var bandwidthInput = document.getElementById('bandwidth-input'); - var bitrateStr = bandwidthInput.value.trim(); - if (bitrateStr !== '' && !isNaN(bitrateStr) ) { - var bitrate = parseInt(bitrateStr) * 1000; - if (bitrate < 0) { - bandwidth = 0; - Janus.log('Negative bitrate input set to 0 (unlimited)'); + var bitrateLimit = parseInt(bandwidthInput.value); + bandwidthInput.value = ''; + socket.emit( + 'set_bitrate_limit', + { bitrateLimit: 1000 * bitrateLimit }, + function(data) { + console.log('set_bitrate_limit response', data); + if (data.success) { + setUserBitrateLimit(bitrateLimit); + } } - videoroomHandle.send({ message: { request: 'configure', bitrate }}); - bandwidthInput.value = ''; - } else { - alert('Invalid value for bitrate'); - } + ); } function handleMessage(msg, jsep) { @@ -286,6 +290,14 @@ document.addEventListener('DOMContentLoaded', function() { } } + function setUserBitrateLimit(bitrateLimit) { + document.getElementById('user-bitrate-limit').innerText = bitrateLimit; + } + + function setControllerBitrateLimit(bitrateLimit) { + document.getElementById('controller-bitrate-limit').innerText = bitrateLimit; + } + function cleanup() { hideVideo(); hideOptions(); -- GitLab