mirror of
https://github.com/obsproject/obs-studio.git
synced 2026-09-24 23:31:36 +08:00
UI: Add eRTMP Multitrack Video Output
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
#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 QString url = [service]() -> 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];
|
||||
}
|
||||
}
|
||||
OBSDataAutoRelease settings = obs_service_get_settings(service);
|
||||
return obs_data_get_string(
|
||||
settings, "multitrack_video_configuration_url");
|
||||
}();
|
||||
|
||||
blog(LOG_INFO, "Go live URL: %s", url.toUtf8().constData());
|
||||
return url;
|
||||
}
|
||||
Reference in New Issue
Block a user