2013-12-11 20:50:10 -08:00
|
|
|
/******************************************************************************
|
2014-03-07 11:56:31 -08:00
|
|
|
Copyright (C) 2013-2014 by Hugh Bailey <obs.jim@gmail.com>
|
2013-12-11 20:50:10 -08:00
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
******************************************************************************/
|
|
|
|
|
2014-02-22 19:14:19 -08:00
|
|
|
#include <obs.hpp>
|
2014-01-26 14:36:15 -08:00
|
|
|
#include <util/util.hpp>
|
|
|
|
#include <util/lexer.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include <QLineEdit>
|
|
|
|
#include <QMessageBox>
|
|
|
|
#include <QCloseEvent>
|
2014-05-20 23:27:27 -07:00
|
|
|
#include <QFileDialog>
|
2014-01-26 14:36:15 -08:00
|
|
|
|
2014-01-25 08:08:56 -08:00
|
|
|
#include "obs-app.hpp"
|
2014-01-26 14:36:15 -08:00
|
|
|
#include "platform.hpp"
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
#include "properties-view.hpp"
|
2014-01-26 14:36:15 -08:00
|
|
|
#include "qt-wrappers.hpp"
|
2014-02-22 19:14:19 -08:00
|
|
|
#include "window-basic-main.hpp"
|
2013-12-28 20:51:18 -08:00
|
|
|
#include "window-basic-settings.hpp"
|
2013-12-10 20:14:20 -08:00
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
#include <util/platform.h>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
/* parses "[width]x[height]", string, i.e. 1024x768 */
|
|
|
|
static bool ConvertResText(const char *res, uint32_t &cx, uint32_t &cy)
|
|
|
|
{
|
|
|
|
BaseLexer lex;
|
|
|
|
base_token token;
|
|
|
|
|
|
|
|
lexer_start(lex, res);
|
|
|
|
|
|
|
|
/* parse width */
|
|
|
|
if (!lexer_getbasetoken(lex, &token, IGNORE_WHITESPACE))
|
|
|
|
return false;
|
|
|
|
if (token.type != BASETOKEN_DIGIT)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
cx = std::stoul(token.text.array);
|
|
|
|
|
|
|
|
/* parse 'x' */
|
|
|
|
if (!lexer_getbasetoken(lex, &token, IGNORE_WHITESPACE))
|
|
|
|
return false;
|
|
|
|
if (strref_cmpi(&token.text, "x") != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
/* parse height */
|
|
|
|
if (!lexer_getbasetoken(lex, &token, IGNORE_WHITESPACE))
|
|
|
|
return false;
|
|
|
|
if (token.type != BASETOKEN_DIGIT)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
cy = std::stoul(token.text.array);
|
|
|
|
|
|
|
|
/* shouldn't be any more tokens after this */
|
|
|
|
if (lexer_getbasetoken(lex, &token, IGNORE_WHITESPACE))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
static inline bool WidgetChanged(QWidget *widget)
|
|
|
|
{
|
|
|
|
return widget->property("changed").toBool();
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
static inline void SetComboByName(QComboBox *combo, const char *name)
|
|
|
|
{
|
|
|
|
int idx = combo->findText(QT_UTF8(name));
|
|
|
|
if (idx != -1)
|
|
|
|
combo->setCurrentIndex(idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void SetComboByValue(QComboBox *combo, const char *name)
|
|
|
|
{
|
|
|
|
int idx = combo->findData(QT_UTF8(name));
|
|
|
|
if (idx != -1)
|
|
|
|
combo->setCurrentIndex(idx);
|
|
|
|
}
|
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
static inline QString GetComboData(QComboBox *combo)
|
|
|
|
{
|
|
|
|
int idx = combo->currentIndex();
|
|
|
|
if (idx == -1)
|
|
|
|
return QString();
|
|
|
|
|
|
|
|
return combo->itemData(idx).toString();
|
|
|
|
}
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::HookWidget(QWidget *widget, const char *signal,
|
|
|
|
const char *slot)
|
|
|
|
{
|
|
|
|
QObject::connect(widget, signal, this, slot);
|
2014-06-23 19:54:20 -07:00
|
|
|
widget->setProperty("changed", QVariant(false));
|
2014-03-07 11:56:31 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
#define COMBO_CHANGED SIGNAL(currentIndexChanged(int))
|
2014-03-10 13:10:35 -07:00
|
|
|
#define EDIT_CHANGED SIGNAL(textChanged(const QString &))
|
2014-03-07 11:56:31 -08:00
|
|
|
#define CBEDIT_CHANGED SIGNAL(editTextChanged(const QString &))
|
|
|
|
#define SCROLL_CHANGED SIGNAL(valueChanged(int))
|
|
|
|
|
|
|
|
#define GENERAL_CHANGED SLOT(GeneralChanged())
|
2014-03-10 13:10:35 -07:00
|
|
|
#define OUTPUTS_CHANGED SLOT(OutputsChanged())
|
2014-03-07 21:34:49 -08:00
|
|
|
#define AUDIO_RESTART SLOT(AudioChangedRestart())
|
|
|
|
#define AUDIO_CHANGED SLOT(AudioChanged())
|
2014-03-07 11:56:31 -08:00
|
|
|
#define VIDEO_RESTART SLOT(VideoChangedRestart())
|
|
|
|
#define VIDEO_RES SLOT(VideoChangedResolution())
|
|
|
|
#define VIDEO_CHANGED SLOT(VideoChanged())
|
|
|
|
|
2014-01-24 20:19:50 -08:00
|
|
|
OBSBasicSettings::OBSBasicSettings(QWidget *parent)
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
: QDialog (parent),
|
|
|
|
main (qobject_cast<OBSBasic*>(parent)),
|
|
|
|
ui (new Ui::OBSBasicSettings),
|
|
|
|
generalChanged (false),
|
|
|
|
outputsChanged (false),
|
|
|
|
audioChanged (false),
|
|
|
|
videoChanged (false),
|
|
|
|
pageIndex (0),
|
|
|
|
loading (true),
|
|
|
|
streamProperties (nullptr)
|
2013-12-11 20:50:10 -08:00
|
|
|
{
|
2014-01-26 14:36:15 -08:00
|
|
|
string path;
|
|
|
|
|
2014-01-24 20:19:50 -08:00
|
|
|
ui->setupUi(this);
|
2014-01-25 08:08:56 -08:00
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
if (!GetDataFilePath("locale/locale.ini", path))
|
|
|
|
throw "Could not find locale/locale.ini path";
|
|
|
|
if (localeIni.Open(path.c_str(), CONFIG_OPEN_EXISTING) != 0)
|
|
|
|
throw "Could not open locale.ini";
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
HookWidget(ui->language, COMBO_CHANGED, GENERAL_CHANGED);
|
|
|
|
HookWidget(ui->outputMode, COMBO_CHANGED, OUTPUTS_CHANGED);
|
|
|
|
HookWidget(ui->simpleOutputPath, EDIT_CHANGED, OUTPUTS_CHANGED);
|
|
|
|
HookWidget(ui->simpleOutputVBitrate, SCROLL_CHANGED, OUTPUTS_CHANGED);
|
|
|
|
HookWidget(ui->simpleOutputABitrate, COMBO_CHANGED, OUTPUTS_CHANGED);
|
|
|
|
HookWidget(ui->channelSetup, COMBO_CHANGED, AUDIO_RESTART);
|
|
|
|
HookWidget(ui->sampleRate, COMBO_CHANGED, AUDIO_RESTART);
|
|
|
|
HookWidget(ui->desktopAudioDevice1, COMBO_CHANGED, AUDIO_CHANGED);
|
|
|
|
HookWidget(ui->desktopAudioDevice2, COMBO_CHANGED, AUDIO_CHANGED);
|
|
|
|
HookWidget(ui->auxAudioDevice1, COMBO_CHANGED, AUDIO_CHANGED);
|
|
|
|
HookWidget(ui->auxAudioDevice2, COMBO_CHANGED, AUDIO_CHANGED);
|
|
|
|
HookWidget(ui->auxAudioDevice3, COMBO_CHANGED, AUDIO_CHANGED);
|
|
|
|
HookWidget(ui->renderer, COMBO_CHANGED, VIDEO_RESTART);
|
|
|
|
HookWidget(ui->adapter, COMBO_CHANGED, VIDEO_RESTART);
|
|
|
|
HookWidget(ui->baseResolution, CBEDIT_CHANGED, VIDEO_RES);
|
|
|
|
HookWidget(ui->outputResolution, CBEDIT_CHANGED, VIDEO_RES);
|
|
|
|
HookWidget(ui->downscaleFilter, COMBO_CHANGED, VIDEO_CHANGED);
|
|
|
|
HookWidget(ui->fpsType, COMBO_CHANGED, VIDEO_CHANGED);
|
|
|
|
HookWidget(ui->fpsCommon, COMBO_CHANGED, VIDEO_CHANGED);
|
|
|
|
HookWidget(ui->fpsInteger, SCROLL_CHANGED, VIDEO_CHANGED);
|
|
|
|
HookWidget(ui->fpsInteger, SCROLL_CHANGED, VIDEO_CHANGED);
|
|
|
|
HookWidget(ui->fpsNumerator, SCROLL_CHANGED, VIDEO_CHANGED);
|
|
|
|
HookWidget(ui->fpsDenominator, SCROLL_CHANGED, VIDEO_CHANGED);
|
|
|
|
|
2014-05-09 15:04:39 -07:00
|
|
|
//Apply button disabled until change.
|
|
|
|
EnableApplyButton(false);
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
LoadServiceTypes();
|
|
|
|
LoadServiceInfo();
|
2014-01-26 14:36:15 -08:00
|
|
|
LoadSettings(false);
|
|
|
|
}
|
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
void OBSBasicSettings::SaveCombo(QComboBox *widget, const char *section,
|
|
|
|
const char *value)
|
|
|
|
{
|
|
|
|
if (WidgetChanged(widget))
|
|
|
|
config_set_string(main->Config(), section, value,
|
|
|
|
QT_TO_UTF8(widget->currentText()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::SaveComboData(QComboBox *widget, const char *section,
|
|
|
|
const char *value)
|
|
|
|
{
|
|
|
|
if (WidgetChanged(widget)) {
|
|
|
|
QString str = GetComboData(widget);
|
|
|
|
config_set_string(main->Config(), section, value,
|
|
|
|
QT_TO_UTF8(str));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::SaveEdit(QLineEdit *widget, const char *section,
|
|
|
|
const char *value)
|
|
|
|
{
|
|
|
|
if (WidgetChanged(widget))
|
|
|
|
config_set_string(main->Config(), section, value,
|
|
|
|
QT_TO_UTF8(widget->text()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::SaveSpinBox(QSpinBox *widget, const char *section,
|
|
|
|
const char *value)
|
|
|
|
{
|
|
|
|
if (WidgetChanged(widget))
|
|
|
|
config_set_int(main->Config(), section, value, widget->value());
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
void OBSBasicSettings::LoadServiceTypes()
|
|
|
|
{
|
|
|
|
const char *type;
|
|
|
|
size_t idx = 0;
|
|
|
|
|
|
|
|
while (obs_enum_service_types(idx++, &type)) {
|
|
|
|
const char *name = obs_service_getdisplayname(type,
|
|
|
|
App()->GetLocale());
|
|
|
|
QString qName = QT_UTF8(name);
|
|
|
|
QString qType = QT_UTF8(type);
|
|
|
|
|
|
|
|
ui->streamType->addItem(qName, qType);
|
|
|
|
}
|
|
|
|
|
|
|
|
type = obs_service_gettype(main->GetService());
|
|
|
|
SetComboByValue(ui->streamType, type);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::LoadServiceInfo()
|
|
|
|
{
|
|
|
|
QLayout *layout = ui->streamContainer->layout();
|
|
|
|
obs_service_t service = main->GetService();
|
|
|
|
obs_data_t settings = obs_service_get_settings(service);
|
|
|
|
obs_properties_t properties = obs_service_properties(service,
|
|
|
|
App()->GetLocale());
|
|
|
|
|
|
|
|
delete streamProperties;
|
|
|
|
streamProperties = new OBSPropertiesView(
|
|
|
|
settings,
|
|
|
|
properties,
|
|
|
|
service,
|
|
|
|
(PropertiesUpdateCallback)obs_service_update,
|
|
|
|
170);
|
|
|
|
|
|
|
|
layout->addWidget(streamProperties);
|
|
|
|
|
|
|
|
obs_data_release(settings);
|
|
|
|
}
|
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
void OBSBasicSettings::LoadLanguageList()
|
|
|
|
{
|
|
|
|
const char *currentLang = config_get_string(GetGlobalConfig(),
|
|
|
|
"General", "Language");
|
|
|
|
|
|
|
|
ui->language->clear();
|
|
|
|
|
|
|
|
size_t numSections = config_num_sections(localeIni);
|
|
|
|
|
|
|
|
for (size_t i = 0; i < numSections; i++) {
|
|
|
|
const char *tag = config_get_section(localeIni, i);
|
|
|
|
const char *name = config_get_string(localeIni, tag, "Name");
|
|
|
|
int idx = ui->language->count();
|
|
|
|
|
|
|
|
ui->language->addItem(QT_UTF8(name), QT_UTF8(tag));
|
|
|
|
|
|
|
|
if (strcmp(tag, currentLang) == 0)
|
|
|
|
ui->language->setCurrentIndex(idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
ui->language->model()->sort(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::LoadGeneralSettings()
|
|
|
|
{
|
|
|
|
loading = true;
|
|
|
|
|
|
|
|
LoadLanguageList();
|
|
|
|
|
|
|
|
loading = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::LoadRendererList()
|
|
|
|
{
|
|
|
|
const char *renderer = config_get_string(GetGlobalConfig(), "Video",
|
|
|
|
"Renderer");
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
ui->renderer->addItem(QT_UTF8("Direct3D 11"));
|
|
|
|
#endif
|
|
|
|
ui->renderer->addItem(QT_UTF8("OpenGL"));
|
|
|
|
|
|
|
|
int idx = ui->renderer->findText(QT_UTF8(renderer));
|
|
|
|
if (idx == -1)
|
|
|
|
idx = 0;
|
|
|
|
|
|
|
|
ui->renderer->setCurrentIndex(idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
Q_DECLARE_METATYPE(MonitorInfo);
|
|
|
|
|
|
|
|
static string ResString(uint32_t cx, uint32_t cy)
|
|
|
|
{
|
|
|
|
stringstream res;
|
|
|
|
res << cx << "x" << cy;
|
|
|
|
return res.str();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* some nice default output resolution vals */
|
|
|
|
static const double vals[] =
|
|
|
|
{
|
|
|
|
1.0,
|
|
|
|
1.25,
|
|
|
|
(1.0/0.75),
|
|
|
|
1.5,
|
|
|
|
(1.0/0.6),
|
|
|
|
1.75,
|
|
|
|
2.0,
|
|
|
|
2.25,
|
|
|
|
2.5,
|
|
|
|
2.75,
|
|
|
|
3.0
|
|
|
|
};
|
|
|
|
|
|
|
|
static const size_t numVals = sizeof(vals)/sizeof(double);
|
|
|
|
|
|
|
|
void OBSBasicSettings::ResetDownscales(uint32_t cx, uint32_t cy)
|
|
|
|
{
|
2014-02-23 15:27:19 -08:00
|
|
|
ui->outputResolution->clear();
|
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
for (size_t idx = 0; idx < numVals; idx++) {
|
|
|
|
uint32_t downscaleCX = uint32_t(double(cx) / vals[idx]);
|
|
|
|
uint32_t downscaleCY = uint32_t(double(cy) / vals[idx]);
|
|
|
|
|
|
|
|
string res = ResString(downscaleCX, downscaleCY);
|
|
|
|
ui->outputResolution->addItem(res.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
ui->outputResolution->lineEdit()->setText(ResString(cx, cy).c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::LoadResolutionLists()
|
|
|
|
{
|
2014-03-06 20:08:12 -08:00
|
|
|
uint32_t cx = config_get_uint(main->Config(), "Video", "BaseCX");
|
|
|
|
uint32_t cy = config_get_uint(main->Config(), "Video", "BaseCY");
|
2014-01-26 14:36:15 -08:00
|
|
|
vector<MonitorInfo> monitors;
|
|
|
|
|
|
|
|
ui->baseResolution->clear();
|
|
|
|
|
|
|
|
GetMonitors(monitors);
|
|
|
|
|
|
|
|
for (MonitorInfo &monitor : monitors) {
|
|
|
|
string res = ResString(monitor.cx, monitor.cy);
|
|
|
|
ui->baseResolution->addItem(res.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
ResetDownscales(cx, cy);
|
|
|
|
|
2014-02-22 19:14:19 -08:00
|
|
|
ui->baseResolution->lineEdit()->setText(ResString(cx, cy).c_str());
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
cx = config_get_uint(main->Config(), "Video", "OutputCX");
|
|
|
|
cy = config_get_uint(main->Config(), "Video", "OutputCY");
|
2014-01-26 14:36:15 -08:00
|
|
|
|
|
|
|
ui->outputResolution->lineEdit()->setText(ResString(cx, cy).c_str());
|
|
|
|
}
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
static inline void LoadFPSCommon(OBSBasic *main, Ui::OBSBasicSettings *ui)
|
2014-01-26 14:36:15 -08:00
|
|
|
{
|
2014-03-06 20:08:12 -08:00
|
|
|
const char *val = config_get_string(main->Config(), "Video",
|
2014-01-26 14:36:15 -08:00
|
|
|
"FPSCommon");
|
|
|
|
|
|
|
|
int idx = ui->fpsCommon->findText(val);
|
|
|
|
if (idx == -1) idx = 3;
|
|
|
|
ui->fpsCommon->setCurrentIndex(idx);
|
|
|
|
}
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
static inline void LoadFPSInteger(OBSBasic *main, Ui::OBSBasicSettings *ui)
|
2014-01-26 14:36:15 -08:00
|
|
|
{
|
2014-03-06 20:08:12 -08:00
|
|
|
uint32_t val = config_get_uint(main->Config(), "Video", "FPSInt");
|
2014-01-26 14:36:15 -08:00
|
|
|
ui->fpsInteger->setValue(val);
|
|
|
|
}
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
static inline void LoadFPSFraction(OBSBasic *main, Ui::OBSBasicSettings *ui)
|
2014-01-26 14:36:15 -08:00
|
|
|
{
|
2014-03-06 20:08:12 -08:00
|
|
|
uint32_t num = config_get_uint(main->Config(), "Video", "FPSNum");
|
|
|
|
uint32_t den = config_get_uint(main->Config(), "Video", "FPSDen");
|
2014-01-26 14:36:15 -08:00
|
|
|
|
|
|
|
ui->fpsNumerator->setValue(num);
|
|
|
|
ui->fpsDenominator->setValue(den);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::LoadFPSData()
|
|
|
|
{
|
2014-03-06 20:08:12 -08:00
|
|
|
LoadFPSCommon(main, ui.get());
|
|
|
|
LoadFPSInteger(main, ui.get());
|
|
|
|
LoadFPSFraction(main, ui.get());
|
2014-01-26 14:36:15 -08:00
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
uint32_t fpsType = config_get_uint(main->Config(), "Video",
|
2014-01-28 23:40:04 -08:00
|
|
|
"FPSType");
|
|
|
|
if (fpsType > 2) fpsType = 0;
|
2014-01-26 14:36:15 -08:00
|
|
|
|
|
|
|
ui->fpsType->setCurrentIndex(fpsType);
|
|
|
|
ui->fpsTypes->setCurrentIndex(fpsType);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::LoadVideoSettings()
|
|
|
|
{
|
|
|
|
loading = true;
|
|
|
|
|
2014-02-22 19:14:19 -08:00
|
|
|
if (video_output_active(obs_video())) {
|
|
|
|
ui->videoPage->setEnabled(false);
|
2014-05-10 18:47:48 -07:00
|
|
|
ui->videoMsg->setText(
|
|
|
|
QTStr("Basic.Settings.Video.CurrentlyActive"));
|
2014-02-22 19:14:19 -08:00
|
|
|
}
|
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
LoadRendererList();
|
|
|
|
LoadResolutionLists();
|
|
|
|
LoadFPSData();
|
|
|
|
|
|
|
|
loading = false;
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
void OBSBasicSettings::LoadSimpleOutputSettings()
|
2014-03-10 13:10:35 -07:00
|
|
|
{
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
const char *path = config_get_string(main->Config(), "SimpleOutput",
|
2014-05-20 23:27:27 -07:00
|
|
|
"FilePath");
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
int videoBitrate = config_get_uint(main->Config(), "SimpleOutput",
|
2014-03-10 13:10:35 -07:00
|
|
|
"VBitrate");
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
int audioBitrate = config_get_uint(main->Config(), "SimpleOutput",
|
2014-03-10 13:10:35 -07:00
|
|
|
"ABitrate");
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
ui->simpleOutputPath->setText(path);
|
|
|
|
ui->simpleOutputVBitrate->setValue(videoBitrate);
|
|
|
|
|
|
|
|
SetComboByName(ui->simpleOutputABitrate,
|
|
|
|
std::to_string(audioBitrate).c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::LoadOutputSettings()
|
|
|
|
{
|
|
|
|
loading = true;
|
|
|
|
|
|
|
|
LoadSimpleOutputSettings();
|
2014-03-10 13:10:35 -07:00
|
|
|
|
|
|
|
loading = false;
|
|
|
|
}
|
|
|
|
|
2014-03-06 06:02:25 -08:00
|
|
|
static inline void LoadListValue(QComboBox *widget, const char *text,
|
|
|
|
const char *val)
|
|
|
|
{
|
|
|
|
widget->addItem(QT_UTF8(text), QT_UTF8(val));
|
|
|
|
}
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::LoadListValues(QComboBox *widget, obs_property_t prop,
|
|
|
|
const char *configName)
|
2014-03-06 06:02:25 -08:00
|
|
|
{
|
|
|
|
size_t count = obs_property_list_item_count(prop);
|
2014-03-07 11:56:31 -08:00
|
|
|
const char *deviceId = config_get_string(main->Config(), "Audio",
|
|
|
|
configName);
|
2014-03-06 06:02:25 -08:00
|
|
|
|
|
|
|
widget->addItem(QTStr("Disabled"), "disabled");
|
|
|
|
|
|
|
|
for (size_t i = 0; i < count; i++) {
|
|
|
|
const char *name = obs_property_list_item_name(prop, i);
|
2014-04-04 00:30:37 -07:00
|
|
|
const char *val = obs_property_list_item_string(prop, i);
|
2014-03-06 06:02:25 -08:00
|
|
|
LoadListValue(widget, name, val);
|
|
|
|
}
|
2014-03-07 11:56:31 -08:00
|
|
|
|
|
|
|
int idx = widget->findData(QVariant(QT_UTF8(deviceId)));
|
|
|
|
if (idx == -1) {
|
|
|
|
deviceId = config_get_default_string(main->Config(), "Audio",
|
|
|
|
configName);
|
|
|
|
idx = widget->findData(QVariant(QT_UTF8(deviceId)));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (idx != -1)
|
|
|
|
widget->setCurrentIndex(idx);
|
2014-03-06 06:02:25 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::LoadAudioDevices()
|
|
|
|
{
|
2014-03-10 13:59:15 -07:00
|
|
|
const char *input_id = App()->InputAudioSource();
|
|
|
|
const char *output_id = App()->OutputAudioSource();
|
2014-03-06 06:02:25 -08:00
|
|
|
|
2014-03-23 01:07:54 -07:00
|
|
|
obs_properties_t input_props = obs_get_source_properties(
|
2014-03-06 06:02:25 -08:00
|
|
|
OBS_SOURCE_TYPE_INPUT, input_id, App()->GetLocale());
|
2014-03-23 01:07:54 -07:00
|
|
|
obs_properties_t output_props = obs_get_source_properties(
|
2014-03-06 06:02:25 -08:00
|
|
|
OBS_SOURCE_TYPE_INPUT, output_id, App()->GetLocale());
|
|
|
|
|
2014-03-10 13:59:15 -07:00
|
|
|
if (input_props) {
|
|
|
|
obs_property_t inputs = obs_properties_get(input_props,
|
|
|
|
"device_id");
|
|
|
|
LoadListValues(ui->auxAudioDevice1, inputs, "AuxDevice1");
|
|
|
|
LoadListValues(ui->auxAudioDevice2, inputs, "AuxDevice2");
|
|
|
|
LoadListValues(ui->auxAudioDevice3, inputs, "AuxDevice3");
|
|
|
|
obs_properties_destroy(input_props);
|
|
|
|
}
|
2014-03-06 06:02:25 -08:00
|
|
|
|
2014-03-10 13:59:15 -07:00
|
|
|
if (output_props) {
|
|
|
|
obs_property_t outputs = obs_properties_get(output_props,
|
|
|
|
"device_id");
|
|
|
|
LoadListValues(ui->desktopAudioDevice1, outputs,
|
|
|
|
"DesktopDevice1");
|
|
|
|
LoadListValues(ui->desktopAudioDevice2, outputs,
|
|
|
|
"DesktopDevice2");
|
|
|
|
obs_properties_destroy(output_props);
|
|
|
|
}
|
2014-03-06 06:02:25 -08:00
|
|
|
}
|
|
|
|
|
2014-02-23 15:27:19 -08:00
|
|
|
void OBSBasicSettings::LoadAudioSettings()
|
|
|
|
{
|
2014-03-06 20:08:12 -08:00
|
|
|
uint32_t sampleRate = config_get_uint(main->Config(), "Audio",
|
2014-02-23 15:27:19 -08:00
|
|
|
"SampleRate");
|
2014-03-06 20:08:12 -08:00
|
|
|
const char *speakers = config_get_string(main->Config(), "Audio",
|
2014-02-23 15:27:19 -08:00
|
|
|
"ChannelSetup");
|
|
|
|
|
|
|
|
loading = true;
|
|
|
|
|
|
|
|
const char *str;
|
|
|
|
if (sampleRate == 22050)
|
|
|
|
str = "22.05khz";
|
|
|
|
else if (sampleRate == 48000)
|
|
|
|
str = "48khz";
|
|
|
|
else
|
|
|
|
str = "44.1khz";
|
|
|
|
|
|
|
|
int sampleRateIdx = ui->sampleRate->findText(str);
|
|
|
|
if (sampleRateIdx != -1)
|
|
|
|
ui->sampleRate->setCurrentIndex(sampleRateIdx);
|
|
|
|
|
|
|
|
if (strcmp(speakers, "Mono") == 0)
|
|
|
|
ui->channelSetup->setCurrentIndex(0);
|
|
|
|
else
|
|
|
|
ui->channelSetup->setCurrentIndex(1);
|
|
|
|
|
2014-03-06 06:02:25 -08:00
|
|
|
LoadAudioDevices();
|
|
|
|
|
2014-02-23 15:27:19 -08:00
|
|
|
loading = false;
|
|
|
|
}
|
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
void OBSBasicSettings::LoadSettings(bool changedOnly)
|
|
|
|
{
|
|
|
|
if (!changedOnly || generalChanged)
|
|
|
|
LoadGeneralSettings();
|
2014-03-10 13:10:35 -07:00
|
|
|
if (!changedOnly || outputsChanged)
|
|
|
|
LoadOutputSettings();
|
2014-02-23 15:27:19 -08:00
|
|
|
if (!changedOnly || audioChanged)
|
|
|
|
LoadAudioSettings();
|
2014-01-26 14:36:15 -08:00
|
|
|
if (!changedOnly || videoChanged)
|
|
|
|
LoadVideoSettings();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::SaveGeneralSettings()
|
|
|
|
{
|
|
|
|
int languageIndex = ui->language->currentIndex();
|
|
|
|
QVariant langData = ui->language->itemData(languageIndex);
|
|
|
|
string language = langData.toString().toStdString();
|
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
if (WidgetChanged(ui->language))
|
|
|
|
config_set_string(GetGlobalConfig(), "General", "Language",
|
|
|
|
language.c_str());
|
2014-01-26 14:36:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSBasicSettings::SaveVideoSettings()
|
|
|
|
{
|
|
|
|
QString baseResolution = ui->baseResolution->currentText();
|
|
|
|
QString outputResolution = ui->outputResolution->currentText();
|
|
|
|
int fpsType = ui->fpsType->currentIndex();
|
|
|
|
uint32_t cx, cy;
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
SaveCombo(ui->renderer, "Video", "Renderer");
|
2014-01-26 14:36:15 -08:00
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
if (WidgetChanged(ui->baseResolution) &&
|
|
|
|
ConvertResText(QT_TO_UTF8(baseResolution), cx, cy)) {
|
2014-03-06 20:08:12 -08:00
|
|
|
config_set_uint(main->Config(), "Video", "BaseCX", cx);
|
|
|
|
config_set_uint(main->Config(), "Video", "BaseCY", cy);
|
2014-01-26 14:36:15 -08:00
|
|
|
}
|
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
if (WidgetChanged(ui->outputResolution) &&
|
|
|
|
ConvertResText(QT_TO_UTF8(outputResolution), cx, cy)) {
|
2014-03-06 20:08:12 -08:00
|
|
|
config_set_uint(main->Config(), "Video", "OutputCX", cx);
|
|
|
|
config_set_uint(main->Config(), "Video", "OutputCY", cy);
|
2014-01-26 14:36:15 -08:00
|
|
|
}
|
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
if (WidgetChanged(ui->fpsType))
|
|
|
|
config_set_uint(main->Config(), "Video", "FPSType", fpsType);
|
|
|
|
|
|
|
|
SaveCombo(ui->fpsCommon, "Video", "FPSCommon");
|
|
|
|
SaveSpinBox(ui->fpsInteger, "Video", "FPSInt");
|
|
|
|
SaveSpinBox(ui->fpsNumerator, "Video", "FPSNum");
|
|
|
|
SaveSpinBox(ui->fpsDenominator, "Video", "FPSDen");
|
2014-02-22 19:14:19 -08:00
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
main->ResetVideo();
|
2014-01-26 14:36:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-10 13:10:35 -07:00
|
|
|
/* TODO: Temporary! */
|
|
|
|
void OBSBasicSettings::SaveOutputSettings()
|
|
|
|
{
|
2014-06-23 19:54:20 -07:00
|
|
|
SaveSpinBox(ui->simpleOutputVBitrate, "SimpleOutput", "VBitrate");
|
|
|
|
SaveCombo(ui->simpleOutputABitrate, "SimpleOutput", "ABitrate");
|
|
|
|
SaveEdit(ui->simpleOutputPath, "SimpleOutput", "FilePath");
|
2014-03-07 11:56:31 -08:00
|
|
|
}
|
|
|
|
|
2014-02-23 15:27:19 -08:00
|
|
|
void OBSBasicSettings::SaveAudioSettings()
|
|
|
|
{
|
2014-03-07 11:56:31 -08:00
|
|
|
QString sampleRateStr = ui->sampleRate->currentText();
|
|
|
|
int channelSetupIdx = ui->channelSetup->currentIndex();
|
2014-02-23 15:27:19 -08:00
|
|
|
|
2014-05-15 17:40:53 -07:00
|
|
|
const char *channelSetup = (channelSetupIdx == 0) ? "Mono" : "Stereo";
|
2014-02-23 15:27:19 -08:00
|
|
|
|
|
|
|
int sampleRate = 44100;
|
|
|
|
if (sampleRateStr == "22.05khz")
|
|
|
|
sampleRate = 22050;
|
|
|
|
else if (sampleRateStr == "48khz")
|
|
|
|
sampleRate = 48000;
|
|
|
|
|
2014-06-23 19:54:20 -07:00
|
|
|
if (WidgetChanged(ui->sampleRate))
|
|
|
|
config_set_uint(main->Config(), "Audio", "SampleRate",
|
|
|
|
sampleRate);
|
|
|
|
|
|
|
|
if (WidgetChanged(ui->channelSetup))
|
|
|
|
config_set_string(main->Config(), "Audio", "ChannelSetup",
|
|
|
|
channelSetup);
|
|
|
|
|
|
|
|
SaveComboData(ui->desktopAudioDevice1, "Audio", "DesktopDevice1");
|
|
|
|
SaveComboData(ui->desktopAudioDevice2, "Audio", "DesktopDevice2");
|
|
|
|
SaveComboData(ui->auxAudioDevice1, "Audio", "AuxDevice1");
|
|
|
|
SaveComboData(ui->auxAudioDevice2, "Audio", "AuxDevice2");
|
|
|
|
SaveComboData(ui->auxAudioDevice3, "Audio", "AuxDevice3");
|
2014-03-07 16:03:34 -08:00
|
|
|
|
|
|
|
main->ResetAudioDevices();
|
2014-02-23 15:27:19 -08:00
|
|
|
}
|
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
void OBSBasicSettings::SaveSettings()
|
|
|
|
{
|
|
|
|
if (generalChanged)
|
|
|
|
SaveGeneralSettings();
|
2014-03-10 13:10:35 -07:00
|
|
|
if (outputsChanged)
|
|
|
|
SaveOutputSettings();
|
2014-02-23 15:27:19 -08:00
|
|
|
if (audioChanged)
|
|
|
|
SaveAudioSettings();
|
2014-01-26 14:36:15 -08:00
|
|
|
if (videoChanged)
|
|
|
|
SaveVideoSettings();
|
|
|
|
|
2014-03-06 20:08:12 -08:00
|
|
|
config_save(main->Config());
|
2014-01-26 14:36:15 -08:00
|
|
|
config_save(GetGlobalConfig());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool OBSBasicSettings::QueryChanges()
|
|
|
|
{
|
|
|
|
QMessageBox::StandardButton button;
|
|
|
|
|
|
|
|
button = QMessageBox::question(this,
|
2014-05-10 18:47:48 -07:00
|
|
|
QTStr("Basic.Settings.ConfirmTitle"),
|
|
|
|
QTStr("Basic.Settings.Confirm"),
|
2014-01-26 14:36:15 -08:00
|
|
|
QMessageBox::Yes | QMessageBox::No |
|
|
|
|
QMessageBox::Cancel);
|
|
|
|
|
|
|
|
if (button == QMessageBox::Cancel)
|
|
|
|
return false;
|
|
|
|
else if (button == QMessageBox::Yes)
|
|
|
|
SaveSettings();
|
|
|
|
else
|
|
|
|
LoadSettings(true);
|
|
|
|
|
|
|
|
ClearChanged();
|
|
|
|
return true;
|
2013-12-11 20:50:10 -08:00
|
|
|
}
|
|
|
|
|
2014-01-24 20:19:50 -08:00
|
|
|
void OBSBasicSettings::closeEvent(QCloseEvent *event)
|
2013-12-11 20:50:10 -08:00
|
|
|
{
|
2014-01-26 14:36:15 -08:00
|
|
|
if (Changed() && !QueryChanges())
|
|
|
|
event->ignore();
|
2013-12-17 12:56:58 -08:00
|
|
|
}
|
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
void OBSBasicSettings::on_listWidget_itemSelectionChanged()
|
2013-12-17 12:56:58 -08:00
|
|
|
{
|
2014-01-26 14:36:15 -08:00
|
|
|
int row = ui->listWidget->currentRow();
|
|
|
|
|
|
|
|
if (loading || row == pageIndex)
|
|
|
|
return;
|
|
|
|
|
|
|
|
pageIndex = row;
|
2013-12-17 12:56:58 -08:00
|
|
|
}
|
|
|
|
|
2014-01-24 20:19:50 -08:00
|
|
|
void OBSBasicSettings::on_buttonBox_clicked(QAbstractButton *button)
|
2013-12-17 12:56:58 -08:00
|
|
|
{
|
2014-01-26 14:36:15 -08:00
|
|
|
QDialogButtonBox::ButtonRole val = ui->buttonBox->buttonRole(button);
|
|
|
|
|
|
|
|
if (val == QDialogButtonBox::ApplyRole ||
|
|
|
|
val == QDialogButtonBox::AcceptRole) {
|
|
|
|
SaveSettings();
|
|
|
|
ClearChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (val == QDialogButtonBox::AcceptRole ||
|
|
|
|
val == QDialogButtonBox::RejectRole) {
|
|
|
|
ClearChanged();
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
void OBSBasicSettings::on_streamType_currentIndexChanged(int idx)
|
|
|
|
{
|
|
|
|
QString val = ui->streamType->itemData(idx).toString();
|
|
|
|
obs_service_t newService;
|
|
|
|
|
|
|
|
if (loading)
|
|
|
|
return;
|
|
|
|
|
|
|
|
delete streamProperties;
|
|
|
|
streamProperties = nullptr;
|
|
|
|
|
|
|
|
newService = obs_service_create(QT_TO_UTF8(val), nullptr, nullptr);
|
|
|
|
if (newService)
|
|
|
|
main->SetService(newService);
|
|
|
|
|
|
|
|
LoadServiceInfo();
|
|
|
|
}
|
|
|
|
|
2014-05-20 23:27:27 -07:00
|
|
|
void OBSBasicSettings::on_simpleOutputBrowse_clicked()
|
|
|
|
{
|
|
|
|
QString dir = QFileDialog::getExistingDirectory(this,
|
|
|
|
QTStr("OpenDirectory"),
|
|
|
|
ui->simpleOutputPath->text(),
|
|
|
|
QFileDialog::ShowDirsOnly |
|
|
|
|
QFileDialog::DontResolveSymlinks);
|
|
|
|
if (dir.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
ui->simpleOutputPath->setText(dir);
|
|
|
|
}
|
|
|
|
|
obs-studio UI: Implement stream settings UI
- Updated the services API so that it links up with an output and
the output gets data from that service rather than via settings.
This allows the service context to have control over how an output is
used, and makes it so that the URL/key/etc isn't necessarily some
static setting.
Also, if the service is attached to an output, it will stick around
until the output is destroyed.
- The settings interface has been updated so that it can allow the
usage of service plugins. What this means is that now you can create
a service plugin that can control aspects of the stream, and it
allows each service to create their own user interface if they create
a service plugin module.
- Testing out saving of current service information. Saves/loads from
JSON in to obs_data_t, seems to be working quite nicely, and the
service object information is saved/preserved on exit, and loaded
again on startup.
- I agonized over the settings user interface for days, and eventually
I just decided that the only way that users weren't going to be
fumbling over options was to split up the settings in to simple/basic
output, pre-configured, and then advanced for advanced use (such as
multiple outputs or services, which I'll implement later).
This was particularly painful to really design right, I wanted more
features and wanted to include everything in one interface but
ultimately just realized from experience that users are just not
technically knowledgable about it and will end up fumbling with the
settings rather than getting things done.
Basically, what this means is that casual users only have to enter in
about 3 things to configure their stream: Stream key, audio bitrate,
and video bitrate. I am really happy with this interface for those
types of users, but it definitely won't be sufficient for advanced
usage or for custom outputs, so that stuff will have to be separated.
- Improved the JSON usage for the 'common streaming services' context,
I realized that JSON arrays are there to ensure sorting, while
forgetting that general items are optimized for hashing. So
basically I'm just using arrays now to sort items in it.
2014-04-24 01:49:07 -07:00
|
|
|
static inline bool StreamExists(const char *name)
|
|
|
|
{
|
|
|
|
return obs_get_service_by_name(name) != nullptr;
|
|
|
|
}
|
|
|
|
|
2014-05-10 18:47:48 -07:00
|
|
|
#define INVALID_RES_STR "Basic.Settings.Video.InvalidResolution"
|
|
|
|
|
2014-01-26 14:36:15 -08:00
|
|
|
static bool ValidResolutions(Ui::OBSBasicSettings *ui)
|
|
|
|
{
|
|
|
|
QString baseRes = ui->baseResolution->lineEdit()->text();
|
|
|
|
QString outputRes = ui->outputResolution->lineEdit()->text();
|
|
|
|
uint32_t cx, cy;
|
|
|
|
|
|
|
|
if (!ConvertResText(QT_TO_UTF8(baseRes), cx, cy) ||
|
|
|
|
!ConvertResText(QT_TO_UTF8(outputRes), cx, cy)) {
|
|
|
|
|
2014-05-10 18:47:48 -07:00
|
|
|
ui->videoMsg->setText(QTStr(INVALID_RES_STR));
|
2014-01-26 14:36:15 -08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-02-22 19:14:19 -08:00
|
|
|
ui->videoMsg->setText("");
|
2014-01-26 14:36:15 -08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::on_baseResolution_editTextChanged(const QString &text)
|
2014-01-26 14:36:15 -08:00
|
|
|
{
|
2014-03-07 11:56:31 -08:00
|
|
|
if (!loading && ValidResolutions(ui.get())) {
|
2014-03-10 14:00:53 -07:00
|
|
|
QString baseResolution = text;
|
2014-03-07 11:56:31 -08:00
|
|
|
uint32_t cx, cy;
|
2014-02-14 14:13:36 -08:00
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
ConvertResText(QT_TO_UTF8(baseResolution), cx, cy);
|
|
|
|
ResetDownscales(cx, cy);
|
|
|
|
}
|
2014-01-26 14:36:15 -08:00
|
|
|
}
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::GeneralChanged()
|
2014-02-23 15:27:19 -08:00
|
|
|
{
|
2014-05-09 15:04:39 -07:00
|
|
|
if (!loading) {
|
2014-03-07 11:56:31 -08:00
|
|
|
generalChanged = true;
|
2014-06-23 19:54:20 -07:00
|
|
|
sender()->setProperty("changed", QVariant(true));
|
2014-05-09 15:04:39 -07:00
|
|
|
EnableApplyButton(true);
|
|
|
|
}
|
2014-02-23 15:27:19 -08:00
|
|
|
}
|
|
|
|
|
2014-03-10 13:10:35 -07:00
|
|
|
void OBSBasicSettings::OutputsChanged()
|
|
|
|
{
|
2014-05-09 15:04:39 -07:00
|
|
|
if (!loading) {
|
2014-03-10 13:10:35 -07:00
|
|
|
outputsChanged = true;
|
2014-06-23 19:54:20 -07:00
|
|
|
sender()->setProperty("changed", QVariant(true));
|
2014-05-09 15:04:39 -07:00
|
|
|
EnableApplyButton(true);
|
|
|
|
}
|
2014-03-10 13:10:35 -07:00
|
|
|
}
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::AudioChanged()
|
2014-02-23 15:27:19 -08:00
|
|
|
{
|
2014-05-09 15:04:39 -07:00
|
|
|
if (!loading) {
|
2014-02-23 15:27:19 -08:00
|
|
|
audioChanged = true;
|
2014-06-23 19:54:20 -07:00
|
|
|
sender()->setProperty("changed", QVariant(true));
|
2014-05-09 15:04:39 -07:00
|
|
|
EnableApplyButton(true);
|
|
|
|
}
|
2014-02-23 15:27:19 -08:00
|
|
|
}
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::AudioChangedRestart()
|
2014-02-23 15:27:19 -08:00
|
|
|
{
|
2014-02-23 17:00:09 -08:00
|
|
|
if (!loading) {
|
2014-02-23 15:27:19 -08:00
|
|
|
audioChanged = true;
|
2014-05-10 18:47:48 -07:00
|
|
|
ui->audioMsg->setText(QTStr("Basic.Settings.ProgramRestart"));
|
2014-06-23 19:54:20 -07:00
|
|
|
sender()->setProperty("changed", QVariant(true));
|
2014-05-09 15:04:39 -07:00
|
|
|
EnableApplyButton(true);
|
2014-02-23 17:00:09 -08:00
|
|
|
}
|
2014-02-23 15:27:19 -08:00
|
|
|
}
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::VideoChangedRestart()
|
2014-01-26 14:36:15 -08:00
|
|
|
{
|
|
|
|
if (!loading) {
|
|
|
|
videoChanged = true;
|
2014-05-10 18:47:48 -07:00
|
|
|
ui->videoMsg->setText(QTStr("Basic.Settings.ProgramRestart"));
|
2014-06-23 19:54:20 -07:00
|
|
|
sender()->setProperty("changed", QVariant(true));
|
2014-05-09 15:04:39 -07:00
|
|
|
EnableApplyButton(true);
|
2014-01-26 14:36:15 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::VideoChangedResolution()
|
2014-01-26 14:36:15 -08:00
|
|
|
{
|
2014-05-09 15:04:39 -07:00
|
|
|
if (!loading && ValidResolutions(ui.get())) {
|
2014-01-26 14:36:15 -08:00
|
|
|
videoChanged = true;
|
2014-06-23 19:54:20 -07:00
|
|
|
sender()->setProperty("changed", QVariant(true));
|
2014-05-09 15:04:39 -07:00
|
|
|
EnableApplyButton(true);
|
|
|
|
}
|
2013-12-13 22:11:23 -08:00
|
|
|
}
|
2014-02-23 15:27:19 -08:00
|
|
|
|
2014-03-07 11:56:31 -08:00
|
|
|
void OBSBasicSettings::VideoChanged()
|
2014-02-23 15:27:19 -08:00
|
|
|
{
|
2014-05-09 15:04:39 -07:00
|
|
|
if (!loading) {
|
2014-02-23 15:27:19 -08:00
|
|
|
videoChanged = true;
|
2014-06-23 19:54:20 -07:00
|
|
|
sender()->setProperty("changed", QVariant(true));
|
2014-05-09 15:04:39 -07:00
|
|
|
EnableApplyButton(true);
|
|
|
|
}
|
2014-02-23 15:27:19 -08:00
|
|
|
}
|