diff --git a/bigbluebutton-html5/imports/api/users/server/modifiers/setUserEffectiveConnectionType.js b/bigbluebutton-html5/imports/api/users/server/modifiers/setUserEffectiveConnectionType.js
index ce640717137eed4083f45712eb58d53c199fd22c..e5cf8272ba50f9059a810db99304369a648fb9f1 100644
--- a/bigbluebutton-html5/imports/api/users/server/modifiers/setUserEffectiveConnectionType.js
+++ b/bigbluebutton-html5/imports/api/users/server/modifiers/setUserEffectiveConnectionType.js
@@ -24,7 +24,7 @@ export default function setUserEffectiveConnectionType(meetingId, userId, effect
     }
 
     if (numChanged) {
-      Logger.info(`Update user ${userId} effective connection to ${effectiveConnectionType}`);
+      Logger.info(`Updated user ${userId} effective connection to ${effectiveConnectionType}`);
     }
   };
 
diff --git a/bigbluebutton-html5/imports/ui/components/app/component.jsx b/bigbluebutton-html5/imports/ui/components/app/component.jsx
index 79645856ea824b5a75c8987cbc65f2427667eb39..34bcff2115b6eb941ea236f0660bcacbe6acc064 100755
--- a/bigbluebutton-html5/imports/ui/components/app/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/app/component.jsx
@@ -7,7 +7,6 @@ import browser from 'browser-detect';
 import PanelManager from '/imports/ui/components/panel-manager/component';
 import PollingContainer from '/imports/ui/components/polling/container';
 import logger from '/imports/startup/client/logger';
-import { makeCall } from '/imports/ui/services/api';
 import ActivityCheckContainer from '/imports/ui/components/activity-check/container';
 import ToastContainer from '../toast/container';
 import ModalContainer from '../modal/container';
@@ -15,6 +14,7 @@ import NotificationsBarContainer from '../notifications-bar/container';
 import AudioContainer from '../audio/container';
 import ChatAlertContainer from '../chat/alert/container';
 import WaitingNotifierContainer from '/imports/ui/components/waiting-users/alert/container';
+import { startBandwidthMonitoring, updateNavigatorConnection } from '/imports/ui/services/network-information/index';
 import { styles } from './styles';
 
 const MOBILE_MEDIA = 'only screen and (max-width: 40em)';
@@ -98,6 +98,8 @@ class App extends Component {
       navigator.connection.addEventListener('change', this.handleNetworkConnection);
     }
 
+    startBandwidthMonitoring();
+
     logger.info({ logCode: 'app_component_componentdidmount' }, 'Client loaded successfully');
   }
 
@@ -115,8 +117,7 @@ class App extends Component {
   }
 
   handleNetworkConnection() {
-    const { effectiveType } = navigator.connection;
-    makeCall('setUserEffectiveConnectionType', effectiveType);
+    updateNavigatorConnection(navigator.connection);
   }
 
   renderPanel() {
diff --git a/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx b/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx
index 84e24fe1a8e4d0a412e027a6e6db5b091d5ea878..c1b53892010031b5db6eb2f90f986fba01c04893 100755
--- a/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/video-provider/component.jsx
@@ -7,6 +7,13 @@ import ReconnectingWebSocket from 'reconnecting-websocket';
 import logger from '/imports/startup/client/logger';
 import { Session } from 'meteor/session';
 import browser from 'browser-detect';
+import {
+  currentWebcamConnections,
+  getCurrentWebcams,
+  deleteWebcamConnection,
+  newWebcamConnection,
+  updateWebcamStats,
+} from '/imports/ui/services/network-information/index';
 import { tryGenerateIceCandidates } from '../../../utils/safari-webrtc';
 import Auth from '/imports/ui/services/auth';
 
@@ -157,6 +164,28 @@ class VideoProvider extends Component {
 
     this.visibility.onVisible(this.unpauseViewers);
     this.visibility.onHidden(this.pauseViewers);
+
+    this.currentWebcamsStatsInterval = setInterval(() => {
+      const currentWebcams = getCurrentWebcams();
+      if (!currentWebcams) return;
+
+      const { payload } = currentWebcams;
+
+      payload.forEach((id) => {
+        const peer = this.webRtcPeers[id];
+
+        const hasLocalStream = peer && peer.started === true
+          && peer.peerConnection.getLocalStreams().length > 0;
+        const hasRemoteStream = peer && peer.started === true
+          && peer.peerConnection.getRemoteStreams().length > 0;
+
+        if (hasLocalStream) {
+          this.customGetStats(peer.peerConnection, peer.peerConnection.getLocalStreams()[0].getVideoTracks()[0], (stats => updateWebcamStats(id, stats)));
+        } else if (hasRemoteStream) {
+          this.customGetStats(peer.peerConnection, peer.peerConnection.getRemoteStreams()[0].getVideoTracks()[0], (stats => updateWebcamStats(id, stats)));
+        }
+      });
+    }, 10000);
   }
 
   componentWillUpdate({ users, userId }) {
@@ -194,6 +223,8 @@ class VideoProvider extends Component {
       this.stopWebRTCPeer(id);
     });
 
+    clearInterval(this.currentWebcamsStatsInterval);
+
     // Close websocket connection to prevent multiple reconnects from happening
     this.ws.close();
   }
@@ -446,6 +477,8 @@ class VideoProvider extends Component {
         webRtcPeer.dispose();
       }
       delete this.webRtcPeers[id];
+      deleteWebcamConnection(id);
+      currentWebcamConnections(this.webRtcPeers);
     } else {
       this.logger('warn', 'No WebRTC peer to stop (not an error)', { cameraId: id });
     }
@@ -527,6 +560,9 @@ class VideoProvider extends Component {
       if (this.webRtcPeers[id].peerConnection) {
         this.webRtcPeers[id].peerConnection.oniceconnectionstatechange = this._getOnIceConnectionStateChangeCallback(id);
       }
+      console.log('VideoProvider.createWebRTCPeer', this.webRtcPeers);
+      newWebcamConnection({ userId: id, peer: this.webRtcPeers[id] });
+      currentWebcamConnections(this.webRtcPeers);
     }
   }
 
@@ -765,9 +801,9 @@ class VideoProvider extends Component {
 
       let videoBitrate;
       if (videoStats.packetsReceived > 0) { // Remote video
-        videoLostPercentage = ((videoStats.packetsLost / ((videoStats.packetsLost + videoStats.packetsReceived) * 100)) || 0).toFixed(1);
+        videoLostPercentage = ((videoStats.packetsLost / ((videoStats.packetsLost + videoStats.packetsReceived)) * 100) || 0).toFixed(1);
         videoBitrate = Math.floor(videoKbitsReceivedPerSecond || 0);
-        videoLostRecentPercentage = ((videoIntervalPacketsLost / ((videoIntervalPacketsLost + videoIntervalPacketsReceived) * 100)) || 0).toFixed(1);
+        videoLostRecentPercentage = ((videoIntervalPacketsLost / ((videoIntervalPacketsLost + videoIntervalPacketsReceived)) * 100) || 0).toFixed(1);
       } else {
         videoLostPercentage = (((videoStats.packetsLost / (videoStats.packetsLost + videoStats.packetsSent)) * 100) || 0).toFixed(1);
         videoBitrate = Math.floor(videoKbitsSentPerSecond || 0);
diff --git a/bigbluebutton-html5/imports/ui/services/network-information/index.js b/bigbluebutton-html5/imports/ui/services/network-information/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..414b4943870b08bfd9b2a1c2bd0615abc840334d
--- /dev/null
+++ b/bigbluebutton-html5/imports/ui/services/network-information/index.js
@@ -0,0 +1,99 @@
+const NetworkInformationCollection = new Mongo.Collection(null);
+
+const NAVIGATOR_CONNECTION = 'NAVIGATOR_CONNECTION';
+const NUMBER_OF_WEBCAMS_CHANGED = 'NUMBER_OF_WEBCAMS_CHANGED';
+const STARTED_WEBCAM_SHARING = 'STARTED_WEBCAM_SHARING';
+const STOPPED_WEBCAM_SHARING = 'STOPPED_WEBCAM_SHARING';
+const WEBCAMS_GET_STATUS = 'WEBCAMS_GET_STATUS';
+
+let monitoringIntervalRef;
+
+export const currentWebcamConnections = (webrtcConnections) => {
+  const doc = {
+    timestamp: new Date().getTime(),
+    event: NUMBER_OF_WEBCAMS_CHANGED,
+    payload: Object.keys(webrtcConnections),
+  };
+
+  NetworkInformationCollection.insert(doc);
+};
+
+export const deleteWebcamConnection = (id) => {
+  const doc = {
+    timestamp: new Date().getTime(),
+    event: STOPPED_WEBCAM_SHARING,
+    payload: { id },
+  };
+
+  NetworkInformationCollection.insert(doc);
+};
+
+export const getCurrentWebcams = () => NetworkInformationCollection
+  .findOne({
+    event: NUMBER_OF_WEBCAMS_CHANGED,
+  }, { sort: { timestamp: -1 } });
+
+export const newWebcamConnection = (webRtcPeer) => {
+  const { userId, peer } = webRtcPeer;
+  const { id: mediaStreamId } = peer.getLocalStream();
+  const doc = {
+    timestamp: new Date().getTime(),
+    event: STARTED_WEBCAM_SHARING,
+    payload: {
+      userId,
+      mediaStreamId,
+    },
+  };
+
+  NetworkInformationCollection.insert(doc);
+};
+
+export const startBandwidthMonitoring = () => {
+  monitoringIntervalRef = setInterval(() => {
+    console.log('startBandwidthMonitoring', NetworkInformationCollection.find({}).fetch());
+  }, 15000);
+};
+
+export const stopBandwidthMonitoring = () => {
+  clearInterval(monitoringIntervalRef);
+};
+
+export const updateNavigatorConnection = ({ effectiveType, downlink, rtt }) => {
+  const doc = {
+    timestamp: new Date().getTime(),
+    event: NAVIGATOR_CONNECTION,
+    payload: {
+      effectiveType,
+      downlink,
+      rtt,
+    },
+  };
+
+  NetworkInformationCollection.insert(doc);
+};
+
+export const updateWebcamStats = (id, stats) => {
+  if (!stats) return;
+
+  const { video } = stats;
+
+  const doc = {
+    timestamp: new Date().getTime(),
+    event: WEBCAMS_GET_STATUS,
+    payload: { id, stats: video },
+  };
+
+  NetworkInformationCollection.insert(doc);
+};
+
+export default {
+  NetworkInformationCollection,
+  currentWebcamConnections,
+  deleteWebcamConnection,
+  getCurrentWebcams,
+  newWebcamConnection,
+  startBandwidthMonitoring,
+  stopBandwidthMonitoring,
+  updateNavigatorConnection,
+  updateWebcamStats,
+};
diff --git a/bigbluebutton-html5/private/locales/en.json b/bigbluebutton-html5/private/locales/en.json
index af009fa54a5209716f57aeef4d53865f5974fa88..8d1bbe2700561fd5b40aebaf50291941e1e9c75b 100755
--- a/bigbluebutton-html5/private/locales/en.json
+++ b/bigbluebutton-html5/private/locales/en.json
@@ -564,5 +564,5 @@
     "app.actionsBar.actionsDropdown.stopShareExternalVideo": "Stop sharing video",
     "app.network.connection.effective.slow": "We're noticing connectivity issues.",
     "app.network.connection.effective.slow.help": "How to fix it?",
-    "app.externalVideo.noteLabel": "Note: Shared YouTube videos will not appear in the recording",
+    "app.externalVideo.noteLabel": "Note: Shared YouTube videos will not appear in the recording"
 }