diff --git a/labs/bbb-webrtc-sfu/config/default.example.yml b/labs/bbb-webrtc-sfu/config/default.example.yml
index 565d12ea97d7aca479ddb84eeb91d9125cba45f6..e1b4497fe58bf0b2798611eac70688ff3c504257 100644
--- a/labs/bbb-webrtc-sfu/config/default.example.yml
+++ b/labs/bbb-webrtc-sfu/config/default.example.yml
@@ -18,9 +18,13 @@ to-akka: "to-akka-apps-redis-channel"
 from-akka: "from-akka-apps-redis-channel"
 common-message-version: "2.x"
 webcam-force-h264: true
+# Target bitrate (kbps) for webcams. Value 0 leaves it unconstrained.
+webcam-target-bitrate: 300000
 screenshare-force-h264: true
 screenshare-preferred-h264-profile: "42e01f"
 screenshareKeyframeInterval: 2
+# Target bitrate (kbps) for screenshare. Value 0 leaves it unconstrained.
+screenshare-target-bitrate: 0
 
 recordScreenSharing: true
 recordWebcams: false
diff --git a/labs/bbb-webrtc-sfu/lib/audio/audio.js b/labs/bbb-webrtc-sfu/lib/audio/audio.js
index 8e6667e65adcd386940cdf5c6961b3e421b3f8be..385c7d8e304a0d3beee3695649d10bde8721e810 100644
--- a/labs/bbb-webrtc-sfu/lib/audio/audio.js
+++ b/labs/bbb-webrtc-sfu/lib/audio/audio.js
@@ -255,7 +255,7 @@ module.exports = class Audio extends BaseProvider {
       return Promise.resolve();
     }
     catch (err) {
-      reject(this._handleError(LOG_PREFIX, err, "recv", this.userId));
+      throw (this._handleError(LOG_PREFIX, err, "recv", this.userId));
     }
   };
 
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js
index a1eac49832889e4b81062107c9d48264a8b88617..7b1345fdb7ccf5e13e95513d6a84f1c70db8b325 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js
@@ -60,13 +60,19 @@ module.exports = class SdpSession extends MediaSession {
           return reject(this._handleError(C.ERROR.MEDIA_NO_AVAILABLE_CODEC));
         }
 
+        const { targetBitrate } = this._options;
+
+        if (answer && targetBitrate && targetBitrate !== '0') {
+          this._answer.addBandwidth('video', targetBitrate);
+        }
+
         if (this._type !== 'WebRtcEndpoint') {
           this._offer.replaceServerIpv4(kurentoIp);
-          return resolve(answer);
+          return resolve(this._answer? this._answer._plainSdp : null);
         }
 
         await this._MediaServer.gatherCandidates(this._mediaElement);
-        resolve(answer);
+        resolve(this._answer._plainSdp);
       }
       catch (err) {
         return reject(this._handleError(err));
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js
index 6f35e3b7c7d64b083b752d6a62c8652da012d0b6..a19912bdba9d2002543a2f01d5e57d050c1c6169 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js
@@ -54,6 +54,20 @@ module.exports = class SdpWrapper {
     return this._mediaCapabilities.hasAvailableAudioCodec;
   }
 
+  addBandwidth (type, bw) {
+    // Bandwidth format
+    // { type: 'TIAS or AS', limit: 2048000 }
+    for(var ml of this._jsonSdp.media) {
+      if(ml.type === type ) {
+        ml['bandwidth'] = [];
+        ml.bandwidth.push({ type: 'TIAS', limit: (bw >>> 0) * 1000 });
+        ml.bandwidth.push({ type: 'AS', limit: bw });
+      }
+    }
+
+    this._plainSdp = transform.write(this._jsonSdp);
+  }
+
   /**
    * Given a SDP, test if there is an audio description in it
    * @return {boolean}    true if there is more than one video description, else false
diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js b/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js
index f2eaa8cc957533ac649516f195c1612846a281ce..aeab9fc3afc1e2860d09a8697cdbcc0f2b12952c 100644
--- a/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js
+++ b/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js
@@ -21,6 +21,7 @@ const kurentoIp = config.get('kurentoIp');
 const localIpAddress = config.get('localIpAddress');
 const FORCE_H264 = config.get('screenshare-force-h264');
 const PREFERRED_H264_PROFILE = config.get('screenshare-preferred-h264-profile');
+const SCREENSHARE_TARGET_BITRATE = config.get('screenshare-target-bitrate');
 const SHOULD_RECORD = config.get('recordScreenSharing');
 const KEYFRAME_INTERVAL = config.get('screenshareKeyframeInterval');
 const LOG_PREFIX = "[screenshare]";
@@ -274,7 +275,7 @@ module.exports = class Screenshare extends BaseProvider {
   _startPresenter (sdpOffer) {
     return new Promise(async (resolve, reject) => {
       try {
-        const retSource = await this.mcs.publish(this.mcsUserId, this._meetingId, 'WebRtcEndpoint', {descriptor: sdpOffer});
+        const retSource = await this.mcs.publish(this.mcsUserId, this._meetingId, 'WebRtcEndpoint', {descriptor: sdpOffer, targetBitrate: SCREENSHARE_TARGET_BITRATE });
 
         this._presenterEndpoint = retSource.sessionId;
         sharedScreens[this._voiceBridge] = this._presenterEndpoint;
diff --git a/labs/bbb-webrtc-sfu/lib/video/video.js b/labs/bbb-webrtc-sfu/lib/video/video.js
index 9250d86d90774f12d12590a6f0526ffe9b28171e..be068de8beda19dafd62708f32faac32df79c4c3 100644
--- a/labs/bbb-webrtc-sfu/lib/video/video.js
+++ b/labs/bbb-webrtc-sfu/lib/video/video.js
@@ -9,6 +9,7 @@ const Messaging = require('../bbb/messages/Messaging');
 const h264_sdp = require('../h264-sdp');
 const BaseProvider = require('../base/BaseProvider');
 const FORCE_H264 = config.get('webcam-force-h264');
+const WEBCAM_TARGET_BITRATE = config.get('webcam-target-bitrate');
 const SHOULD_RECORD = config.get('recordWebcams');
 const LOG_PREFIX = "[video]";
 
@@ -259,7 +260,7 @@ module.exports = class Video extends BaseProvider {
     return new Promise(async (resolve, reject) => {
       try {
         if (this.shared) {
-          let { answer, sessionId } = await this.mcs.publish(this.userId, this.meetingId, type, { descriptor });
+          let { answer, sessionId } = await this.mcs.publish(this.userId, this.meetingId, type, { descriptor, targetBitrate: WEBCAM_TARGET_BITRATE });
           this.mediaId = sessionId;
           sharedWebcams[this.id] = this.mediaId;
           return resolve(answer);