1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#include "goliveapi-network.hpp"
#include "goliveapi-censoredjson.hpp"
#include <obs.hpp>
#include <obs-app.hpp>
#include <remote-text.hpp>
#include "multitrack-video-error.hpp"
#include <qstring.h>
#include <string>
#include <QMessageBox>
#include <QThreadPool>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
Qt::ConnectionType BlockingConnectionTypeFor(QObject *object);
void HandleGoLiveApiErrors(QWidget *parent, const json &raw_json,
const GoLiveApi::Config &config)
{
using GoLiveApi::StatusResult;
if (!config.status)
return;
auto &status = *config.status;
if (status.result == StatusResult::Success)
return;
auto warn_continue = [&](QString message) {
bool ret = false;
QMetaObject::invokeMethod(
parent,
[=] {
QMessageBox mb(parent);
mb.setIcon(QMessageBox::Warning);
mb.setWindowTitle(QTStr(
"ConfigDownload.WarningMessageTitle"));
mb.setTextFormat(Qt::RichText);
mb.setText(
message +
QTStr("FailedToStartStream.WarningRetry"));
mb.setStandardButtons(
QMessageBox::StandardButton::Yes |
QMessageBox::StandardButton::No);
return mb.exec() ==
QMessageBox::StandardButton::No;
},
BlockingConnectionTypeFor(parent), &ret);
if (ret)
throw MultitrackVideoError::cancel();
};
auto missing_html = [] {
return QTStr("FailedToStartStream.StatusMissingHTML")
.toStdString();
};
if (status.result == StatusResult::Unknown) {
return warn_continue(
QTStr("FailedToStartStream.WarningUnknownStatus")
.arg(raw_json["status"]["result"]
.dump()
.c_str()));
} else if (status.result == StatusResult::Warning) {
if (config.encoder_configurations.empty()) {
throw MultitrackVideoError::warning(
status.html_en_us.value_or(missing_html())
.c_str());
}
return warn_continue(
status.html_en_us.value_or(missing_html()).c_str());
} else if (status.result == StatusResult::Error) {
throw MultitrackVideoError::critical(
status.html_en_us.value_or(missing_html()).c_str());
}
}
GoLiveApi::Config DownloadGoLiveConfig(QWidget *parent, QString url,
const GoLiveApi::PostData &post_data,
const QString &multitrack_video_name)
{
json post_data_json = post_data;
blog(LOG_INFO, "Go live POST data: %s",
censoredJson(post_data_json).toUtf8().constData());
if (url.isEmpty())
throw MultitrackVideoError::critical(
QTStr("FailedToStartStream.MissingConfigURL"));
std::string encodeConfigText;
std::string libraryError;
std::vector<std::string> headers;
headers.push_back("Content-Type: application/json");
bool encodeConfigDownloadedOk = GetRemoteFile(
url.toLocal8Bit(), encodeConfigText,
libraryError, // out params
nullptr,
nullptr, // out params (response code and content type)
"POST", post_data_json.dump().c_str(), headers,
nullptr, // signature
5); // timeout in seconds
if (!encodeConfigDownloadedOk)
throw MultitrackVideoError::warning(
QTStr("FailedToStartStream.ConfigRequestFailed")
.arg(url, libraryError.c_str()));
try {
auto data = json::parse(encodeConfigText);
blog(LOG_INFO, "Go live response data: %s",
censoredJson(data, true).toUtf8().constData());
GoLiveApi::Config config = data;
HandleGoLiveApiErrors(parent, data, config);
return config;
} catch (const json::exception &e) {
blog(LOG_INFO, "Failed to parse go live config: %s", e.what());
throw MultitrackVideoError::warning(
QTStr("FailedToStartStream.FallbackToDefault")
.arg(multitrack_video_name));
}
}
QString MultitrackVideoAutoConfigURL(obs_service_t *service)
{
static const std::optional<QString> cli_url =
[]() -> std::optional<QString> {
auto args = qApp->arguments();
for (int i = 0; i < args.length() - 1; i++) {
if (args[i] == "--config-url" &&
args.length() > (i + 1)) {
return args[i + 1];
}
}
return std::nullopt;
}();
QString url;
if (cli_url.has_value()) {
url = *cli_url;
} else {
OBSDataAutoRelease settings = obs_service_get_settings(service);
url = obs_data_get_string(settings,
"multitrack_video_configuration_url");
}
blog(LOG_INFO, "Go live URL: %s", url.toUtf8().constData());
return url;
}
|