diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini
index 8a24e7265..c95632577 100644
--- a/UI/data/locale/en-US.ini
+++ b/UI/data/locale/en-US.ini
@@ -935,6 +935,7 @@ Basic.Settings.Appearance.General.NoVariant="No Styles Available"
# basic mode 'stream' settings
Basic.Settings.Stream="Stream"
+Basic.Settings.Stream.Destination="Destination"
Basic.Settings.Stream.Custom.UseAuthentication="Use authentication"
Basic.Settings.Stream.Custom.Username="Username"
Basic.Settings.Stream.Custom.Password="Password"
@@ -960,6 +961,16 @@ Basic.Settings.Stream.Recommended.MaxResolution="Maximum Resolution: %1"
Basic.Settings.Stream.Recommended.MaxFPS="Maximum FPS: %1"
Basic.Settings.Stream.SpecifyCustomServer="Specify Custom Server..."
Basic.Settings.Stream.ServiceCustomServer="Custom Server"
+Basic.Settings.Stream.EnableMultitrackVideo="Enable %1"
+Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrate="Maximum Streaming Bandwidth"
+Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrateAuto="Auto"
+Basic.Settings.Stream.MultitrackVideoMaximumVideoTracks="Maximum Video Tracks"
+Basic.Settings.Stream.MultitrackVideoMaximumVideoTracksAuto="Auto"
+Basic.Settings.Stream.MultitrackVideoStreamDumpEnable="Enable stream dump to FLV (uses simple recording file settings)"
+Basic.Settings.Stream.MultitrackVideoConfigOverride="Config Override (JSON)"
+Basic.Settings.Stream.MultitrackVideoConfigOverrideEnable="Enable Config Override"
+Basic.Settings.Stream.MultitrackVideoLabel="Multitrack Video"
+Basic.Settings.Stream.AdvancedOptions="Advanced Options"
# basic mode 'output' settings
Basic.Settings.Output="Output"
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui
index 504c48ed9..a144805d3 100644
--- a/UI/forms/OBSBasicSettings.ui
+++ b/UI/forms/OBSBasicSettings.ui
@@ -1204,366 +1204,614 @@
-
-
-
- QFormLayout::AllNonFixedFieldsGrow
+
+
+ QFrame::NoFrame
+
+
+ QFrame::Plain
+
+
+ true
+
+
+
+
+ 0
+ 0
+
-
- Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
- -
-
-
- Basic.AutoConfig.StreamPage.Server
-
-
-
- -
-
-
-
- 0
- 0
-
-
-
- 1
-
-
-
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Basic.Settings.Stream.Destination
+
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
- 0
+ 9
- 0
+ 2
- 0
+ 9
- 0
+ 9
-
-
-
+
-
+
+
+ Basic.AutoConfig.StreamPage.Server
+
+
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ 1
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+
+
+
+ -
+
+
+ Basic.Settings.Stream.ServiceCustomServer
+
+
+ serviceCustomServer
+
+
+
+ -
+
+
+ -
+
+
+ Basic.AutoConfig.StreamPage.StreamKey
+
+
+ true
+
+
+ key
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ Show
+
+
+
+ -
+
+
+
+
+
+ -4
+
+
+ Basic.AutoConfig.StreamPage.GetStreamKey
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 170
+ 0
+
+
+
+
+ -
+
+
-
+
+
+ PointingHandCursor
+
+
+ Basic.AutoConfig.StreamPage.ConnectAccount
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 0
+
+
+
+
+
+
+ -
+
+
+ Basic.AutoConfig.StreamPage.ConnectedAccount
+
+
+
+ -
+
+
+ 8
+
+
+ 7
+
+
+ 7
+
+
-
+
+
+ font-weight: bold
+
+
+ Auth.LoadingChannel.Title
+
+
+
+ -
+
+
+ Basic.AutoConfig.StreamPage.DisconnectAccount
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+
+
+ -
+
+
-
+
+
+ Basic.AutoConfig.StreamPage.UseStreamKeyAdvanced
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 0
+
+
+
+
+
+
+ -
+
+
+ Basic.Settings.Stream.Custom.UseAuthentication
+
+
+
+ -
+
+
+ Basic.Settings.Stream.Custom.Username
+
+
+ authUsername
+
+
+
+ -
+
+
+ -
+
+
+ Basic.Settings.Stream.Custom.Password
+
+
+ authPw
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+ QLineEdit::Password
+
+
+
+ -
+
+
+ Show
+
+
+
+
+
-
-
+
+ -
+
+
+
+ 0
+ 0
+
+
+
+ Basic.Settings.Stream.MultitrackVideoLabel
+
+
+
+ QFormLayout::AllNonFixedFieldsGrow
+
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
+
- 0
+ 9
- 0
+ 2
- 0
+ 9
- 0
+ 9
-
-
-
+
-
+
+
+ Basic.Settings.Stream.EnableMultitrackVideo
+
+
+
+ -
+
+
+ MultitrackVideo.Info
+
+
+ Qt::RichText
+
+
+ true
+
+
+ true
+
+
+
+ -
+
+
+ Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrate
+
+
+
+ -
+
+
-
+
+
+ Basic.Settings.Stream.MultitrackVideoMaximumAggregateBitrateAuto
+
+
+ QSizePolicy::Minimum, QSizePolicy::Minimum
+
+
+
+ -
+
+
+ QSizePolicy::MinimumExpanding, QSizePolicy::Minimum
+
+
+ 500
+
+
+ 1000000
+
+
+ 8000
+
+
+
+
+
+ -
+
+
+ Basic.Settings.Stream.MultitrackVideoMaximumVideoTracks
+
+
+
+ -
+
+
-
+
+
+ Basic.Settings.Stream.MultitrackVideoMaximumVideoTracksAuto
+
+
+ QSizePolicy::Minimum, QSizePolicy::Minimum
+
+
+
+ -
+
+
+ QSizePolicy::MinimumExpanding, QSizePolicy::Minimum
+
+
+ 0
+
+
+ 100
+
+
+ 0
+
+
+
+
+
+ -
+
+
+ Basic.Settings.Stream.MultitrackVideoStreamDumpEnable
+
+
+
+ -
+
+
+ Basic.Settings.Stream.MultitrackVideoConfigOverrideEnable
+
+
+
+ -
+
+
+ Basic.Settings.Stream.MultitrackVideoConfigOverride
+
+
+
+ -
+
+
+ QSizePolicy::Preferred, QSizePolicy::MinimumExpanding
+
+
-
-
- -
-
-
- Basic.Settings.Stream.ServiceCustomServer
-
-
- serviceCustomServer
-
-
-
- -
-
-
- -
-
-
- Basic.AutoConfig.StreamPage.StreamKey
-
-
- true
-
-
- key
-
-
-
- -
-
-
-
- 0
+
+ -
+
+
+
+ 0
+ 0
+
-
- 0
+
+ Basic.Settings.Stream.AdvancedOptions
-
- 0
-
-
- 0
-
-
-
-
-
-
-
-
-
-
-
- QLineEdit::Password
-
-
-
- -
-
-
- Show
-
-
-
- -
-
-
-
-
-
- -4
-
-
- Basic.AutoConfig.StreamPage.GetStreamKey
-
-
-
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 170
- 8
-
-
-
-
- -
-
-
- 8
-
-
- 7
-
-
- 7
-
-
-
-
-
- font-weight: bold
+
+
+ QFormLayout::AllNonFixedFieldsGrow
-
- Auth.LoadingChannel.Title
+
+ Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter
-
-
- -
-
-
- Basic.AutoConfig.StreamPage.DisconnectAccount
+
+ 9
-
-
- -
-
-
- Qt::Horizontal
+
+ 2
-
-
- 40
- 20
-
+
+ 9
-
-
-
-
- -
-
-
- Basic.Settings.Stream.BandwidthTestMode
-
-
-
- -
-
-
- Basic.Settings.Stream.Custom.UseAuthentication
-
-
-
- -
-
-
- Basic.Settings.Stream.Custom.Username
-
-
- authUsername
-
-
-
- -
-
-
- -
-
-
- Basic.Settings.Stream.Custom.Password
-
-
- authPw
-
-
-
- -
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
-
-
-
- QLineEdit::Password
-
-
-
- -
-
-
- Show
-
-
-
-
-
-
- -
-
-
- -
-
-
- Basic.Settings.Stream.TTVAddon
-
-
- twitchAddonDropdown
-
-
-
- -
-
-
- Basic.Settings.Stream.IgnoreRecommended
-
-
-
- -
-
-
-
-
-
- Qt::RichText
-
-
- true
-
-
-
- -
-
-
-
-
-
- Basic.AutoConfig.StreamPage.UseStreamKeyAdvanced
+
+ 9
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
- -
-
-
- Basic.AutoConfig.StreamPage.ConnectedAccount
-
-
-
- -
-
-
-
-
-
- PointingHandCursor
-
-
- Basic.AutoConfig.StreamPage.ConnectAccount
-
-
-
- -
-
-
- Qt::Horizontal
-
-
-
- 40
- 20
-
-
-
-
-
-
-
+ -
+
+
+ Basic.Settings.Stream.TTVAddon
+
+
+ twitchAddonDropdown
+
+
+
+ -
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 170
+ 0
+
+
+
+
+ -
+
+
+ Basic.Settings.Stream.BandwidthTestMode
+
+
+
+ -
+
+
+ Basic.Settings.Stream.IgnoreRecommended
+
+
+
+ -
+
+
+
+
+
+ Qt::RichText
+
+
+ true
+
+
+
+
+
+
+
+
diff --git a/UI/window-basic-settings-stream.cpp b/UI/window-basic-settings-stream.cpp
index 04cc3a3bb..8a5f41c00 100644
--- a/UI/window-basic-settings-stream.cpp
+++ b/UI/window-basic-settings-stream.cpp
@@ -45,7 +45,7 @@ enum class Section : int {
StreamKey,
};
-inline bool OBSBasicSettings::IsCustomService() const
+bool OBSBasicSettings::IsCustomService() const
{
return ui->service->currentData().toInt() == (int)ListOpt::Custom;
}
@@ -96,6 +96,16 @@ void OBSBasicSettings::InitStreamPage()
&OBSBasicSettings::DisplayEnforceWarning);
connect(ui->ignoreRecommended, &QCheckBox::toggled, this,
&OBSBasicSettings::UpdateResFPSLimits);
+
+ connect(ui->enableMultitrackVideo, &QCheckBox::toggled, this,
+ &OBSBasicSettings::UpdateMultitrackVideo);
+ connect(ui->multitrackVideoMaximumAggregateBitrateAuto,
+ &QCheckBox::toggled, this,
+ &OBSBasicSettings::UpdateMultitrackVideo);
+ connect(ui->multitrackVideoMaximumVideoTracksAuto, &QCheckBox::toggled,
+ this, &OBSBasicSettings::UpdateMultitrackVideo);
+ connect(ui->multitrackVideoConfigOverrideEnable, &QCheckBox::toggled,
+ this, &OBSBasicSettings::UpdateMultitrackVideo);
}
void OBSBasicSettings::LoadStream1Settings()
@@ -155,6 +165,44 @@ void OBSBasicSettings::LoadStream1Settings()
ui->twitchAddonDropdown->setCurrentIndex(idx);
}
+ ui->enableMultitrackVideo->setChecked(config_get_bool(
+ main->Config(), "Stream1", "EnableMultitrackVideo"));
+
+ ui->multitrackVideoMaximumAggregateBitrateAuto->setChecked(
+ config_get_bool(main->Config(), "Stream1",
+ "MultitrackVideoMaximumAggregateBitrateAuto"));
+ if (config_has_user_value(main->Config(), "Stream1",
+ "MultitrackVideoMaximumAggregateBitrate")) {
+ ui->multitrackVideoMaximumAggregateBitrate->setValue(
+ config_get_int(
+ main->Config(), "Stream1",
+ "MultitrackVideoMaximumAggregateBitrate"));
+ }
+
+ ui->multitrackVideoMaximumVideoTracksAuto->setChecked(
+ config_get_bool(main->Config(), "Stream1",
+ "MultitrackVideoMaximumVideoTracksAuto"));
+ if (config_has_user_value(main->Config(), "Stream1",
+ "MultitrackVideoMaximumVideoTracks"))
+ ui->multitrackVideoMaximumVideoTracks->setValue(
+ config_get_int(main->Config(), "Stream1",
+ "MultitrackVideoMaximumVideoTracks"));
+
+ ui->multitrackVideoStreamDumpEnable->setChecked(config_get_bool(
+ main->Config(), "Stream1", "MultitrackVideoStreamDumpEnabled"));
+
+ ui->multitrackVideoConfigOverrideEnable->setChecked(
+ config_get_bool(main->Config(), "Stream1",
+ "MultitrackVideoConfigOverrideEnabled"));
+ if (config_has_user_value(main->Config(), "Stream1",
+ "MultitrackVideoConfigOverride"))
+ ui->multitrackVideoConfigOverride->setPlainText(
+ DeserializeConfigText(
+ config_get_string(
+ main->Config(), "Stream1",
+ "MultitrackVideoConfigOverride"))
+ .c_str());
+
UpdateServerList();
if (is_rtmp_common) {
@@ -187,6 +235,7 @@ void OBSBasicSettings::LoadStream1Settings()
UpdateMoreInfoLink();
UpdateVodTrackSetting();
UpdateServiceRecommendations();
+ UpdateMultitrackVideo();
bool streamActive = obs_frontend_streaming_active();
ui->streamPage->setEnabled(!streamActive);
@@ -315,6 +364,49 @@ void OBSBasicSettings::SaveStream1Settings()
}
SaveCheckBox(ui->ignoreRecommended, "Stream1", "IgnoreRecommended");
+
+ auto oldMultitrackVideoSetting = config_get_bool(
+ main->Config(), "Stream1", "EnableMultitrackVideo");
+
+ if (!IsCustomService()) {
+ OBSDataAutoRelease settings = obs_data_create();
+ obs_data_set_string(settings, "service",
+ QT_TO_UTF8(ui->service->currentText()));
+ OBSServiceAutoRelease temp_service = obs_service_create_private(
+ "rtmp_common", "auto config query service", settings);
+ settings = obs_service_get_settings(temp_service);
+ auto available = obs_data_has_user_value(
+ settings, "multitrack_video_configuration_url");
+
+ if (available) {
+ SaveCheckBox(ui->enableMultitrackVideo, "Stream1",
+ "EnableMultitrackVideo");
+ } else {
+ config_remove_value(main->Config(), "Stream1",
+ "EnableMultitrackVideo");
+ }
+ } else {
+ SaveCheckBox(ui->enableMultitrackVideo, "Stream1",
+ "EnableMultitrackVideo");
+ }
+ SaveCheckBox(ui->multitrackVideoMaximumAggregateBitrateAuto, "Stream1",
+ "MultitrackVideoMaximumAggregateBitrateAuto");
+ SaveSpinBox(ui->multitrackVideoMaximumAggregateBitrate, "Stream1",
+ "MultitrackVideoMaximumAggregateBitrate");
+ SaveCheckBox(ui->multitrackVideoMaximumVideoTracksAuto, "Stream1",
+ "MultitrackVideoMaximumVideoTracksAuto");
+ SaveSpinBox(ui->multitrackVideoMaximumVideoTracks, "Stream1",
+ "MultitrackVideoMaximumVideoTracks");
+ SaveCheckBox(ui->multitrackVideoStreamDumpEnable, "Stream1",
+ "MultitrackVideoStreamDumpEnabled");
+ SaveCheckBox(ui->multitrackVideoConfigOverrideEnable, "Stream1",
+ "MultitrackVideoConfigOverrideEnabled");
+ SaveText(ui->multitrackVideoConfigOverride, "Stream1",
+ "MultitrackVideoConfigOverride");
+
+ if (oldMultitrackVideoSetting != ui->enableMultitrackVideo->isChecked())
+ main->ResetOutputs();
+
SwapMultiTrack(QT_TO_UTF8(protocol));
}
@@ -555,6 +647,7 @@ void OBSBasicSettings::on_service_currentIndexChanged(int idx)
protocol = FindProtocol();
UpdateAdvNetworkGroup();
+ UpdateMultitrackVideo();
if (ServiceSupportsCodecCheck() && UpdateResFPSLimits()) {
lastServiceIdx = idx;
@@ -576,6 +669,7 @@ void OBSBasicSettings::on_customServer_textChanged(const QString &)
protocol = FindProtocol();
UpdateAdvNetworkGroup();
+ UpdateMultitrackVideo();
if (ServiceSupportsCodecCheck())
lastCustomServer = ui->customServer->text();
@@ -596,6 +690,10 @@ void OBSBasicSettings::ServiceChanged(bool resetFields)
if (resetFields || lastService != service.c_str()) {
reset_service_ui_fields(ui.get(), service, loading);
+
+ ui->enableMultitrackVideo->setChecked(config_get_bool(
+ main->Config(), "Stream1", "EnableMultitrackVideo"));
+ UpdateMultitrackVideo();
}
ui->useAuth->setVisible(custom);
@@ -605,8 +703,8 @@ void OBSBasicSettings::ServiceChanged(bool resetFields)
ui->authPwWidget->setVisible(custom);
if (custom || whip) {
- ui->streamkeyPageLayout->insertRow(1, ui->serverLabel,
- ui->serverStackedWidget);
+ ui->destinationLayout->insertRow(1, ui->serverLabel,
+ ui->serverStackedWidget);
ui->serverStackedWidget->setCurrentIndex(1);
ui->serverStackedWidget->setVisible(true);
diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp
index f61c02e2a..fc241576e 100644
--- a/UI/window-basic-settings.cpp
+++ b/UI/window-basic-settings.cpp
@@ -337,6 +337,7 @@ void RestrictResetBitrates(initializer_list boxes, int maxbitrate);
#define GROUP_CHANGED &QGroupBox::toggled
#define SCROLL_CHANGED &QSpinBox::valueChanged
#define DSCROLL_CHANGED &QDoubleSpinBox::valueChanged
+#define TEXT_CHANGED &QPlainTextEdit::textChanged
#define GENERAL_CHANGED &OBSBasicSettings::GeneralChanged
#define STREAM1_CHANGED &OBSBasicSettings::Stream1Changed
@@ -419,6 +420,14 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->authUsername, EDIT_CHANGED, STREAM1_CHANGED);
HookWidget(ui->authPw, EDIT_CHANGED, STREAM1_CHANGED);
HookWidget(ui->ignoreRecommended, CHECK_CHANGED, STREAM1_CHANGED);
+ HookWidget(ui->enableMultitrackVideo, CHECK_CHANGED, STREAM1_CHANGED);
+ HookWidget(ui->multitrackVideoMaximumAggregateBitrateAuto, CHECK_CHANGED, STREAM1_CHANGED);
+ HookWidget(ui->multitrackVideoMaximumAggregateBitrate, SCROLL_CHANGED, STREAM1_CHANGED);
+ HookWidget(ui->multitrackVideoMaximumVideoTracksAuto, CHECK_CHANGED, STREAM1_CHANGED);
+ HookWidget(ui->multitrackVideoMaximumVideoTracks, SCROLL_CHANGED, STREAM1_CHANGED);
+ HookWidget(ui->multitrackVideoStreamDumpEnable, CHECK_CHANGED, STREAM1_CHANGED);
+ HookWidget(ui->multitrackVideoConfigOverrideEnable, CHECK_CHANGED, STREAM1_CHANGED);
+ HookWidget(ui->multitrackVideoConfigOverride, TEXT_CHANGED, STREAM1_CHANGED);
HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleNoSpace, CHECK_CHANGED, OUTPUTS_CHANGED);
@@ -1068,6 +1077,21 @@ void OBSBasicSettings::SaveSpinBox(QSpinBox *widget, const char *section,
config_set_int(main->Config(), section, value, widget->value());
}
+void OBSBasicSettings::SaveText(QPlainTextEdit *widget, const char *section,
+ const char *value)
+{
+ if (!WidgetChanged(widget))
+ return;
+
+ auto utf8 = widget->toPlainText().toUtf8();
+
+ OBSDataAutoRelease safe_text = obs_data_create();
+ obs_data_set_string(safe_text, "text", utf8.constData());
+
+ config_set_string(main->Config(), section, value,
+ obs_data_get_json(safe_text));
+}
+
std::string DeserializeConfigText(const char *value)
{
OBSDataAutoRelease data = obs_data_create_from_json(value);
@@ -6253,6 +6277,116 @@ void OBSBasicSettings::UpdateAdvNetworkGroup()
#endif
}
+extern bool MultitrackVideoDeveloperModeEnabled();
+
+void OBSBasicSettings::UpdateMultitrackVideo()
+{
+ // Technically, it should currently be safe to toggle multitrackVideo
+ // while not streaming (recording should be irrelevant), but practically
+ // output settings aren't currently being tracked with that degree of
+ // flexibility, so just disable everything while outputs are active.
+ auto toggle_available = !main->Active();
+
+ // FIXME: protocol is not updated properly for WHIP; what do?
+ auto available = protocol.startsWith("RTMP");
+
+ if (available && !IsCustomService()) {
+ OBSDataAutoRelease settings = obs_data_create();
+ obs_data_set_string(settings, "service",
+ QT_TO_UTF8(ui->service->currentText()));
+ OBSServiceAutoRelease temp_service = obs_service_create_private(
+ "rtmp_common", "auto config query service", settings);
+ settings = obs_service_get_settings(temp_service);
+ available = obs_data_has_user_value(
+ settings, "multitrack_video_configuration_url");
+ if (!available && ui->enableMultitrackVideo->isChecked())
+ ui->enableMultitrackVideo->setChecked(false);
+ }
+
+ ui->multitrackVideoGroupBox->setVisible(available);
+
+ ui->enableMultitrackVideo->setEnabled(toggle_available);
+
+ ui->multitrackVideoMaximumAggregateBitrateLabel->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked());
+ ui->multitrackVideoMaximumAggregateBitrateAuto->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked());
+ ui->multitrackVideoMaximumAggregateBitrate->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked() &&
+ !ui->multitrackVideoMaximumAggregateBitrateAuto->isChecked());
+
+ ui->multitrackVideoMaximumVideoTracksLabel->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked());
+ ui->multitrackVideoMaximumVideoTracksAuto->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked());
+ ui->multitrackVideoMaximumVideoTracks->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked() &&
+ !ui->multitrackVideoMaximumVideoTracksAuto->isChecked());
+
+ ui->multitrackVideoStreamDumpEnable->setVisible(
+ available && MultitrackVideoDeveloperModeEnabled());
+ ui->multitrackVideoConfigOverrideEnable->setVisible(
+ available && MultitrackVideoDeveloperModeEnabled());
+ ui->multitrackVideoConfigOverrideLabel->setVisible(
+ available && MultitrackVideoDeveloperModeEnabled());
+ ui->multitrackVideoConfigOverride->setVisible(
+ available && MultitrackVideoDeveloperModeEnabled());
+
+ ui->multitrackVideoStreamDumpEnable->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked());
+ ui->multitrackVideoConfigOverrideEnable->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked());
+ ui->multitrackVideoConfigOverrideLabel->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked() &&
+ ui->multitrackVideoConfigOverrideEnable->isChecked());
+ ui->multitrackVideoConfigOverride->setEnabled(
+ toggle_available && ui->enableMultitrackVideo->isChecked() &&
+ ui->multitrackVideoConfigOverrideEnable->isChecked());
+
+ if (available) {
+ OBSDataAutoRelease settings;
+ {
+ auto service_name = ui->service->currentText();
+ auto custom_server = ui->customServer->text().trimmed();
+
+ obs_properties_t *props =
+ obs_get_service_properties("rtmp_common");
+ obs_property_t *service =
+ obs_properties_get(props, "service");
+
+ settings = obs_data_create();
+
+ obs_data_set_string(settings, "service",
+ QT_TO_UTF8(service_name));
+ obs_property_modified(service, settings);
+
+ obs_properties_destroy(props);
+ }
+
+ auto multitrack_video_name =
+ QTStr("Basic.Settings.Stream.MultitrackVideoLabel");
+ if (obs_data_has_user_value(settings, "multitrack_video_name"))
+ multitrack_video_name = obs_data_get_string(
+ settings, "multitrack_video_name");
+
+ ui->enableMultitrackVideo->setText(
+ QTStr("Basic.Settings.Stream.EnableMultitrackVideo")
+ .arg(multitrack_video_name));
+
+ if (obs_data_has_user_value(settings,
+ "multitrack_video_disclaimer")) {
+ ui->multitrackVideoInfo->setVisible(true);
+ ui->multitrackVideoInfo->setText(obs_data_get_string(
+ settings, "multitrack_video_disclaimer"));
+ } else {
+ ui->multitrackVideoInfo->setText(
+ QTStr("MultitrackVideo.Info")
+ .arg(multitrack_video_name,
+ ui->service->currentText()));
+ }
+ }
+}
+
void OBSBasicSettings::SimpleStreamAudioEncoderChanged()
{
PopulateSimpleBitrates(
diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp
index 03d55a263..846b80014 100644
--- a/UI/window-basic-settings.hpp
+++ b/UI/window-basic-settings.hpp
@@ -195,6 +195,8 @@ private:
const char *value);
void SaveSpinBox(QSpinBox *widget, const char *section,
const char *value);
+ void SaveText(QPlainTextEdit *widget, const char *section,
+ const char *value);
void SaveFormat(QComboBox *combo);
void SaveEncoder(QComboBox *combo, const char *section,
const char *value);
@@ -275,7 +277,7 @@ private:
/* stream */
void InitStreamPage();
- inline bool IsCustomService() const;
+ bool IsCustomService() const;
inline bool IsWHIP() const;
void LoadServices(bool showAll);
void OnOAuthStreamKeyConnected();
@@ -301,6 +303,7 @@ private:
bool IsCustomServer();
private slots:
+ void UpdateMultitrackVideo();
void RecreateOutputResolutionWidget();
bool UpdateResFPSLimits();
void DisplayEnforceWarning(bool checked);