diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini
index 308d2947e..c8908f658 100644
--- a/UI/data/locale/en-US.ini
+++ b/UI/data/locale/en-US.ini
@@ -675,6 +675,9 @@ Basic.Settings.Output.Encoder="Encoder"
Basic.Settings.Output.SelectDirectory="Select Recording Directory"
Basic.Settings.Output.SelectFile="Select Recording File"
Basic.Settings.Output.EnforceBitrate="Enforce streaming service bitrate limits"
+Basic.Settings.Output.DynamicBitrate="Dynamically change bitrate to manage congestion"
+Basic.Settings.Output.DynamicBitrate.Beta="Dynamically change bitrate to manage congestion (Beta)"
+Basic.Settings.Output.DynamicBitrate.TT="Instead of dropping frames to reduce congestion, dynamically changes bitrate on the fly. Note that this can increase delay to viewers if there is significant sudden congestion. When the bitrate drops, it can take up to a few minutes to restore."
Basic.Settings.Output.Mode="Output Mode"
Basic.Settings.Output.Mode.Simple="Simple"
Basic.Settings.Output.Mode.Adv="Advanced"
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui
index 7e511263f..a10e48277 100644
--- a/UI/forms/OBSBasicSettings.ui
+++ b/UI/forms/OBSBasicSettings.ui
@@ -152,7 +152,7 @@
0
0
803
- 954
+ 977
@@ -4443,9 +4443,9 @@
0
- -114
+ 0
803
- 761
+ 781
@@ -5072,14 +5072,14 @@
-
- -
+
-
Basic.Settings.Advanced.Network.EnableNewSocketLoop
- -
+
-
false
@@ -5089,7 +5089,7 @@
- -
+
-
Qt::Horizontal
@@ -5097,11 +5097,21 @@
170
- 20
+ 1
+ -
+
+
+ Basic.Settings.Output.DynamicBitrate.TT
+
+
+ Basic.Settings.Output.DynamicBitrate.Beta
+
+
+
diff --git a/UI/window-basic-main-outputs.cpp b/UI/window-basic-main-outputs.cpp
index 93cd37c7c..802c5d1c2 100644
--- a/UI/window-basic-main-outputs.cpp
+++ b/UI/window-basic-main-outputs.cpp
@@ -784,6 +784,8 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
"NewSocketLoopEnable");
bool enableLowLatencyMode =
config_get_bool(main->Config(), "Output", "LowLatencyEnable");
+ bool enableDynBitrate =
+ config_get_bool(main->Config(), "Output", "DynamicBitrate");
obs_data_t *settings = obs_data_create();
obs_data_set_string(settings, "bind_ip", bindIP);
@@ -791,6 +793,7 @@ bool SimpleOutput::StartStreaming(obs_service_t *service)
enableNewSocketLoop);
obs_data_set_bool(settings, "low_latency_mode_enabled",
enableLowLatencyMode);
+ obs_data_set_bool(settings, "dyn_bitrate", enableDynBitrate);
obs_output_update(streamOutput, settings);
obs_data_release(settings);
@@ -1576,6 +1579,8 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
"NewSocketLoopEnable");
bool enableLowLatencyMode =
config_get_bool(main->Config(), "Output", "LowLatencyEnable");
+ bool enableDynBitrate =
+ config_get_bool(main->Config(), "Output", "DynamicBitrate");
obs_data_t *settings = obs_data_create();
obs_data_set_string(settings, "bind_ip", bindIP);
@@ -1583,6 +1588,7 @@ bool AdvancedOutput::StartStreaming(obs_service_t *service)
enableNewSocketLoop);
obs_data_set_bool(settings, "low_latency_mode_enabled",
enableLowLatencyMode);
+ obs_data_set_bool(settings, "dyn_bitrate", enableDynBitrate);
obs_output_update(streamOutput, settings);
obs_data_release(settings);
diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp
index c2083e169..cbd549396 100644
--- a/UI/window-basic-settings.cpp
+++ b/UI/window-basic-settings.cpp
@@ -466,6 +466,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->enableLowLatencyMode, CHECK_CHANGED, ADV_CHANGED);
HookWidget(ui->hotkeyFocusType, COMBO_CHANGED, ADV_CHANGED);
HookWidget(ui->autoRemux, CHECK_CHANGED, ADV_CHANGED);
+ HookWidget(ui->dynBitrate, CHECK_CHANGED, ADV_CHANGED);
/* clang-format on */
#define ADD_HOTKEY_FOCUS_TYPE(s) \
@@ -2264,6 +2265,8 @@ void OBSBasicSettings::LoadAdvancedSettings()
bool autoRemux = config_get_bool(main->Config(), "Video", "AutoRemux");
const char *hotkeyFocusType = config_get_string(
App()->GlobalConfig(), "General", "HotkeyFocusType");
+ bool dynBitrate =
+ config_get_bool(main->Config(), "Output", "DynamicBitrate");
loading = true;
@@ -2291,6 +2294,7 @@ void OBSBasicSettings::LoadAdvancedSettings()
ui->streamDelayPreserve->setChecked(preserveDelay);
ui->streamDelayEnable->setChecked(enableDelay);
ui->autoRemux->setChecked(autoRemux);
+ ui->dynBitrate->setChecked(dynBitrate);
SetComboByName(ui->colorFormat, videoColorFormat);
SetComboByName(ui->colorSpace, videoColorSpace);
@@ -2987,6 +2991,7 @@ void OBSBasicSettings::SaveAdvancedSettings()
SaveSpinBox(ui->reconnectMaxRetries, "Output", "MaxRetries");
SaveComboData(ui->bindToIP, "Output", "BindIP");
SaveCheckBox(ui->autoRemux, "Video", "AutoRemux");
+ SaveCheckBox(ui->dynBitrate, "Output", "DynamicBitrate");
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
QString newDevice = ui->monitoringDevice->currentData().toString();