UI: Move "enforce" setting to "ignore" stream section

Moves the "Enforce streaming service bitrate" option from simple output
mode to the stream section, renames it to "Ignore streaming service
setting recommendations" (inverting it). When trying to check it, it
will now also display a message box warning the user that it's generally
a not-so-good idea.

Also displays recommended settings for the service.
This commit is contained in:
jp9000 2020-11-11 09:48:39 -08:00
parent 005863a346
commit 546dcc7a14
7 changed files with 159 additions and 68 deletions

View File

@ -707,6 +707,11 @@ Basic.Settings.Stream.StreamSettingsWarning="Open Settings"
Basic.Settings.Stream.MissingUrlAndApiKey="URL and Stream Key are missing.\n\nOpen settings to enter the URL and Stream Key in the 'stream' tab."
Basic.Settings.Stream.MissingUrl="Stream URL is missing.\n\nOpen settings to enter the URL in the 'Stream' tab."
Basic.Settings.Stream.MissingStreamKey="Stream key is missing.\n\nOpen settings to enter the stream key in the 'Stream' tab."
Basic.Settings.Stream.IgnoreRecommended="Ignore streaming service setting recommendations"
Basic.Settings.Stream.IgnoreRecommended.Warn.Title="Override Recommended Settings"
Basic.Settings.Stream.IgnoreRecommended.Warn.Text="Warning: Ignoring the service's limitations may result in degraded stream quality or prevent you from streaming.\n\nContinue?"
Basic.Settings.Stream.Recommended.MaxVideoBitrate="Maximum Video Bitrate: %1 kbps"
Basic.Settings.Stream.Recommended.MaxAudioBitrate="Maximum Audio Bitrate: %1 kbps"
# basic mode 'output' settings
Basic.Settings.Output="Output"
@ -714,7 +719,6 @@ Basic.Settings.Output.Format="Recording Format"
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.\n\nNote that this can increase delay to viewers if there is significant sudden congestion.\nWhen the bitrate drops, it can take up to a few minutes to restore.\n\nCurrently only supported for RTMP."
@ -735,8 +739,8 @@ Basic.Settings.Output.Simple.RecordingQuality.Stream="Same as stream"
Basic.Settings.Output.Simple.RecordingQuality.Small="High Quality, Medium File Size"
Basic.Settings.Output.Simple.RecordingQuality.HQ="Indistinguishable Quality, Large File Size"
Basic.Settings.Output.Simple.RecordingQuality.Lossless="Lossless Quality, Tremendously Large File Size"
Basic.Settings.Output.Simple.Warn.VideoBitrate="Warning: The streaming video bitrate will be set to %1, which is the upper limit for the current streaming service. If you're sure you want to go above %1, enable advanced encoder options and uncheck \"Enforce streaming service bitrate limits\"."
Basic.Settings.Output.Simple.Warn.AudioBitrate="Warning: The streaming audio bitrate will be set to %1, which is the upper limit for the current streaming service. If you're sure you want to go above %1, enable advanced encoder options and uncheck \"Enforce streaming service bitrate limits\"."
Basic.Settings.Output.Simple.Warn.VideoBitrate="Warning: The streaming video bitrate will be set to %1, which is the upper limit for the current streaming service."
Basic.Settings.Output.Simple.Warn.AudioBitrate="Warning: The streaming audio bitrate will be set to %1, which is the upper limit for the current streaming service."
Basic.Settings.Output.Simple.Warn.CannotPause="Warning: Recordings cannot be paused if the recording quality is set to \"Same as stream\"."
Basic.Settings.Output.Simple.Warn.Encoder="Warning: Recording with a software encoder at a different quality than the stream will require extra CPU usage if you stream and record at the same time."
Basic.Settings.Output.Simple.Warn.Lossless="Warning: Lossless quality generates tremendously large file sizes! Lossless quality can use upward of 7 gigabytes of disk space per minute at high resolutions and framerates. Lossless is not recommended for long recordings unless you have a very large amount of disk space available."

View File

@ -151,8 +151,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>806</width>
<height>1254</height>
<width>803</width>
<height>1026</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_19">
@ -1245,6 +1245,20 @@
</property>
</widget>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="ignoreRecommended">
<property name="text">
<string>Basic.Settings.Stream.IgnoreRecommended</string>
</property>
</widget>
</item>
<item row="11" column="1">
<widget class="QLabel" name="enforceSettingsLabel">
<property name="text">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
@ -1281,8 +1295,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>813</width>
<height>761</height>
<width>601</width>
<height>602</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
@ -1427,6 +1441,19 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="simpleOutStrEncoderLabel">
<property name="text">
<string>Basic.Settings.Output.Encoder</string>
</property>
<property name="buddy">
<cstring>simpleOutRecEncoder</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="simpleOutStrEncoder"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_20">
<property name="text">
@ -1509,10 +1536,7 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="simpleOutPreset"/>
</item>
<item row="5" column="0">
<item row="4" column="0">
<widget class="QLabel" name="label_24">
<property name="enabled">
<bool>true</bool>
@ -1525,7 +1549,10 @@
</property>
</widget>
</item>
<item row="6" column="0">
<item row="4" column="1">
<widget class="QComboBox" name="simpleOutPreset"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_23">
<property name="text">
<string>Basic.Settings.Output.CustomEncoderSettings</string>
@ -1535,29 +1562,9 @@
</property>
</widget>
</item>
<item row="6" column="1">
<item row="5" column="1">
<widget class="QLineEdit" name="simpleOutCustom"/>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="simpleOutEnforce">
<property name="text">
<string>Basic.Settings.Output.EnforceBitrate</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="simpleOutStrEncoder"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="simpleOutStrEncoderLabel">
<property name="text">
<string>Basic.Settings.Output.Encoder</string>
</property>
<property name="buddy">
<cstring>simpleOutRecEncoder</cstring>
</property>
</widget>
</item>
</layout>
</widget>
</item>
@ -3776,8 +3783,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>767</width>
<height>582</height>
<width>555</width>
<height>469</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_50">
@ -4632,8 +4639,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>791</width>
<height>970</height>
<width>599</width>
<height>781</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_23">
@ -5507,7 +5514,6 @@
<tabstop>simpleOutStrEncoder</tabstop>
<tabstop>simpleOutputABitrate</tabstop>
<tabstop>simpleOutAdvanced</tabstop>
<tabstop>simpleOutEnforce</tabstop>
<tabstop>simpleOutPreset</tabstop>
<tabstop>simpleOutCustom</tabstop>
<tabstop>simpleOutputPath</tabstop>
@ -5834,22 +5840,6 @@
</hint>
</hints>
</connection>
<connection>
<sender>simpleOutAdvanced</sender>
<signal>toggled(bool)</signal>
<receiver>simpleOutEnforce</receiver>
<slot>setVisible(bool)</slot>
<hints>
<hint type="sourcelabel">
<x>251</x>
<y>64</y>
</hint>
<hint type="destinationlabel">
<x>251</x>
<y>64</y>
</hint>
</hints>
</connection>
<connection>
<sender>systemTrayEnabled</sender>
<signal>toggled(bool)</signal>

View File

@ -482,8 +482,8 @@ void SimpleOutput::Update()
int audioBitrate = GetAudioBitrate();
bool advanced =
config_get_bool(main->Config(), "SimpleOutput", "UseAdvanced");
bool enforceBitrate = config_get_bool(main->Config(), "SimpleOutput",
"EnforceBitrate");
bool enforceBitrate = !config_get_bool(main->Config(), "Stream1",
"IgnoreRecommended");
const char *custom = config_get_string(main->Config(), "SimpleOutput",
"x264Settings");
const char *encoder = config_get_string(main->Config(), "SimpleOutput",
@ -521,7 +521,7 @@ void SimpleOutput::Update()
obs_service_apply_encoder_settings(main->GetService(), h264Settings,
aacSettings);
if (advanced && !enforceBitrate) {
if (!enforceBitrate) {
obs_data_set_int(h264Settings, "bitrate", videoBitrate);
obs_data_set_int(aacSettings, "bitrate", audioBitrate);
}
@ -1250,6 +1250,8 @@ void AdvancedOutput::UpdateStreamSettings()
{
bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut",
"ApplyServiceSettings");
bool enforceBitrate = !config_get_bool(main->Config(), "Stream1",
"IgnoreRecommended");
bool dynBitrate =
config_get_bool(main->Config(), "Output", "DynamicBitrate");
const char *streamEncoder =
@ -1258,9 +1260,13 @@ void AdvancedOutput::UpdateStreamSettings()
OBSData settings = GetDataFromJsonFile("streamEncoder.json");
ApplyEncoderDefaults(settings, h264Streaming);
if (applyServiceSettings)
if (applyServiceSettings) {
int bitrate = (int)obs_data_get_int(settings, "bitrate");
obs_service_apply_encoder_settings(main->GetService(), settings,
nullptr);
if (!enforceBitrate)
obs_data_set_int(settings, "bitrate", bitrate);
}
if (dynBitrate && astrcmpi(streamEncoder, "jim_nvenc") == 0)
obs_data_set_bool(settings, "lookahead", false);
@ -1480,6 +1486,8 @@ inline void AdvancedOutput::UpdateAudioSettings()
{
bool applyServiceSettings = config_get_bool(main->Config(), "AdvOut",
"ApplyServiceSettings");
bool enforceBitrate = !config_get_bool(main->Config(), "Stream1",
"IgnoreRecommended");
int streamTrackIndex =
config_get_int(main->Config(), "AdvOut", "TrackIndex");
int vodTrackIndex =
@ -1510,9 +1518,15 @@ inline void AdvancedOutput::UpdateAudioSettings()
if (track == streamTrackIndex || track == vodTrackIndex) {
if (applyServiceSettings) {
int bitrate = (int)obs_data_get_int(settings[i],
"bitrate");
obs_service_apply_encoder_settings(
main->GetService(), nullptr,
settings[i]);
if (!enforceBitrate)
obs_data_set_int(settings[i], "bitrate",
bitrate);
}
}

View File

@ -1266,6 +1266,22 @@ bool OBSBasic::InitBasicConfigDefaults()
changed = true;
}
/* ----------------------------------------------------- */
/* move bitrate enforcement setting to new value */
if (config_has_user_value(basicConfig, "SimpleOutput",
"EnforceBitrate") &&
!config_has_user_value(basicConfig, "Stream1",
"IgnoreRecommended") &&
!config_has_user_value(basicConfig, "Stream1", "MovedOldEnforce")) {
bool enforce = config_get_bool(basicConfig, "SimpleOutput",
"EnforceBitrate");
config_set_bool(basicConfig, "Stream1", "IgnoreRecommended",
!enforce);
config_set_bool(basicConfig, "Stream1", "MovedOldEnforce",
true);
changed = true;
}
/* ----------------------------------------------------- */
if (changed)
@ -1275,6 +1291,9 @@ bool OBSBasic::InitBasicConfigDefaults()
config_set_default_string(basicConfig, "Output", "Mode", "Simple");
config_set_default_bool(basicConfig, "Stream1", "IgnoreRecommended",
false);
config_set_default_string(basicConfig, "SimpleOutput", "FilePath",
GetDefaultVideoSavePath().c_str());
config_set_default_string(basicConfig, "SimpleOutput", "RecFormat",
@ -1283,8 +1302,6 @@ bool OBSBasic::InitBasicConfigDefaults()
config_set_default_uint(basicConfig, "SimpleOutput", "ABitrate", 160);
config_set_default_bool(basicConfig, "SimpleOutput", "UseAdvanced",
false);
config_set_default_bool(basicConfig, "SimpleOutput", "EnforceBitrate",
true);
config_set_default_string(basicConfig, "SimpleOutput", "Preset",
"veryfast");
config_set_default_string(basicConfig, "SimpleOutput", "NVENCPreset",

View File

@ -73,8 +73,12 @@ void OBSBasicSettings::InitStreamPage()
SLOT(UpdateKeyLink()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateVodTrackSetting()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateServiceRecommendations()));
connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
SLOT(UpdateKeyLink()));
connect(ui->ignoreRecommended, SIGNAL(clicked(bool)), this,
SLOT(DisplayEnforceWarning(bool)));
connect(ui->customServer, SIGNAL(editingFinished(const QString &)),
this, SLOT(UpdateKeyLink()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
@ -83,6 +87,9 @@ void OBSBasicSettings::InitStreamPage()
void OBSBasicSettings::LoadStream1Settings()
{
bool ignoreRecommended =
config_get_bool(main->Config(), "Stream1", "IgnoreRecommended");
obs_service_t *service_obj = main->GetService();
const char *type = obs_service_get_type(service_obj);
@ -144,10 +151,13 @@ void OBSBasicSettings::LoadStream1Settings()
UpdateKeyLink();
UpdateMoreInfoLink();
UpdateVodTrackSetting();
UpdateServiceRecommendations();
bool streamActive = obs_frontend_streaming_active();
ui->streamPage->setEnabled(!streamActive);
ui->ignoreRecommended->setChecked(ignoreRecommended);
loading = false;
}
@ -216,6 +226,8 @@ void OBSBasicSettings::SaveStream1Settings()
main->auth = auth;
if (!!main->auth)
main->auth->LoadUI();
SaveCheckBox(ui->ignoreRecommended, "Stream1", "IgnoreRecommended");
}
void OBSBasicSettings::UpdateMoreInfoLink()
@ -655,3 +667,60 @@ OBSService OBSBasicSettings::GetStream1Service()
{
return stream1Changed ? SpawnTempService() : main->GetService();
}
void OBSBasicSettings::UpdateServiceRecommendations()
{
bool customServer = IsCustomService();
ui->ignoreRecommended->setVisible(!customServer);
ui->enforceSettingsLabel->setVisible(!customServer);
OBSService service = GetStream1Service();
int vbitrate, abitrate;
obs_service_get_max_bitrate(service, &vbitrate, &abitrate);
QString text;
#define ENFORCE_TEXT(x) QTStr("Basic.Settings.Stream.Recommended." x)
if (vbitrate)
text += ENFORCE_TEXT("MaxVideoBitrate")
.arg(QString::number(vbitrate));
if (abitrate) {
if (!text.isEmpty())
text += "\n";
text += ENFORCE_TEXT("MaxAudioBitrate")
.arg(QString::number(abitrate));
}
#undef ENFORCE_TEXT
ui->enforceSettingsLabel->setText(text);
}
void OBSBasicSettings::DisplayEnforceWarning(bool checked)
{
if (IsCustomService())
return;
if (!checked) {
SimpleRecordingEncoderChanged();
return;
}
QMessageBox::StandardButton button;
#define ENFORCE_WARNING(x) \
QTStr("Basic.Settings.Stream.IgnoreRecommended.Warn." x)
button = OBSMessageBox::question(this, ENFORCE_WARNING("Title"),
ENFORCE_WARNING("Text"));
#undef ENFORCE_WARNING
if (button == QMessageBox::No) {
QMetaObject::invokeMethod(ui->ignoreRecommended, "setChecked",
Qt::QueuedConnection,
Q_ARG(bool, false));
return;
}
SimpleRecordingEncoderChanged();
}

View File

@ -425,6 +425,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->useAuth, CHECK_CHANGED, STREAM1_CHANGED);
HookWidget(ui->authUsername, EDIT_CHANGED, STREAM1_CHANGED);
HookWidget(ui->authPw, EDIT_CHANGED, STREAM1_CHANGED);
HookWidget(ui->ignoreRecommended, CHECK_CHANGED, STREAM1_CHANGED);
HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleNoSpace, CHECK_CHANGED, OUTPUTS_CHANGED);
@ -433,7 +434,6 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
HookWidget(ui->simpleOutStrEncoder, COMBO_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleOutputABitrate, COMBO_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleOutAdvanced, CHECK_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleOutEnforce, CHECK_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleOutPreset, COMBO_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleOutCustom, EDIT_CHANGED, OUTPUTS_CHANGED);
HookWidget(ui->simpleOutRecQuality, COMBO_CHANGED, OUTPUTS_CHANGED);
@ -755,7 +755,7 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
this, SLOT(SimpleRecordingEncoderChanged()));
connect(ui->simpleOutAdvanced, SIGNAL(toggled(bool)), this,
SLOT(SimpleRecordingEncoderChanged()));
connect(ui->simpleOutEnforce, SIGNAL(toggled(bool)), this,
connect(ui->ignoreRecommended, SIGNAL(toggled(bool)), this,
SLOT(SimpleRecordingEncoderChanged()));
connect(ui->simpleReplayBuf, SIGNAL(toggled(bool)), this,
SLOT(SimpleReplayBufferChanged()));
@ -1612,8 +1612,6 @@ void OBSBasicSettings::LoadSimpleOutputSettings()
config_get_uint(main->Config(), "SimpleOutput", "ABitrate");
bool advanced =
config_get_bool(main->Config(), "SimpleOutput", "UseAdvanced");
bool enforceBitrate = config_get_bool(main->Config(), "SimpleOutput",
"EnforceBitrate");
const char *preset =
config_get_string(main->Config(), "SimpleOutput", "Preset");
const char *qsvPreset =
@ -1662,7 +1660,6 @@ void OBSBasicSettings::LoadSimpleOutputSettings()
std::to_string(audioBitrate).c_str());
ui->simpleOutAdvanced->setChecked(advanced);
ui->simpleOutEnforce->setChecked(enforceBitrate);
ui->simpleOutCustom->setText(custom);
idx = ui->simpleOutRecQuality->findData(QString(recQual));
@ -3304,7 +3301,6 @@ void OBSBasicSettings::SaveOutputSettings()
SaveCheckBox(ui->simpleNoSpace, "SimpleOutput", "FileNameWithoutSpace");
SaveCombo(ui->simpleOutRecFormat, "SimpleOutput", "RecFormat");
SaveCheckBox(ui->simpleOutAdvanced, "SimpleOutput", "UseAdvanced");
SaveCheckBox(ui->simpleOutEnforce, "SimpleOutput", "EnforceBitrate");
SaveComboData(ui->simpleOutPreset, "SimpleOutput", presetType);
SaveEdit(ui->simpleOutCustom, "SimpleOutput", "x264Settings");
SaveComboData(ui->simpleOutRecQuality, "SimpleOutput", "RecQuality");
@ -4602,8 +4598,7 @@ void OBSBasicSettings::SimpleRecordingEncoderChanged()
{
QString qual = ui->simpleOutRecQuality->currentData().toString();
QString warning;
bool advanced = ui->simpleOutAdvanced->isChecked();
bool enforceBitrate = ui->simpleOutEnforce->isChecked() || !advanced;
bool enforceBitrate = !ui->ignoreRecommended->isChecked();
OBSService service = GetStream1Service();
delete simpleOutRecWarning;

View File

@ -245,7 +245,9 @@ private slots:
void UpdateServerList();
void UpdateKeyLink();
void UpdateVodTrackSetting();
void UpdateServiceRecommendations();
void UpdateMoreInfoLink();
void DisplayEnforceWarning(bool checked);
void on_show_clicked();
void on_authPwShow_clicked();
void on_connectAccount_clicked();