mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-05-14 02:14:39 -04:00
QT_TO_UTF8 returns a const char * that, in general, shouldn't be stored. This is because QT_TO_UTF8(str) expands to str.toUtf8().constData(): toUtf8() returns a QByteArray, and constData() the pointer to its data which is only valid until the QByteArray goes out of scope, which is immediately after the call. The original code that is changed here only works because in all of the situations, the object that is stored to is actually a std::string that gets constructed implicitly, so the constData() pointer is valid long enough for the std::string constructor to copy the data. The issue is that any "... = QT_TO_UTF8" code *looks* unsafe, and may lead new or unfamiliar contributors to assume that they can also use it, only to do "const char *... = QT_TO_UTF8(...)" which is dangerous. Additionally, it introduces an unnecessary round of implicit conversions and copies when QString.toStdString() already exists and copies into the string buffer directly.
702 lines
22 KiB
C++
702 lines
22 KiB
C++
#include "AutoConfigStreamPage.hpp"
|
|
#include "AutoConfig.hpp"
|
|
#include "ui_AutoConfigStreamPage.h"
|
|
|
|
#include <oauth/OAuth.hpp>
|
|
#include <utility/GoLiveAPI_Network.hpp>
|
|
#include <utility/GoLiveAPI_PostData.hpp>
|
|
#include <utility/MultitrackVideoError.hpp>
|
|
#ifdef YOUTUBE_ENABLED
|
|
#include <utility/YoutubeApiWrappers.hpp>
|
|
#endif
|
|
#include <widgets/OBSBasic.hpp>
|
|
|
|
#include <qt-wrappers.hpp>
|
|
|
|
#include "moc_AutoConfigStreamPage.cpp"
|
|
|
|
enum class ListOpt : int {
|
|
ShowAll = 1,
|
|
Custom,
|
|
};
|
|
|
|
struct QCef;
|
|
extern QCef *cef;
|
|
|
|
#define wiz reinterpret_cast<AutoConfig *>(wizard())
|
|
|
|
AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent) : QWizardPage(parent), ui(new Ui_AutoConfigStreamPage)
|
|
{
|
|
ui->setupUi(this);
|
|
ui->bitrateLabel->setVisible(false);
|
|
ui->bitrate->setVisible(false);
|
|
ui->connectAccount2->setVisible(false);
|
|
ui->disconnectAccount->setVisible(false);
|
|
ui->useMultitrackVideo->setVisible(false);
|
|
|
|
ui->connectedAccountLabel->setVisible(false);
|
|
ui->connectedAccountText->setVisible(false);
|
|
|
|
int vertSpacing = ui->topLayout->verticalSpacing();
|
|
|
|
QMargins m = ui->topLayout->contentsMargins();
|
|
m.setBottom(vertSpacing / 2);
|
|
ui->topLayout->setContentsMargins(m);
|
|
|
|
m = ui->loginPageLayout->contentsMargins();
|
|
m.setTop(vertSpacing / 2);
|
|
ui->loginPageLayout->setContentsMargins(m);
|
|
|
|
m = ui->streamkeyPageLayout->contentsMargins();
|
|
m.setTop(vertSpacing / 2);
|
|
ui->streamkeyPageLayout->setContentsMargins(m);
|
|
|
|
setTitle(QTStr("Basic.AutoConfig.StreamPage"));
|
|
setSubTitle(QTStr("Basic.AutoConfig.StreamPage.SubTitle"));
|
|
|
|
LoadServices(false);
|
|
|
|
connect(ui->service, &QComboBox::currentIndexChanged, this, &AutoConfigStreamPage::ServiceChanged);
|
|
connect(ui->customServer, &QLineEdit::textChanged, this, &AutoConfigStreamPage::ServiceChanged);
|
|
connect(ui->customServer, &QLineEdit::textChanged, this, &AutoConfigStreamPage::UpdateKeyLink);
|
|
connect(ui->customServer, &QLineEdit::editingFinished, this, &AutoConfigStreamPage::UpdateKeyLink);
|
|
connect(ui->doBandwidthTest, &QCheckBox::toggled, this, &AutoConfigStreamPage::ServiceChanged);
|
|
|
|
connect(ui->service, &QComboBox::currentIndexChanged, this, &AutoConfigStreamPage::UpdateServerList);
|
|
|
|
connect(ui->service, &QComboBox::currentIndexChanged, this, &AutoConfigStreamPage::UpdateKeyLink);
|
|
connect(ui->service, &QComboBox::currentIndexChanged, this, &AutoConfigStreamPage::UpdateMoreInfoLink);
|
|
|
|
connect(ui->useStreamKeyAdv, &QPushButton::clicked, this, [&]() {
|
|
ui->streamKeyWidget->setVisible(true);
|
|
ui->streamKeyLabel->setVisible(true);
|
|
ui->useStreamKeyAdv->setVisible(false);
|
|
});
|
|
|
|
connect(ui->key, &QLineEdit::textChanged, this, &AutoConfigStreamPage::UpdateCompleted);
|
|
connect(ui->regionUS, &QCheckBox::toggled, this, &AutoConfigStreamPage::UpdateCompleted);
|
|
connect(ui->regionEU, &QCheckBox::toggled, this, &AutoConfigStreamPage::UpdateCompleted);
|
|
connect(ui->regionAsia, &QCheckBox::toggled, this, &AutoConfigStreamPage::UpdateCompleted);
|
|
connect(ui->regionOther, &QCheckBox::toggled, this, &AutoConfigStreamPage::UpdateCompleted);
|
|
}
|
|
|
|
AutoConfigStreamPage::~AutoConfigStreamPage() {}
|
|
|
|
bool AutoConfigStreamPage::isComplete() const
|
|
{
|
|
return ready;
|
|
}
|
|
|
|
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 = IsCustomService();
|
|
|
|
const char *serverType = wiz->customServer ? "rtmp_custom" : "rtmp_common";
|
|
|
|
if (!wiz->customServer) {
|
|
obs_data_set_string(service_settings, "service", QT_TO_UTF8(ui->service->currentText()));
|
|
}
|
|
|
|
OBSServiceAutoRelease service = obs_service_create(serverType, "temp_service", service_settings, nullptr);
|
|
|
|
int bitrate;
|
|
if (!ui->doBandwidthTest->isChecked()) {
|
|
bitrate = ui->bitrate->value();
|
|
wiz->idealBitrate = bitrate;
|
|
} else {
|
|
/* Default test target is 10 Mbps */
|
|
bitrate = 10000;
|
|
#ifdef YOUTUBE_ENABLED
|
|
if (IsYouTubeService(wiz->serviceName)) {
|
|
/* Adjust upper bound to YouTube limits
|
|
* for resolutions above 1080p */
|
|
if (wiz->baseResolutionCY > 1440)
|
|
bitrate = 51000;
|
|
else if (wiz->baseResolutionCY > 1080)
|
|
bitrate = 18000;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
OBSDataAutoRelease settings = obs_data_create();
|
|
obs_data_set_int(settings, "bitrate", bitrate);
|
|
obs_service_apply_encoder_settings(service, settings, nullptr);
|
|
|
|
if (wiz->customServer) {
|
|
QString server = ui->customServer->text().trimmed();
|
|
const std::string name = server.toStdString();
|
|
wiz->server = name;
|
|
wiz->serverName = name;
|
|
} else {
|
|
wiz->serverName = ui->server->currentText().toStdString();
|
|
wiz->server = ui->server->currentData().toString().toStdString();
|
|
}
|
|
|
|
wiz->bandwidthTest = ui->doBandwidthTest->isChecked();
|
|
wiz->startingBitrate = (int)obs_data_get_int(settings, "bitrate");
|
|
wiz->idealBitrate = wiz->startingBitrate;
|
|
wiz->regionUS = ui->regionUS->isChecked();
|
|
wiz->regionEU = ui->regionEU->isChecked();
|
|
wiz->regionAsia = ui->regionAsia->isChecked();
|
|
wiz->regionOther = ui->regionOther->isChecked();
|
|
wiz->serviceName = ui->service->currentText().toStdString();
|
|
if (ui->preferHardware)
|
|
wiz->preferHardware = ui->preferHardware->isChecked();
|
|
wiz->key = ui->key->text().toStdString();
|
|
|
|
if (!wiz->customServer) {
|
|
if (wiz->serviceName == "Twitch")
|
|
wiz->service = AutoConfig::Service::Twitch;
|
|
#ifdef YOUTUBE_ENABLED
|
|
else if (IsYouTubeService(wiz->serviceName))
|
|
wiz->service = AutoConfig::Service::YouTube;
|
|
#endif
|
|
else if (wiz->serviceName == "Amazon IVS")
|
|
wiz->service = AutoConfig::Service::AmazonIVS;
|
|
else
|
|
wiz->service = AutoConfig::Service::Other;
|
|
} else {
|
|
wiz->service = AutoConfig::Service::Other;
|
|
}
|
|
|
|
if (wiz->service == AutoConfig::Service::Twitch) {
|
|
wiz->testMultitrackVideo = ui->useMultitrackVideo->isChecked();
|
|
|
|
if (wiz->testMultitrackVideo) {
|
|
std::vector<OBSCanvasAutoRelease> canvases;
|
|
canvases.emplace_back(obs_get_main_canvas());
|
|
auto postData = constructGoLivePost(QString::fromStdString(wiz->key), std::nullopt,
|
|
std::nullopt, false, canvases);
|
|
|
|
OBSDataAutoRelease service_settings = obs_service_get_settings(service);
|
|
auto multitrack_video_name = QTStr("Basic.Settings.Stream.MultitrackVideoLabel");
|
|
if (obs_data_has_user_value(service_settings, "multitrack_video_name")) {
|
|
multitrack_video_name = obs_data_get_string(service_settings, "multitrack_video_name");
|
|
}
|
|
|
|
try {
|
|
auto config = DownloadGoLiveConfig(this, MultitrackVideoAutoConfigURL(service),
|
|
postData, multitrack_video_name);
|
|
|
|
for (const auto &endpoint : config.ingest_endpoints) {
|
|
if (qstrnicmp("RTMP", endpoint.protocol.c_str(), 4) != 0)
|
|
continue;
|
|
|
|
std::string address = endpoint.url_template;
|
|
auto pos = address.find("/{stream_key}");
|
|
if (pos != address.npos)
|
|
address.erase(pos);
|
|
|
|
wiz->serviceConfigServers.push_back({address, address});
|
|
}
|
|
|
|
int multitrackVideoBitrate = 0;
|
|
for (auto &encoder_config : config.encoder_configurations) {
|
|
auto it = encoder_config.settings.find("bitrate");
|
|
if (it == encoder_config.settings.end())
|
|
continue;
|
|
|
|
if (!it->is_number_integer())
|
|
continue;
|
|
|
|
int bitrate = 0;
|
|
it->get_to(bitrate);
|
|
multitrackVideoBitrate += bitrate;
|
|
}
|
|
|
|
if (multitrackVideoBitrate > 0) {
|
|
wiz->startingBitrate = multitrackVideoBitrate;
|
|
wiz->idealBitrate = multitrackVideoBitrate;
|
|
wiz->multitrackVideo.targetBitrate = multitrackVideoBitrate;
|
|
wiz->multitrackVideo.testSuccessful = true;
|
|
}
|
|
} catch (const MultitrackVideoError & /*err*/) {
|
|
// FIXME: do something sensible
|
|
}
|
|
}
|
|
}
|
|
|
|
if (wiz->service != AutoConfig::Service::Twitch && wiz->service != AutoConfig::Service::YouTube &&
|
|
wiz->service != AutoConfig::Service::AmazonIVS && wiz->bandwidthTest) {
|
|
QMessageBox::StandardButton button;
|
|
#define WARNING_TEXT(x) QTStr("Basic.AutoConfig.StreamPage.StreamWarning." x)
|
|
button = OBSMessageBox::question(this, WARNING_TEXT("Title"), WARNING_TEXT("Text"));
|
|
#undef WARNING_TEXT
|
|
|
|
if (button == QMessageBox::No)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void AutoConfigStreamPage::on_show_clicked()
|
|
{
|
|
if (ui->key->echoMode() == QLineEdit::Password) {
|
|
ui->key->setEchoMode(QLineEdit::Normal);
|
|
ui->show->setText(QTStr("Hide"));
|
|
} else {
|
|
ui->key->setEchoMode(QLineEdit::Password);
|
|
ui->show->setText(QTStr("Show"));
|
|
}
|
|
}
|
|
|
|
void AutoConfigStreamPage::OnOAuthStreamKeyConnected()
|
|
{
|
|
OAuthStreamKey *a = reinterpret_cast<OAuthStreamKey *>(auth.get());
|
|
|
|
if (a) {
|
|
bool validKey = !a->key().empty();
|
|
|
|
if (validKey)
|
|
ui->key->setText(QT_UTF8(a->key().c_str()));
|
|
|
|
ui->streamKeyWidget->setVisible(false);
|
|
ui->streamKeyLabel->setVisible(false);
|
|
ui->connectAccount2->setVisible(false);
|
|
ui->disconnectAccount->setVisible(true);
|
|
ui->useStreamKeyAdv->setVisible(false);
|
|
|
|
ui->connectedAccountLabel->setVisible(false);
|
|
ui->connectedAccountText->setVisible(false);
|
|
|
|
#ifdef YOUTUBE_ENABLED
|
|
if (IsYouTubeService(a->service())) {
|
|
ui->key->clear();
|
|
|
|
ui->connectedAccountLabel->setVisible(true);
|
|
ui->connectedAccountText->setVisible(true);
|
|
|
|
ui->connectedAccountText->setText(QTStr("Auth.LoadingChannel.Title"));
|
|
|
|
YoutubeApiWrappers *ytAuth = reinterpret_cast<YoutubeApiWrappers *>(a);
|
|
ChannelDescription cd;
|
|
if (ytAuth->GetChannelDescription(cd)) {
|
|
ui->connectedAccountText->setText(cd.title);
|
|
|
|
/* Create throwaway stream key for bandwidth test */
|
|
if (ui->doBandwidthTest->isChecked()) {
|
|
StreamDescription stream = {"", "", "OBS Studio Test Stream"};
|
|
if (ytAuth->InsertStream(stream)) {
|
|
ui->key->setText(stream.name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
ui->stackedWidget->setCurrentIndex((int)Section::StreamKey);
|
|
UpdateCompleted();
|
|
}
|
|
|
|
void AutoConfigStreamPage::OnAuthConnected()
|
|
{
|
|
std::string service = ui->service->currentText().toStdString();
|
|
Auth::Type type = Auth::AuthType(service);
|
|
|
|
if (type == Auth::Type::OAuth_StreamKey || type == Auth::Type::OAuth_LinkedAccount) {
|
|
OnOAuthStreamKeyConnected();
|
|
}
|
|
}
|
|
|
|
void AutoConfigStreamPage::on_connectAccount_clicked()
|
|
{
|
|
std::string service = ui->service->currentText().toStdString();
|
|
|
|
OAuth::DeleteCookies(service);
|
|
|
|
auth = OAuthStreamKey::Login(this, service);
|
|
if (!!auth) {
|
|
OnAuthConnected();
|
|
|
|
ui->useStreamKeyAdv->setVisible(false);
|
|
}
|
|
}
|
|
|
|
#define DISCONNECT_COMFIRM_TITLE "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Title"
|
|
#define DISCONNECT_COMFIRM_TEXT "Basic.AutoConfig.StreamPage.DisconnectAccount.Confirm.Text"
|
|
|
|
void AutoConfigStreamPage::on_disconnectAccount_clicked()
|
|
{
|
|
QMessageBox::StandardButton button;
|
|
|
|
button = OBSMessageBox::question(this, QTStr(DISCONNECT_COMFIRM_TITLE), QTStr(DISCONNECT_COMFIRM_TEXT));
|
|
|
|
if (button == QMessageBox::No) {
|
|
return;
|
|
}
|
|
|
|
OBSBasic *main = OBSBasic::Get();
|
|
|
|
main->auth.reset();
|
|
auth.reset();
|
|
|
|
std::string service = ui->service->currentText().toStdString();
|
|
|
|
#ifdef BROWSER_AVAILABLE
|
|
OAuth::DeleteCookies(service);
|
|
#endif
|
|
|
|
reset_service_ui_fields(service);
|
|
|
|
ui->streamKeyWidget->setVisible(true);
|
|
ui->streamKeyLabel->setVisible(true);
|
|
ui->key->setText("");
|
|
|
|
ui->connectedAccountLabel->setVisible(false);
|
|
ui->connectedAccountText->setVisible(false);
|
|
|
|
/* Restore key link when disconnecting account */
|
|
UpdateKeyLink();
|
|
}
|
|
|
|
void AutoConfigStreamPage::on_useStreamKey_clicked()
|
|
{
|
|
ui->stackedWidget->setCurrentIndex((int)Section::StreamKey);
|
|
UpdateCompleted();
|
|
}
|
|
|
|
void AutoConfigStreamPage::on_preferHardware_clicked()
|
|
{
|
|
auto *main = OBSBasic::Get();
|
|
bool multitrackVideoEnabled = config_has_user_value(main->Config(), "Stream1", "EnableMultitrackVideo")
|
|
? config_get_bool(main->Config(), "Stream1", "EnableMultitrackVideo")
|
|
: true;
|
|
|
|
ui->useMultitrackVideo->setEnabled(ui->preferHardware->isChecked());
|
|
ui->multitrackVideoInfo->setEnabled(ui->preferHardware->isChecked());
|
|
ui->useMultitrackVideo->setChecked(ui->preferHardware->isChecked() && multitrackVideoEnabled);
|
|
}
|
|
|
|
static inline bool is_auth_service(const std::string &service)
|
|
{
|
|
return Auth::AuthType(service) != Auth::Type::None;
|
|
}
|
|
|
|
static inline bool is_external_oauth(const std::string &service)
|
|
{
|
|
return Auth::External(service);
|
|
}
|
|
|
|
void AutoConfigStreamPage::reset_service_ui_fields(std::string &service)
|
|
{
|
|
#ifdef YOUTUBE_ENABLED
|
|
// when account is already connected:
|
|
OAuthStreamKey *a = reinterpret_cast<OAuthStreamKey *>(auth.get());
|
|
if (a && service == a->service() && IsYouTubeService(a->service())) {
|
|
ui->connectedAccountLabel->setVisible(true);
|
|
ui->connectedAccountText->setVisible(true);
|
|
ui->connectAccount2->setVisible(false);
|
|
ui->disconnectAccount->setVisible(true);
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
bool external_oauth = is_external_oauth(service);
|
|
if (external_oauth) {
|
|
ui->streamKeyWidget->setVisible(false);
|
|
ui->streamKeyLabel->setVisible(false);
|
|
ui->connectAccount2->setVisible(true);
|
|
ui->useStreamKeyAdv->setVisible(true);
|
|
|
|
ui->stackedWidget->setCurrentIndex((int)Section::StreamKey);
|
|
|
|
} else if (cef) {
|
|
QString key = ui->key->text();
|
|
bool can_auth = is_auth_service(service);
|
|
int page = can_auth && key.isEmpty() ? (int)Section::Connect : (int)Section::StreamKey;
|
|
|
|
ui->stackedWidget->setCurrentIndex(page);
|
|
ui->streamKeyWidget->setVisible(true);
|
|
ui->streamKeyLabel->setVisible(true);
|
|
ui->connectAccount2->setVisible(can_auth);
|
|
ui->useStreamKeyAdv->setVisible(false);
|
|
} else {
|
|
ui->connectAccount2->setVisible(false);
|
|
ui->useStreamKeyAdv->setVisible(false);
|
|
}
|
|
|
|
ui->connectedAccountLabel->setVisible(false);
|
|
ui->connectedAccountText->setVisible(false);
|
|
ui->disconnectAccount->setVisible(false);
|
|
}
|
|
|
|
void AutoConfigStreamPage::ServiceChanged()
|
|
{
|
|
bool showMore = ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
|
|
if (showMore)
|
|
return;
|
|
|
|
std::string service = ui->service->currentText().toStdString();
|
|
bool regionBased = service == "Twitch";
|
|
bool testBandwidth = ui->doBandwidthTest->isChecked();
|
|
bool custom = IsCustomService();
|
|
|
|
bool ertmp_multitrack_video_available = service == "Twitch";
|
|
|
|
bool custom_disclaimer = false;
|
|
auto multitrack_video_name = QTStr("Basic.Settings.Stream.MultitrackVideoLabel");
|
|
if (!custom) {
|
|
OBSDataAutoRelease service_settings = obs_data_create();
|
|
obs_data_set_string(service_settings, "service", service.c_str());
|
|
OBSServiceAutoRelease obs_service =
|
|
obs_service_create("rtmp_common", "temp service", service_settings, nullptr);
|
|
|
|
if (obs_data_has_user_value(service_settings, "multitrack_video_name")) {
|
|
multitrack_video_name = obs_data_get_string(service_settings, "multitrack_video_name");
|
|
}
|
|
|
|
if (obs_data_has_user_value(service_settings, "multitrack_video_disclaimer")) {
|
|
ui->multitrackVideoInfo->setText(
|
|
obs_data_get_string(service_settings, "multitrack_video_disclaimer"));
|
|
custom_disclaimer = true;
|
|
}
|
|
}
|
|
|
|
if (!custom_disclaimer) {
|
|
ui->multitrackVideoInfo->setText(
|
|
QTStr("MultitrackVideo.Info").arg(multitrack_video_name, service.c_str()));
|
|
}
|
|
|
|
ui->multitrackVideoInfo->setVisible(ertmp_multitrack_video_available);
|
|
ui->useMultitrackVideo->setVisible(ertmp_multitrack_video_available);
|
|
ui->useMultitrackVideo->setText(
|
|
QTStr("Basic.AutoConfig.StreamPage.UseMultitrackVideo").arg(multitrack_video_name));
|
|
ui->multitrackVideoInfo->setEnabled(wiz->hardwareEncodingAvailable);
|
|
ui->useMultitrackVideo->setEnabled(wiz->hardwareEncodingAvailable);
|
|
|
|
reset_service_ui_fields(service);
|
|
|
|
/* Test three closest servers if "Auto" is available for Twitch */
|
|
if ((service == "Twitch" && wiz->twitchAuto) || (service == "Amazon IVS" && wiz->amazonIVSAuto))
|
|
regionBased = false;
|
|
|
|
ui->streamkeyPageLayout->removeWidget(ui->serverLabel);
|
|
ui->streamkeyPageLayout->removeWidget(ui->serverStackedWidget);
|
|
|
|
if (custom) {
|
|
ui->streamkeyPageLayout->insertRow(1, ui->serverLabel, ui->serverStackedWidget);
|
|
|
|
ui->region->setVisible(false);
|
|
ui->serverStackedWidget->setCurrentIndex(1);
|
|
ui->serverStackedWidget->setVisible(true);
|
|
ui->serverLabel->setVisible(true);
|
|
} else {
|
|
if (!testBandwidth)
|
|
ui->streamkeyPageLayout->insertRow(2, ui->serverLabel, ui->serverStackedWidget);
|
|
|
|
ui->region->setVisible(regionBased && testBandwidth);
|
|
ui->serverStackedWidget->setCurrentIndex(0);
|
|
ui->serverStackedWidget->setHidden(testBandwidth);
|
|
ui->serverLabel->setHidden(testBandwidth);
|
|
}
|
|
|
|
wiz->testRegions = regionBased && testBandwidth;
|
|
|
|
ui->bitrateLabel->setHidden(testBandwidth);
|
|
ui->bitrate->setHidden(testBandwidth);
|
|
|
|
OBSBasic *main = OBSBasic::Get();
|
|
|
|
if (main->auth) {
|
|
auto system_auth_service = main->auth->service();
|
|
bool service_check = service.find(system_auth_service) != std::string::npos;
|
|
#ifdef YOUTUBE_ENABLED
|
|
service_check = service_check ? service_check
|
|
: IsYouTubeService(system_auth_service) && IsYouTubeService(service);
|
|
#endif
|
|
if (service_check) {
|
|
auth.reset();
|
|
auth = main->auth;
|
|
OnAuthConnected();
|
|
}
|
|
}
|
|
|
|
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"));
|
|
ui->streamKeyLabel->setToolTip("");
|
|
} else if (!IsCustomService()) {
|
|
ui->streamKeyLabel->setText(QTStr("Basic.AutoConfig.StreamPage.StreamKey"));
|
|
ui->streamKeyLabel->setToolTip("");
|
|
} else {
|
|
/* add tooltips for stream key */
|
|
QString file = !App()->IsThemeDark() ? ":/res/images/help.svg" : ":/res/images/help_light.svg";
|
|
QString lStr = "<html>%1 <img src='%2' style=' \
|
|
vertical-align: bottom; \
|
|
' /></html>";
|
|
|
|
ui->streamKeyLabel->setText(lStr.arg(QTStr("Basic.AutoConfig.StreamPage.StreamKey"), file));
|
|
ui->streamKeyLabel->setToolTip(QTStr("Basic.AutoConfig.StreamPage.StreamKey.ToolTip"));
|
|
}
|
|
|
|
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()
|
|
{
|
|
const bool custom = IsCustomService();
|
|
if (ui->stackedWidget->currentIndex() == (int)Section::Connect ||
|
|
(ui->key->text().isEmpty() && !auth && !custom)) {
|
|
ready = false;
|
|
} else {
|
|
if (custom) {
|
|
ready = !ui->customServer->text().isEmpty();
|
|
} else {
|
|
ready = !wiz->testRegions || ui->regionUS->isChecked() || ui->regionEU->isChecked() ||
|
|
ui->regionAsia->isChecked() || ui->regionOther->isChecked();
|
|
}
|
|
}
|
|
emit completeChanged();
|
|
}
|