diff --git a/UI/CMakeLists.txt b/UI/CMakeLists.txt
index 0530b9fce..ca0457204 100644
--- a/UI/CMakeLists.txt
+++ b/UI/CMakeLists.txt
@@ -152,8 +152,6 @@ target_sources(
crash-report.cpp
crash-report.hpp
display-helpers.hpp
- streaming-helpers.cpp
- streaming-helpers.hpp
platform.hpp
qt-display.cpp
qt-display.hpp
diff --git a/UI/data/locale/en-US.ini b/UI/data/locale/en-US.ini
index 503227322..80954326b 100644
--- a/UI/data/locale/en-US.ini
+++ b/UI/data/locale/en-US.ini
@@ -1084,7 +1084,6 @@ Basic.Settings.Advanced.StreamDelay.Duration="Duration"
Basic.Settings.Advanced.StreamDelay.Preserve="Preserve cutoff point (increase delay) when reconnecting"
Basic.Settings.Advanced.StreamDelay.MemoryUsage="Estimated Memory Usage: %1 MB"
Basic.Settings.Advanced.Network="Network"
-Basic.Settings.Advanced.Network.Disabled="The currently selected streaming protocol does not support changing network settings."
Basic.Settings.Advanced.Network.BindToIP="Bind to IP"
Basic.Settings.Advanced.Network.EnableNewSocketLoop="Enable network optimizations"
Basic.Settings.Advanced.Network.EnableLowLatencyMode="Enable TCP pacing"
diff --git a/UI/forms/AutoConfigStreamPage.ui b/UI/forms/AutoConfigStreamPage.ui
index b5ee7b145..a6b858082 100644
--- a/UI/forms/AutoConfigStreamPage.ui
+++ b/UI/forms/AutoConfigStreamPage.ui
@@ -6,7 +6,7 @@
0
0
- 726
+ 692
407
@@ -89,14 +89,7 @@
0
-
-
-
-
- 0
- 0
-
-
-
+
-
diff --git a/UI/forms/OBSBasicSettings.ui b/UI/forms/OBSBasicSettings.ui
index 51def4a8e..c7c480cd1 100644
--- a/UI/forms/OBSBasicSettings.ui
+++ b/UI/forms/OBSBasicSettings.ui
@@ -5565,15 +5565,8 @@
2
-
-
-
-
- Basic.Settings.Advanced.Network.Disabled
-
-
-
- -
-
+
-
+
Basic.Settings.Advanced.Network.BindToIP
@@ -5582,17 +5575,17 @@
- -
+
-
- -
+
-
Basic.Settings.Advanced.Network.EnableNewSocketLoop
- -
+
-
false
@@ -5602,7 +5595,7 @@
- -
+
-
Qt::Horizontal
@@ -5615,7 +5608,7 @@
- -
+
-
Basic.Settings.Output.DynamicBitrate.TT
diff --git a/UI/streaming-helpers.cpp b/UI/streaming-helpers.cpp
deleted file mode 100644
index 24ffedc5e..000000000
--- a/UI/streaming-helpers.cpp
+++ /dev/null
@@ -1,205 +0,0 @@
-#include "streaming-helpers.hpp"
-#include "qt-wrappers.hpp"
-#include "obs-app.hpp"
-
-#include "../plugins/rtmp-services/rtmp-format-ver.h"
-
-#include
-#include
-#include
-
-using namespace json11;
-
-static Json open_json_file(const char *path)
-{
- BPtr file_data = os_quick_read_utf8_file(path);
- if (!file_data)
- return Json();
-
- std::string err;
- Json json = Json::parse(file_data, err);
- if (json["format_version"].int_value() != RTMP_SERVICES_FORMAT_VERSION)
- return Json();
- return json;
-}
-
-static inline bool name_matches(const Json &service, const char *name)
-{
- if (service["name"].string_value() == name)
- return true;
-
- auto &alt_names = service["alt_names"].array_items();
- for (const Json &alt_name : alt_names) {
- if (alt_name.string_value() == name) {
- return true;
- }
- }
-
- return false;
-}
-
-Json get_services_json()
-{
- obs_module_t *mod = obs_get_module("rtmp-services");
- Json root;
-
- BPtr file = obs_module_get_config_path(mod, "services.json");
- if (file)
- root = open_json_file(file);
-
- if (root.is_null()) {
- file = obs_find_module_file(mod, "services.json");
- if (file)
- root = open_json_file(file);
- }
-
- return root;
-}
-
-Json get_service_from_json(const Json &root, const char *name)
-{
- auto &services = root["services"].array_items();
- for (const Json &service : services) {
- if (name_matches(service, name)) {
- return service;
- }
- }
-
- return Json();
-}
-
-bool StreamSettingsUI::IsServiceOutputHasNetworkFeatures()
-{
- if (IsCustomService())
- return ui_customServer->text().startsWith("rtmp");
-
- Json service = get_service_from_json(
- GetServicesJson(), QT_TO_UTF8(ui_service->currentText()));
-
- if (!service["recommended"]["output"].is_string())
- return true;
-
- if (service["recommended"]["output"].string_value().compare(
- "rtmp_output") == 0)
- return true;
-
- return false;
-}
-
-void StreamSettingsUI::UpdateMoreInfoLink()
-{
- if (IsCustomService()) {
- ui_moreInfoButton->hide();
- return;
- }
-
- QString serviceName = ui_service->currentText();
- Json service = get_service_from_json(GetServicesJson(),
- QT_TO_UTF8(serviceName));
-
- const std::string &more_info_link =
- service["more_info_link"].string_value();
-
- if (more_info_link.empty()) {
- ui_moreInfoButton->hide();
- } else {
- ui_moreInfoButton->setTargetUrl(QUrl(more_info_link.c_str()));
- ui_moreInfoButton->show();
- }
-}
-
-void StreamSettingsUI::UpdateKeyLink()
-{
- QString serviceName = ui_service->currentText();
- QString customServer = ui_customServer->text().trimmed();
-
- Json service = get_service_from_json(GetServicesJson(),
- QT_TO_UTF8(serviceName));
-
- std::string streamKeyLink = service["stream_key_link"].string_value();
- if (customServer.contains("fbcdn.net") && IsCustomService()) {
- streamKeyLink =
- "https://www.facebook.com/live/producer?ref=OBS";
- }
-
- if (serviceName == "Dacast") {
- ui_streamKeyLabel->setText(
- QTStr("Basic.AutoConfig.StreamPage.EncoderKey"));
- } else {
- ui_streamKeyLabel->setText(
- QTStr("Basic.AutoConfig.StreamPage.StreamKey"));
- }
-
- if (streamKeyLink.empty()) {
- ui_streamKeyButton->hide();
- } else {
- ui_streamKeyButton->setTargetUrl(QUrl(streamKeyLink.c_str()));
- ui_streamKeyButton->show();
- }
-}
-
-void StreamSettingsUI::LoadServices(bool showAll)
-{
- auto &services = GetServicesJson()["services"].array_items();
-
- ui_service->blockSignals(true);
- ui_service->clear();
-
- QStringList names;
-
- for (const Json &service : services) {
- if (!showAll && !service["common"].bool_value())
- continue;
- names.push_back(service["name"].string_value().c_str());
- }
-
- if (showAll)
- names.sort(Qt::CaseInsensitive);
-
- for (QString &name : names)
- ui_service->addItem(name);
-
- if (!showAll) {
- ui_service->addItem(
- QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"),
- QVariant((int)ListOpt::ShowAll));
- }
-
- ui_service->insertItem(
- 0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
- QVariant((int)ListOpt::Custom));
-
- if (!lastService.isEmpty()) {
- int idx = ui_service->findText(lastService);
- if (idx != -1)
- ui_service->setCurrentIndex(idx);
- }
-
- ui_service->blockSignals(false);
-}
-
-void StreamSettingsUI::UpdateServerList()
-{
- QString serviceName = ui_service->currentText();
- bool showMore = ui_service->currentData().toInt() ==
- (int)ListOpt::ShowAll;
-
- if (showMore) {
- LoadServices(true);
- ui_service->showPopup();
- return;
- } else {
- lastService = serviceName;
- }
-
- Json service = get_service_from_json(GetServicesJson(),
- QT_TO_UTF8(serviceName));
-
- ui_server->clear();
-
- auto &servers = service["servers"].array_items();
- for (const Json &entry : servers) {
- ui_server->addItem(entry["name"].string_value().c_str(),
- entry["url"].string_value().c_str());
- }
-}
diff --git a/UI/streaming-helpers.hpp b/UI/streaming-helpers.hpp
deleted file mode 100644
index d314d0054..000000000
--- a/UI/streaming-helpers.hpp
+++ /dev/null
@@ -1,73 +0,0 @@
-#pragma once
-
-#include "url-push-button.hpp"
-#include
-#include
-#include
-
-#include
-
-extern json11::Json get_services_json();
-extern json11::Json get_service_from_json(const json11::Json &root,
- const char *name);
-
-enum class ListOpt : int {
- ShowAll = 1,
- Custom,
-};
-
-class StreamSettingsUI : public QObject {
- Q_OBJECT
-
- QLabel *ui_streamKeyLabel;
- QComboBox *ui_service;
- QComboBox *ui_server;
- QLineEdit *ui_customServer;
- UrlPushButton *ui_moreInfoButton;
- UrlPushButton *ui_streamKeyButton;
-
- json11::Json servicesRoot;
- bool servicesLoaded = false;
- QString lastService;
-
-public:
- inline void Setup(QLabel *streamKeyLabel, QComboBox *service,
- QComboBox *server, QLineEdit *customServer,
- UrlPushButton *moreInfoButton,
- UrlPushButton *streamKeyButton)
- {
- ui_streamKeyLabel = streamKeyLabel;
- ui_service = service;
- ui_server = server;
- ui_customServer = customServer;
- ui_moreInfoButton = moreInfoButton;
- ui_streamKeyButton = streamKeyButton;
- }
-
- inline bool IsCustomService() const
- {
- return ui_service->currentData().toInt() ==
- (int)ListOpt::Custom;
- }
-
- inline void ClearLastService() { lastService.clear(); }
-
- inline json11::Json GetServicesJson()
- {
- if (!servicesLoaded && servicesRoot.is_null()) {
- servicesRoot = get_services_json();
- servicesLoaded = true;
- }
- return servicesRoot;
- }
-
- inline const QString &LastService() const { return lastService; }
-
- bool IsServiceOutputHasNetworkFeatures();
-
-public slots:
- void UpdateMoreInfoLink();
- void UpdateKeyLink();
- void LoadServices(bool showAll);
- void UpdateServerList();
-};
diff --git a/UI/window-basic-auto-config-test.cpp b/UI/window-basic-auto-config-test.cpp
index 346c92f05..17b15e33b 100644
--- a/UI/window-basic-auto-config-test.cpp
+++ b/UI/window-basic-auto-config-test.cpp
@@ -19,7 +19,6 @@
#define wiz reinterpret_cast(wizard())
using namespace std;
-using namespace json11;
/* ------------------------------------------------------------------------- */
@@ -120,19 +119,28 @@ void AutoConfigTestPage::StartRecordingEncoderStage()
void AutoConfigTestPage::GetServers(std::vector &servers)
{
- Json root = get_services_json();
- Json service = get_service_from_json(root, wiz->serviceName.c_str());
+ OBSDataAutoRelease settings = obs_data_create();
+ obs_data_set_string(settings, "service", wiz->serviceName.c_str());
- auto &json_services = service["servers"].array_items();
- for (const Json &server : json_services) {
- const std::string &name = server["name"].string_value();
- const std::string &url = server["url"].string_value();
+ obs_properties_t *ppts = obs_get_service_properties("rtmp_common");
+ obs_property_t *p = obs_properties_get(ppts, "service");
+ obs_property_modified(p, settings);
- if (wiz->CanTestServer(name.c_str())) {
- ServerInfo info(name, url);
+ p = obs_properties_get(ppts, "server");
+ size_t count = obs_property_list_item_count(p);
+ servers.reserve(count);
+
+ for (size_t i = 0; i < count; i++) {
+ const char *name = obs_property_list_item_name(p, i);
+ const char *server = obs_property_list_item_string(p, i);
+
+ if (wiz->CanTestServer(name)) {
+ ServerInfo info(name, server);
servers.push_back(info);
}
}
+
+ obs_properties_destroy(ppts);
}
static inline void string_depad_key(string &key)
diff --git a/UI/window-basic-auto-config.cpp b/UI/window-basic-auto-config.cpp
index 697608331..eb4e72b99 100644
--- a/UI/window-basic-auto-config.cpp
+++ b/UI/window-basic-auto-config.cpp
@@ -23,8 +23,6 @@
#include "youtube-api-wrappers.hpp"
#endif
-using namespace json11;
-
struct QCef;
struct QCefCookieManager;
@@ -242,6 +240,11 @@ bool AutoConfigVideoPage::validatePage()
/* ------------------------------------------------------------------------- */
+enum class ListOpt : int {
+ ShowAll = 1,
+ Custom,
+};
+
AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
: QWizardPage(parent), ui(new Ui_AutoConfigStreamPage)
{
@@ -251,10 +254,6 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
ui->connectAccount2->setVisible(false);
ui->disconnectAccount->setVisible(false);
- streamUi.Setup(ui->streamKeyLabel, ui->service, ui->server,
- ui->customServer, ui->moreInfoButton,
- ui->streamKeyButton);
-
ui->connectedAccountLabel->setVisible(false);
ui->connectedAccountText->setVisible(false);
@@ -275,25 +274,25 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
setTitle(QTStr("Basic.AutoConfig.StreamPage"));
setSubTitle(QTStr("Basic.AutoConfig.StreamPage.SubTitle"));
- streamUi.LoadServices(false);
+ LoadServices(false);
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(ServiceChanged()));
connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
SLOT(ServiceChanged()));
- connect(ui->customServer, SIGNAL(textChanged(const QString &)),
- &streamUi, SLOT(UpdateKeyLink()));
- connect(ui->customServer, SIGNAL(editingFinished()), &streamUi,
+ connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
+ SLOT(UpdateKeyLink()));
+ connect(ui->customServer, SIGNAL(editingFinished()), this,
SLOT(UpdateKeyLink()));
connect(ui->doBandwidthTest, SIGNAL(toggled(bool)), this,
SLOT(ServiceChanged()));
- connect(ui->service, SIGNAL(currentIndexChanged(int)), &streamUi,
+ connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateServerList()));
- connect(ui->service, SIGNAL(currentIndexChanged(int)), &streamUi,
+ connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateKeyLink()));
- connect(ui->service, SIGNAL(currentIndexChanged(int)), &streamUi,
+ connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateMoreInfoLink()));
connect(ui->useStreamKeyAdv, &QPushButton::clicked, this,
@@ -323,11 +322,16 @@ int AutoConfigStreamPage::nextId() const
return AutoConfig::TestPage;
}
+inline bool AutoConfigStreamPage::IsCustomService() const
+{
+ return ui->service->currentData().toInt() == (int)ListOpt::Custom;
+}
+
bool AutoConfigStreamPage::validatePage()
{
OBSDataAutoRelease service_settings = obs_data_create();
- wiz->customServer = streamUi.IsCustomService();
+ wiz->customServer = IsCustomService();
const char *serverType = wiz->customServer ? "rtmp_custom"
: "rtmp_common";
@@ -538,7 +542,7 @@ void AutoConfigStreamPage::on_disconnectAccount_clicked()
ui->connectedAccountText->setVisible(false);
/* Restore key link when disconnecting account */
- streamUi.UpdateKeyLink();
+ UpdateKeyLink();
}
void AutoConfigStreamPage::on_useStreamKey_clicked()
@@ -611,7 +615,7 @@ void AutoConfigStreamPage::ServiceChanged()
std::string service = QT_TO_UTF8(ui->service->currentText());
bool regionBased = service == "Twitch";
bool testBandwidth = ui->doBandwidthTest->isChecked();
- bool custom = streamUi.IsCustomService();
+ bool custom = IsCustomService();
reset_service_ui_fields(service);
@@ -668,13 +672,166 @@ void AutoConfigStreamPage::ServiceChanged()
UpdateCompleted();
}
+void AutoConfigStreamPage::UpdateMoreInfoLink()
+{
+ if (IsCustomService()) {
+ ui->moreInfoButton->hide();
+ return;
+ }
+
+ QString serviceName = ui->service->currentText();
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+ obs_property_t *services = obs_properties_get(props, "service");
+
+ OBSDataAutoRelease settings = obs_data_create();
+
+ obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
+ obs_property_modified(services, settings);
+
+ const char *more_info_link =
+ obs_data_get_string(settings, "more_info_link");
+
+ if (!more_info_link || (*more_info_link == '\0')) {
+ ui->moreInfoButton->hide();
+ } else {
+ ui->moreInfoButton->setTargetUrl(QUrl(more_info_link));
+ ui->moreInfoButton->show();
+ }
+ obs_properties_destroy(props);
+}
+
+void AutoConfigStreamPage::UpdateKeyLink()
+{
+ QString serviceName = ui->service->currentText();
+ QString customServer = ui->customServer->text().trimmed();
+ QString streamKeyLink;
+
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+ obs_property_t *services = obs_properties_get(props, "service");
+
+ OBSDataAutoRelease settings = obs_data_create();
+
+ obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
+ obs_property_modified(services, settings);
+
+ streamKeyLink = obs_data_get_string(settings, "stream_key_link");
+
+ if (customServer.contains("fbcdn.net") && IsCustomService()) {
+ streamKeyLink =
+ "https://www.facebook.com/live/producer?ref=OBS";
+ }
+
+ if (serviceName == "Dacast") {
+ ui->streamKeyLabel->setText(
+ QTStr("Basic.AutoConfig.StreamPage.EncoderKey"));
+ } else {
+ ui->streamKeyLabel->setText(
+ QTStr("Basic.AutoConfig.StreamPage.StreamKey"));
+ }
+
+ if (QString(streamKeyLink).isNull() ||
+ QString(streamKeyLink).isEmpty()) {
+ ui->streamKeyButton->hide();
+ } else {
+ ui->streamKeyButton->setTargetUrl(QUrl(streamKeyLink));
+ ui->streamKeyButton->show();
+ }
+ obs_properties_destroy(props);
+}
+
+void AutoConfigStreamPage::LoadServices(bool showAll)
+{
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+
+ OBSDataAutoRelease settings = obs_data_create();
+
+ obs_data_set_bool(settings, "show_all", showAll);
+
+ obs_property_t *prop = obs_properties_get(props, "show_all");
+ obs_property_modified(prop, settings);
+
+ ui->service->blockSignals(true);
+ ui->service->clear();
+
+ QStringList names;
+
+ obs_property_t *services = obs_properties_get(props, "service");
+ size_t services_count = obs_property_list_item_count(services);
+ for (size_t i = 0; i < services_count; i++) {
+ const char *name = obs_property_list_item_string(services, i);
+ names.push_back(name);
+ }
+
+ if (showAll)
+ names.sort(Qt::CaseInsensitive);
+
+ for (QString &name : names)
+ ui->service->addItem(name);
+
+ if (!showAll) {
+ ui->service->addItem(
+ QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"),
+ QVariant((int)ListOpt::ShowAll));
+ }
+
+ ui->service->insertItem(
+ 0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
+ QVariant((int)ListOpt::Custom));
+
+ if (!lastService.isEmpty()) {
+ int idx = ui->service->findText(lastService);
+ if (idx != -1)
+ ui->service->setCurrentIndex(idx);
+ }
+
+ obs_properties_destroy(props);
+
+ ui->service->blockSignals(false);
+}
+
+void AutoConfigStreamPage::UpdateServerList()
+{
+ QString serviceName = ui->service->currentText();
+ bool showMore = ui->service->currentData().toInt() ==
+ (int)ListOpt::ShowAll;
+
+ if (showMore) {
+ LoadServices(true);
+ ui->service->showPopup();
+ return;
+ } else {
+ lastService = serviceName;
+ }
+
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+ obs_property_t *services = obs_properties_get(props, "service");
+
+ OBSDataAutoRelease settings = obs_data_create();
+
+ obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
+ obs_property_modified(services, settings);
+
+ obs_property_t *servers = obs_properties_get(props, "server");
+
+ ui->server->clear();
+
+ size_t servers_count = obs_property_list_item_count(servers);
+ for (size_t i = 0; i < servers_count; i++) {
+ const char *name = obs_property_list_item_name(servers, i);
+ const char *server = obs_property_list_item_string(servers, i);
+ ui->server->addItem(name, server);
+ }
+
+ obs_properties_destroy(props);
+}
+
void AutoConfigStreamPage::UpdateCompleted()
{
if (ui->stackedWidget->currentIndex() == (int)Section::Connect ||
(ui->key->text().isEmpty() && !auth)) {
ready = false;
} else {
- bool custom = streamUi.IsCustomService();
+ bool custom = IsCustomService();
if (custom) {
ready = !ui->customServer->text().isEmpty();
} else {
@@ -729,10 +886,18 @@ AutoConfig::AutoConfig(QWidget *parent) : QWizard(parent)
/* ----------------------------------------- */
/* check to see if Twitch's "auto" available */
- Json servicesRoot = get_services_json();
- Json serviceJson = get_service_from_json(servicesRoot, "Twitch");
- Json servers = serviceJson["servers"];
- twitchAuto = servers[0]["url"].string_value() == "auto";
+ OBSDataAutoRelease twitchSettings = obs_data_create();
+
+ obs_data_set_string(twitchSettings, "service", "Twitch");
+
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+ obs_properties_apply_settings(props, twitchSettings);
+
+ obs_property_t *p = obs_properties_get(props, "server");
+ const char *first = obs_property_list_item_string(p, 0);
+ twitchAuto = strcmp(first, "auto") == 0;
+
+ obs_properties_destroy(props);
/* ----------------------------------------- */
/* load service/servers */
@@ -765,10 +930,10 @@ AutoConfig::AutoConfig(QWidget *parent) : QWizard(parent)
serviceList->blockSignals(false);
}
- streamPage->streamUi.UpdateServerList();
- streamPage->streamUi.UpdateKeyLink();
- streamPage->streamUi.UpdateMoreInfoLink();
- streamPage->streamUi.ClearLastService();
+ streamPage->UpdateServerList();
+ streamPage->UpdateKeyLink();
+ streamPage->UpdateMoreInfoLink();
+ streamPage->lastService.clear();
if (!customServer) {
QComboBox *serverList = streamPage->ui->server;
diff --git a/UI/window-basic-auto-config.hpp b/UI/window-basic-auto-config.hpp
index 6f3a6aee4..e88d5b502 100644
--- a/UI/window-basic-auto-config.hpp
+++ b/UI/window-basic-auto-config.hpp
@@ -13,10 +13,6 @@
#include
#include
-#include
-
-#include "streaming-helpers.hpp"
-
class Ui_AutoConfigStartPage;
class Ui_AutoConfigVideoPage;
class Ui_AutoConfigStreamPage;
@@ -175,9 +171,11 @@ class AutoConfigStreamPage : public QWizardPage {
std::shared_ptr auth;
std::unique_ptr ui;
+ QString lastService;
bool ready = false;
- StreamSettingsUI streamUi;
+ void LoadServices(bool showAll);
+ inline bool IsCustomService() const;
public:
AutoConfigStreamPage(QWidget *parent = nullptr);
@@ -196,6 +194,9 @@ public slots:
void on_disconnectAccount_clicked();
void on_useStreamKey_clicked();
void ServiceChanged();
+ void UpdateKeyLink();
+ void UpdateMoreInfoLink();
+ void UpdateServerList();
void UpdateCompleted();
void reset_service_ui_fields(std::string &service);
@@ -247,8 +248,7 @@ class AutoConfigTestPage : public QWizardPage {
inline ServerInfo() {}
- inline ServerInfo(const std::string &name_,
- const std::string &address_)
+ inline ServerInfo(const char *name_, const char *address_)
: name(name_), address(address_)
{
}
diff --git a/UI/window-basic-settings-stream.cpp b/UI/window-basic-settings-stream.cpp
index bbc97dc3b..3e4eb15c0 100644
--- a/UI/window-basic-settings-stream.cpp
+++ b/UI/window-basic-settings-stream.cpp
@@ -20,19 +20,27 @@
#include "youtube-api-wrappers.hpp"
#endif
-using namespace json11;
-
struct QCef;
struct QCefCookieManager;
extern QCef *cef;
extern QCefCookieManager *panel_cookies;
+enum class ListOpt : int {
+ ShowAll = 1,
+ Custom,
+};
+
enum class Section : int {
Connect,
StreamKey,
};
+inline bool OBSBasicSettings::IsCustomService() const
+{
+ return ui->service->currentData().toInt() == (int)ListOpt::Custom;
+}
+
void OBSBasicSettings::InitStreamPage()
{
ui->connectAccount2->setVisible(false);
@@ -59,11 +67,7 @@ void OBSBasicSettings::InitStreamPage()
m.setTop(vertSpacing / 2);
ui->streamkeyPageLayout->setContentsMargins(m);
- streamUi.Setup(ui->streamKeyLabel, ui->service, ui->server,
- ui->customServer, ui->moreInfoButton,
- ui->getStreamKeyButton);
-
- streamUi.LoadServices(false);
+ LoadServices(false);
ui->twitchAddonDropdown->addItem(
QTStr("Basic.Settings.Stream.TTVAddon.None"));
@@ -74,9 +78,9 @@ void OBSBasicSettings::InitStreamPage()
ui->twitchAddonDropdown->addItem(
QTStr("Basic.Settings.Stream.TTVAddon.Both"));
- connect(ui->service, SIGNAL(currentIndexChanged(int)), &streamUi,
+ connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateServerList()));
- connect(ui->service, SIGNAL(currentIndexChanged(int)), &streamUi,
+ connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateKeyLink()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateVodTrackSetting()));
@@ -84,19 +88,14 @@ void OBSBasicSettings::InitStreamPage()
SLOT(UpdateServiceRecommendations()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateResFPSLimits()));
- connect(ui->customServer, SIGNAL(textChanged(const QString &)),
- &streamUi, SLOT(UpdateKeyLink()));
+ connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
+ SLOT(UpdateKeyLink()));
connect(ui->ignoreRecommended, SIGNAL(clicked(bool)), this,
SLOT(DisplayEnforceWarning(bool)));
connect(ui->ignoreRecommended, SIGNAL(toggled(bool)), this,
SLOT(UpdateResFPSLimits()));
- connect(ui->service, SIGNAL(currentIndexChanged(int)), &streamUi,
- SLOT(UpdateMoreInfoLink()));
-
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
- SLOT(UpdateAdvNetworkGroup()));
- connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
- SLOT(UpdateAdvNetworkGroup()));
+ SLOT(UpdateMoreInfoLink()));
}
void OBSBasicSettings::LoadStream1Settings()
@@ -143,7 +142,7 @@ void OBSBasicSettings::LoadStream1Settings()
ui->twitchAddonDropdown->setCurrentIndex(idx);
}
- streamUi.UpdateServerList();
+ UpdateServerList();
if (strcmp(type, "rtmp_common") == 0) {
int idx = ui->server->findData(server);
@@ -157,11 +156,11 @@ void OBSBasicSettings::LoadStream1Settings()
ui->key->setText(key);
- streamUi.ClearLastService();
+ lastService.clear();
on_service_currentIndexChanged(0);
- streamUi.UpdateKeyLink();
- streamUi.UpdateMoreInfoLink();
+ UpdateKeyLink();
+ UpdateMoreInfoLink();
UpdateVodTrackSetting();
UpdateServiceRecommendations();
@@ -178,7 +177,7 @@ void OBSBasicSettings::LoadStream1Settings()
void OBSBasicSettings::SaveStream1Settings()
{
- bool customServer = streamUi.IsCustomService();
+ bool customServer = IsCustomService();
const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
obs_service_t *oldService = main->GetService();
@@ -247,6 +246,123 @@ void OBSBasicSettings::SaveStream1Settings()
SaveCheckBox(ui->ignoreRecommended, "Stream1", "IgnoreRecommended");
}
+void OBSBasicSettings::UpdateMoreInfoLink()
+{
+ if (IsCustomService()) {
+ ui->moreInfoButton->hide();
+ return;
+ }
+
+ QString serviceName = ui->service->currentText();
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+ obs_property_t *services = obs_properties_get(props, "service");
+
+ OBSDataAutoRelease settings = obs_data_create();
+
+ obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
+ obs_property_modified(services, settings);
+
+ const char *more_info_link =
+ obs_data_get_string(settings, "more_info_link");
+
+ if (!more_info_link || (*more_info_link == '\0')) {
+ ui->moreInfoButton->hide();
+ } else {
+ ui->moreInfoButton->setTargetUrl(QUrl(more_info_link));
+ ui->moreInfoButton->show();
+ }
+ obs_properties_destroy(props);
+}
+
+void OBSBasicSettings::UpdateKeyLink()
+{
+ QString serviceName = ui->service->currentText();
+ QString customServer = ui->customServer->text().trimmed();
+ QString streamKeyLink;
+
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+ obs_property_t *services = obs_properties_get(props, "service");
+
+ OBSDataAutoRelease settings = obs_data_create();
+
+ obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
+ obs_property_modified(services, settings);
+
+ streamKeyLink = obs_data_get_string(settings, "stream_key_link");
+
+ if (customServer.contains("fbcdn.net") && IsCustomService()) {
+ streamKeyLink =
+ "https://www.facebook.com/live/producer?ref=OBS";
+ }
+
+ if (serviceName == "Dacast") {
+ ui->streamKeyLabel->setText(
+ QTStr("Basic.AutoConfig.StreamPage.EncoderKey"));
+ } else {
+ ui->streamKeyLabel->setText(
+ QTStr("Basic.AutoConfig.StreamPage.StreamKey"));
+ }
+
+ if (QString(streamKeyLink).isNull() ||
+ QString(streamKeyLink).isEmpty()) {
+ ui->getStreamKeyButton->hide();
+ } else {
+ ui->getStreamKeyButton->setTargetUrl(QUrl(streamKeyLink));
+ ui->getStreamKeyButton->show();
+ }
+ obs_properties_destroy(props);
+}
+
+void OBSBasicSettings::LoadServices(bool showAll)
+{
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+
+ OBSDataAutoRelease settings = obs_data_create();
+
+ obs_data_set_bool(settings, "show_all", showAll);
+
+ obs_property_t *prop = obs_properties_get(props, "show_all");
+ obs_property_modified(prop, settings);
+
+ ui->service->blockSignals(true);
+ ui->service->clear();
+
+ QStringList names;
+
+ obs_property_t *services = obs_properties_get(props, "service");
+ size_t services_count = obs_property_list_item_count(services);
+ for (size_t i = 0; i < services_count; i++) {
+ const char *name = obs_property_list_item_string(services, i);
+ names.push_back(name);
+ }
+
+ if (showAll)
+ names.sort(Qt::CaseInsensitive);
+
+ for (QString &name : names)
+ ui->service->addItem(name);
+
+ if (!showAll) {
+ ui->service->addItem(
+ QTStr("Basic.AutoConfig.StreamPage.Service.ShowAll"),
+ QVariant((int)ListOpt::ShowAll));
+ }
+
+ ui->service->insertItem(
+ 0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
+ QVariant((int)ListOpt::Custom));
+
+ if (!lastService.isEmpty()) {
+ int idx = ui->service->findText(lastService);
+ if (idx != -1)
+ ui->service->setCurrentIndex(idx);
+ }
+
+ obs_properties_destroy(props);
+
+ ui->service->blockSignals(false);
+}
+
static inline bool is_auth_service(const std::string &service)
{
return Auth::AuthType(service) != Auth::Type::None;
@@ -319,14 +435,14 @@ void OBSBasicSettings::on_service_currentIndexChanged(int)
return;
std::string service = QT_TO_UTF8(ui->service->currentText());
- bool custom = streamUi.IsCustomService();
+ bool custom = IsCustomService();
ui->disconnectAccount->setVisible(false);
ui->bandwidthTestEnable->setVisible(false);
ui->twitchAddonDropdown->setVisible(false);
ui->twitchAddonLabel->setVisible(false);
- if (streamUi.LastService() != service.c_str()) {
+ if (lastService != service.c_str()) {
reset_service_ui_fields(ui.get(), service, loading);
}
@@ -368,6 +484,42 @@ void OBSBasicSettings::on_service_currentIndexChanged(int)
}
}
+void OBSBasicSettings::UpdateServerList()
+{
+ QString serviceName = ui->service->currentText();
+ bool showMore = ui->service->currentData().toInt() ==
+ (int)ListOpt::ShowAll;
+
+ if (showMore) {
+ LoadServices(true);
+ ui->service->showPopup();
+ return;
+ } else {
+ lastService = serviceName;
+ }
+
+ obs_properties_t *props = obs_get_service_properties("rtmp_common");
+ obs_property_t *services = obs_properties_get(props, "service");
+
+ OBSDataAutoRelease settings = obs_data_create();
+
+ obs_data_set_string(settings, "service", QT_TO_UTF8(serviceName));
+ obs_property_modified(services, settings);
+
+ obs_property_t *servers = obs_properties_get(props, "server");
+
+ ui->server->clear();
+
+ size_t servers_count = obs_property_list_item_count(servers);
+ for (size_t i = 0; i < servers_count; i++) {
+ const char *name = obs_property_list_item_name(servers, i);
+ const char *server = obs_property_list_item_string(servers, i);
+ ui->server->addItem(name, server);
+ }
+
+ obs_properties_destroy(props);
+}
+
void OBSBasicSettings::on_show_clicked()
{
if (ui->key->echoMode() == QLineEdit::Password) {
@@ -392,7 +544,7 @@ void OBSBasicSettings::on_authPwShow_clicked()
OBSService OBSBasicSettings::SpawnTempService()
{
- bool custom = streamUi.IsCustomService();
+ bool custom = IsCustomService();
const char *service_id = custom ? "rtmp_custom" : "rtmp_common";
OBSDataAutoRelease settings = obs_data_create();
@@ -535,7 +687,7 @@ void OBSBasicSettings::on_useStreamKey_clicked()
void OBSBasicSettings::on_useAuth_toggled()
{
- if (!streamUi.IsCustomService())
+ if (!IsCustomService())
return;
bool use_auth = ui->useAuth->isChecked();
@@ -553,7 +705,7 @@ void OBSBasicSettings::UpdateVodTrackSetting()
bool enableVodTrack = ui->service->currentText() == "Twitch";
bool wasEnabled = !!vodTrackCheckbox;
- if (enableForCustomServer && streamUi.IsCustomService())
+ if (enableForCustomServer && IsCustomService())
enableVodTrack = true;
if (enableVodTrack == wasEnabled)
@@ -640,7 +792,7 @@ OBSService OBSBasicSettings::GetStream1Service()
void OBSBasicSettings::UpdateServiceRecommendations()
{
- bool customServer = streamUi.IsCustomService();
+ bool customServer = IsCustomService();
ui->ignoreRecommended->setVisible(!customServer);
ui->enforceSettingsLabel->setVisible(!customServer);
@@ -714,7 +866,7 @@ void OBSBasicSettings::UpdateServiceRecommendations()
void OBSBasicSettings::DisplayEnforceWarning(bool checked)
{
- if (streamUi.IsCustomService())
+ if (IsCustomService())
return;
if (!checked) {
@@ -816,7 +968,7 @@ void OBSBasicSettings::UpdateResFPSLimits()
size_t res_count = 0;
int max_fps = 0;
- if (!streamUi.IsCustomService() && !ignoreRecommended) {
+ if (!IsCustomService() && !ignoreRecommended) {
OBSService service = GetStream1Service();
obs_service_get_supported_resolutions(service, &res_list,
&res_count);
diff --git a/UI/window-basic-settings.cpp b/UI/window-basic-settings.cpp
index 4d309edab..5122bd06c 100644
--- a/UI/window-basic-settings.cpp
+++ b/UI/window-basic-settings.cpp
@@ -934,8 +934,6 @@ OBSBasicSettings::OBSBasicSettings(QWidget *parent)
connect(ui->useStreamKeyAdv, SIGNAL(clicked()), this,
SLOT(UseStreamKeyAdvClicked()));
-
- UpdateAdvNetworkGroup();
}
OBSBasicSettings::~OBSBasicSettings()
@@ -5422,18 +5420,3 @@ void OBSBasicSettings::RecreateOutputResolutionWidget()
ui->outputResolution->lineEdit()->setValidator(
ui->baseResolution->lineEdit()->validator());
}
-
-void OBSBasicSettings::UpdateAdvNetworkGroup()
-{
- bool enabled = streamUi.IsServiceOutputHasNetworkFeatures();
-
- ui->advNetworkDisabled->setVisible(!enabled);
-
- ui->bindToIPLabel->setVisible(enabled);
- ui->bindToIP->setVisible(enabled);
- ui->dynBitrate->setVisible(enabled);
-#ifdef _WIN32
- ui->enableNewSocketLoop->setVisible(enabled);
- ui->enableLowLatencyMode->setVisible(enabled);
-#endif
-}
diff --git a/UI/window-basic-settings.hpp b/UI/window-basic-settings.hpp
index d15b18532..b4bc43583 100644
--- a/UI/window-basic-settings.hpp
+++ b/UI/window-basic-settings.hpp
@@ -28,7 +28,6 @@
#include
-#include "streaming-helpers.hpp"
#include "auth-base.hpp"
class OBSBasic;
@@ -42,8 +41,6 @@ class OBSHotkeyWidget;
#include "ui_OBSBasicSettings.h"
-#include
-
#define VOLUME_METER_DECAY_FAST 23.53
#define VOLUME_METER_DECAY_MEDIUM 11.76
#define VOLUME_METER_DECAY_SLOW 8.57
@@ -162,8 +159,6 @@ private:
uint32_t outputCX = 0;
uint32_t outputCY = 0;
- StreamSettingsUI streamUi;
-
QPointer simpleVodTrack;
QPointer vodTrackCheckbox;
@@ -254,15 +249,21 @@ private:
/* stream */
void InitStreamPage();
+ inline bool IsCustomService() const;
+ void LoadServices(bool showAll);
void OnOAuthStreamKeyConnected();
void OnAuthConnected();
+ QString lastService;
int prevLangIndex;
bool prevBrowserAccel;
private slots:
+ void UpdateServerList();
+ void UpdateKeyLink();
void UpdateVodTrackSetting();
void UpdateServiceRecommendations();
void RecreateOutputResolutionWidget();
void UpdateResFPSLimits();
+ void UpdateMoreInfoLink();
void DisplayEnforceWarning(bool checked);
void on_show_clicked();
void on_authPwShow_clicked();
@@ -391,8 +392,6 @@ private slots:
void UpdateStreamDelayEstimate();
- void UpdateAdvNetworkGroup();
-
void UpdateAutomaticReplayBufferCheckboxes();
void AdvOutSplitFileChanged();