diff --git a/docs/configuration.md b/docs/configuration.md
index f5e31f72..1f31d74c 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -1316,6 +1316,29 @@ editing the `conf` file in a text editor. Use the examples as reference.
+### max_bitrate
+
+
+
+ Description
+
+ The maximum bitrate (in Kbps) that Sunshine will encode the stream at. If set to 0, it will always use the bitrate requested by Moonlight.
+
+
+
+ Default
+ @code{}
+ 0
+ @endcode
+
+
+ Example
+ @code{}
+ max_bitrate = 5000
+ @endcode
+
+
+
### min_fps_factor
diff --git a/package.json b/package.json
index 666acfcd..b5c5325c 100644
--- a/package.json
+++ b/package.json
@@ -10,12 +10,12 @@
"dependencies": {
"@lizardbyte/shared-web": "2024.921.191855",
"vue": "3.5.13",
- "vue-i18n": "11.0.1"
+ "vue-i18n": "11.1.1"
},
"devDependencies": {
"@vitejs/plugin-vue": "4.6.2",
"serve": "14.2.3",
- "vite": "4.5.2",
+ "vite": "4.5.9",
"vite-plugin-ejs": "1.6.4"
}
}
diff --git a/packaging/linux/flatpak/deps/shared-modules b/packaging/linux/flatpak/deps/shared-modules
index 802d8041..85cf3273 160000
--- a/packaging/linux/flatpak/deps/shared-modules
+++ b/packaging/linux/flatpak/deps/shared-modules
@@ -1 +1 @@
-Subproject commit 802d80416180436ff9929ce2a2e098203ace078e
+Subproject commit 85cf3273f89eeede7dcb301f77a7ced32fecaa3a
diff --git a/scripts/requirements.txt b/scripts/requirements.txt
index cd2ef869..7cfbae48 100644
--- a/scripts/requirements.txt
+++ b/scripts/requirements.txt
@@ -1,2 +1,2 @@
-Babel==2.16.0
+Babel==2.17.0
clang-format
diff --git a/src/config.cpp b/src/config.cpp
index 77ed1ce1..e01deb91 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -513,7 +513,10 @@ namespace config {
{}, // mode_remapping
{} // wa
}, // display_device
+
1, // min_fps_factor
+ 0 // max_bitrate
+
"1920x1080x60", // fallback_mode
};
@@ -1183,6 +1186,7 @@ namespace config {
bool_f(vars, "dd_wa_hdr_toggle", video.dd.wa.hdr_toggle);
int_between_f(vars, "min_fps_factor", video.min_fps_factor, {1, 3});
+ int_f(vars, "max_bitrate", video.max_bitrate);
string_f(vars, "fallback_mode", video.fallback_mode);
path_f(vars, "pkey", nvhttp.pkey);
diff --git a/src/config.h b/src/config.h
index 3693dc6e..7022134e 100644
--- a/src/config.h
+++ b/src/config.h
@@ -141,6 +141,8 @@ namespace config {
} dd;
int min_fps_factor; // Minimum fps target, determines minimum frame time
+ int max_bitrate; // Maximum bitrate, sets ceiling in kbps for bitrate requested from client
+
std::string fallback_mode;
};
diff --git a/src/video.cpp b/src/video.cpp
index 0951f357..73f67b10 100644
--- a/src/video.cpp
+++ b/src/video.cpp
@@ -1711,7 +1711,8 @@ namespace video {
}
}
- auto bitrate = config.bitrate * 1000;
+ auto bitrate = ((config::video.max_bitrate > 0) ? std::min(config.bitrate, config::video.max_bitrate) : config.bitrate) * 1000;
+ BOOST_LOG(info) << "Streaming bitrate is " << bitrate;
ctx->rc_max_rate = bitrate;
ctx->bit_rate = bitrate;
diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html
index fb3bb738..16e4d2ac 100644
--- a/src_assets/common/assets/web/config.html
+++ b/src_assets/common/assets/web/config.html
@@ -201,6 +201,7 @@
"headless_mode": "disabled",
"double_refreshrate": "disabled",
"min_fps_factor": 1,
+ "max_bitrate": 0,
},
},
{
diff --git a/src_assets/common/assets/web/configs/tabs/audiovideo/DisplayModesSettings.vue b/src_assets/common/assets/web/configs/tabs/audiovideo/DisplayModesSettings.vue
index c74d4a6c..2bf997ba 100644
--- a/src_assets/common/assets/web/configs/tabs/audiovideo/DisplayModesSettings.vue
+++ b/src_assets/common/assets/web/configs/tabs/audiovideo/DisplayModesSettings.vue
@@ -17,6 +17,13 @@ const config = ref(props.config)
{{ $t('config.min_fps_factor_desc') }}
+
+
+
+
{{ $t("config.max_bitrate") }}
+
+
{{ $t("config.max_bitrate_desc") }}
+