From 0b9a8aa1fdde69c91b32ee083bd6084366b47b16 Mon Sep 17 00:00:00 2001 From: jp9000 Date: Mon, 18 Jul 2022 14:33:40 -0700 Subject: [PATCH] Revert service json lookup refactor in UI Certain services have custom server lits handling which I had forgotten about, so although it would have been nice to have this refactor, we'll have to live with relying on the plugin properties object directly for a while. This also reverts obsproject/obs-studio#6530 and obsproject/obs-studio#6683 because that change depended on this problematic refactor code. This reverts commits: f2e6122881e6b8be3470d5574235afa32a4badc5, bc80d0ca95a3c79cf1f4bc24df437f4ace125e30, 050a29da1a7ad620f05fbd2927786da2f36d85b9, 22ffc04f735830de19a654cd94839504313afb0a, 275e510aad8161bdcd101828f45584a0430ac65e, 2fa5ffe4dfdb50acaa7df4b7f4f80cf1d12cf913. --- UI/CMakeLists.txt | 2 - UI/data/locale/en-US.ini | 1 - UI/forms/AutoConfigStreamPage.ui | 11 +- UI/forms/OBSBasicSettings.ui | 21 +-- UI/streaming-helpers.cpp | 205 ------------------------- UI/streaming-helpers.hpp | 73 --------- UI/window-basic-auto-config-test.cpp | 26 ++-- UI/window-basic-auto-config.cpp | 215 +++++++++++++++++++++++---- UI/window-basic-auto-config.hpp | 14 +- UI/window-basic-settings-stream.cpp | 212 ++++++++++++++++++++++---- UI/window-basic-settings.cpp | 17 --- UI/window-basic-settings.hpp | 13 +- 12 files changed, 411 insertions(+), 399 deletions(-) delete mode 100644 UI/streaming-helpers.cpp delete mode 100644 UI/streaming-helpers.hpp 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();