From dfa12f980731100a6da67633bf9d71254be9e4f2 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Wed, 24 May 2023 20:26:51 +0200 Subject: [PATCH] Add support for configuring additional streaming options * Set server * Set stream key * Set username * Set password --- data/locale/de-DE.ini | 2 +- data/locale/en-US.ini | 6 +- data/locale/es-ES.ini | 2 +- data/locale/ru-RU.ini | 2 +- data/locale/tr-TR.ini | 2 +- data/locale/zh-CN.ini | 2 +- src/macro-core/macro-action-streaming.cpp | 136 +++++++++++++++++++--- src/macro-core/macro-action-streaming.hpp | 15 ++- 8 files changed, 147 insertions(+), 20 deletions(-) diff --git a/data/locale/de-DE.ini b/data/locale/de-DE.ini index 170d7ce0..164557b0 100644 --- a/data/locale/de-DE.ini +++ b/data/locale/de-DE.ini @@ -438,7 +438,7 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}" AdvSceneSwitcher.action.streaming="Stream" AdvSceneSwitcher.action.streaming.type.stop="Stream stoppen" AdvSceneSwitcher.action.streaming.type.start="Stream starten" -AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}" +AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}" AdvSceneSwitcher.action.run="Ausführen" AdvSceneSwitcher.action.run.arguments="Argumente:" AdvSceneSwitcher.action.run.addArgument="Argument hinzufügen" diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index a29adf2f..cab6e5e2 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -494,7 +494,11 @@ AdvSceneSwitcher.action.streaming="Streaming" AdvSceneSwitcher.action.streaming.type.stop="Stop streaming" AdvSceneSwitcher.action.streaming.type.start="Start streaming" AdvSceneSwitcher.action.streaming.type.keyFrameInterval="Set keyframe interval" -AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}" +AdvSceneSwitcher.action.streaming.type.server="Set server URL" +AdvSceneSwitcher.action.streaming.type.streamKey="Set stream key" +AdvSceneSwitcher.action.streaming.type.username="Set username" +AdvSceneSwitcher.action.streaming.type.password="Set password" +AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}" AdvSceneSwitcher.action.run="Run" AdvSceneSwitcher.action.sceneVisibility="Scene item visibility" AdvSceneSwitcher.action.sceneVisibility.type.show="Show" diff --git a/data/locale/es-ES.ini b/data/locale/es-ES.ini index 6dbed907..071b1b50 100644 --- a/data/locale/es-ES.ini +++ b/data/locale/es-ES.ini @@ -360,7 +360,7 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}" AdvSceneSwitcher.action.streaming="Transmisión" AdvSceneSwitcher.action.streaming.type.stop="Detener transmisión" AdvSceneSwitcher.action.streaming.type.start="Iniciar transmisión" -AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}" +AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}" AdvSceneSwitcher.action.run="Ejecutar" AdvSceneSwitcher.action.run.arguments="Argumentos:" AdvSceneSwitcher.action.run.addArgument="Agregar argumento" diff --git a/data/locale/ru-RU.ini b/data/locale/ru-RU.ini index e570fc8b..1a54c13f 100644 --- a/data/locale/ru-RU.ini +++ b/data/locale/ru-RU.ini @@ -144,7 +144,7 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}" AdvSceneSwitcher.action.streaming="Потоковое вещание" AdvSceneSwitcher.action.streaming.type.stop="Остановить потоковое вещание" AdvSceneSwitcher.action.streaming.type.start="Начать потоковое вещание" -AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}" +AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}" AdvSceneSwitcher.action.run="Запустить" diff --git a/data/locale/tr-TR.ini b/data/locale/tr-TR.ini index 9383c83d..29207e7f 100644 --- a/data/locale/tr-TR.ini +++ b/data/locale/tr-TR.ini @@ -290,7 +290,7 @@ AdvSceneSwitcher.action.replay.entry="{{actions}}" AdvSceneSwitcher.action.streaming="Yayın" AdvSceneSwitcher.action.streaming.type.stop="Yayın durdur" AdvSceneSwitcher.action.streaming.type.start="Yayın başlat" -AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}" +AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}" AdvSceneSwitcher.action.run="Çalıştır" AdvSceneSwitcher.action.run.arguments="Argümanlar:" AdvSceneSwitcher.action.run.addArgument="Argüman ekle" diff --git a/data/locale/zh-CN.ini b/data/locale/zh-CN.ini index feb8f460..4f477cb9 100644 --- a/data/locale/zh-CN.ini +++ b/data/locale/zh-CN.ini @@ -494,7 +494,7 @@ AdvSceneSwitcher.action.streaming="推流" AdvSceneSwitcher.action.streaming.type.stop="停止推流" AdvSceneSwitcher.action.streaming.type.start="开始推流" AdvSceneSwitcher.action.streaming.type.keyFrameInterval="设置关键帧间隔" -AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}" +AdvSceneSwitcher.action.streaming.entry="{{actions}}{{keyFrameInterval}}{{stringValue}}{{showPassword}}" AdvSceneSwitcher.action.run="运行" AdvSceneSwitcher.action.sceneVisibility="场景项目可见性" AdvSceneSwitcher.action.sceneVisibility.type.show="显示" diff --git a/src/macro-core/macro-action-streaming.cpp b/src/macro-core/macro-action-streaming.cpp index cd379586..55702fde 100644 --- a/src/macro-core/macro-action-streaming.cpp +++ b/src/macro-core/macro-action-streaming.cpp @@ -19,6 +19,14 @@ const static std::map actionTypes = { "AdvSceneSwitcher.action.streaming.type.start"}, {MacroActionStream::Action::KEYFRAME_INTERVAL, "AdvSceneSwitcher.action.streaming.type.keyFrameInterval"}, + {MacroActionStream::Action::SERVER, + "AdvSceneSwitcher.action.streaming.type.server"}, + {MacroActionStream::Action::STREAM_KEY, + "AdvSceneSwitcher.action.streaming.type.streamKey"}, + {MacroActionStream::Action::USERNAME, + "AdvSceneSwitcher.action.streaming.type.username"}, + {MacroActionStream::Action::PASSWORD, + "AdvSceneSwitcher.action.streaming.type.password"}, }; constexpr int streamStartCooldown = 5; @@ -28,14 +36,45 @@ std::chrono::high_resolution_clock::time_point MacroActionStream::s_lastAttempt void MacroActionStream::SetKeyFrameInterval() { const auto configPath = GetPathInProfileDir("streamEncoder.json"); - obs_data_t *settings = + auto settings = obs_data_create_from_json_file_safe(configPath.c_str(), "bak"); - obs_data_set_int(settings, "keyint_sec", _keyFrameInterval); - if (settings) { - obs_data_save_json_safe(settings, configPath.c_str(), "tmp", - "bak"); - obs_data_release(settings); + if (!settings) { + blog(LOG_WARNING, "failed to set key frame interval"); + return; } + obs_data_set_int(settings, "keyint_sec", _keyFrameInterval); + obs_data_save_json_safe(settings, configPath.c_str(), "tmp", "bak"); + obs_data_release(settings); +} + +void MacroActionStream::SetStreamSettingsValue(const char *name, + const std::string &value, + bool enableAuth) +{ + const auto configPath = GetPathInProfileDir("service.json"); + auto data = + obs_data_create_from_json_file_safe(configPath.c_str(), "bak"); + if (!data) { + blog(LOG_WARNING, "failed to set %s", name); + return; + } + auto settings = obs_data_get_obj(data, "settings"); + if (!settings) { + blog(LOG_WARNING, "failed to set %s", name); + obs_data_release(data); + return; + } + obs_data_set_string(settings, name, value.c_str()); + if (enableAuth) { + obs_data_set_bool(settings, "use_auth", true); + } + obs_data_set_obj(data, "settings", settings); + auto service = obs_frontend_get_streaming_service(); + obs_service_update(service, settings); + obs_frontend_save_streaming_service(); + obs_frontend_set_streaming_service(service); + obs_data_release(settings); + obs_data_release(data); } bool MacroActionStream::CooldownDurationReached() @@ -64,6 +103,18 @@ bool MacroActionStream::PerformAction() case Action::KEYFRAME_INTERVAL: SetKeyFrameInterval(); break; + case Action::SERVER: + SetStreamSettingsValue("server", _stringValue); + break; + case Action::STREAM_KEY: + SetStreamSettingsValue("key", _stringValue); + break; + case Action::USERNAME: + SetStreamSettingsValue("username", _stringValue, true); + break; + case Action::PASSWORD: + SetStreamSettingsValue("password", _stringValue, true); + break; default: break; } @@ -86,6 +137,7 @@ bool MacroActionStream::Save(obs_data_t *obj) const MacroAction::Save(obj); obs_data_set_int(obj, "action", static_cast(_action)); _keyFrameInterval.Save(obj, "keyFrameInterval"); + _stringValue.Save(obj, "stringValue"); return true; } @@ -94,6 +146,7 @@ bool MacroActionStream::Load(obs_data_t *obj) MacroAction::Load(obj); _action = static_cast(obs_data_get_int(obj, "action")); _keyFrameInterval.Load(obj, "keyFrameInterval"); + _stringValue.Load(obj, "stringValue"); return true; } @@ -108,11 +161,18 @@ MacroActionStreamEdit::MacroActionStreamEdit( QWidget *parent, std::shared_ptr entryData) : QWidget(parent), _actions(new QComboBox()), - _keyFrameInterval(new VariableSpinBox()) + _keyFrameInterval(new VariableSpinBox()), + _stringValue(new VariableLineEdit(this)), + _showPassword(new QPushButton()) { _keyFrameInterval->setMinimum(0); _keyFrameInterval->setMaximum(25); + _showPassword->setMaximumWidth(22); + _showPassword->setFlat(true); + _showPassword->setStyleSheet( + "QPushButton { background-color: transparent; border: 0px }"); + populateActionSelection(_actions); QWidget::connect(_actions, SIGNAL(currentIndexChanged(int)), this, @@ -122,12 +182,21 @@ MacroActionStreamEdit::MacroActionStreamEdit( SIGNAL(NumberVariableChanged(const NumberVariable &)), this, SLOT(KeyFrameIntervalChanged(const NumberVariable &))); + QWidget::connect(_stringValue, SIGNAL(editingFinished()), this, + SLOT(StringValueChanged())); + QWidget::connect(_showPassword, SIGNAL(pressed()), this, + SLOT(ShowPassword())); + QWidget::connect(_showPassword, SIGNAL(released()), this, + SLOT(HidePassword())); QHBoxLayout *mainLayout = new QHBoxLayout; PlaceWidgets(obs_module_text("AdvSceneSwitcher.action.streaming.entry"), mainLayout, {{"{{actions}}", _actions}, - {"{{keyFrameInterval}}", _keyFrameInterval}}); + {"{{keyFrameInterval}}", _keyFrameInterval}, + {"{{stringValue}}", _stringValue}, + {"{{showPassword}}", _showPassword}}, + false); setLayout(mainLayout); _entryData = entryData; @@ -142,6 +211,7 @@ void MacroActionStreamEdit::UpdateEntryData() } _actions->setCurrentIndex(static_cast(_entryData->_action)); _keyFrameInterval->SetValue(_entryData->_keyFrameInterval); + _stringValue->setText(_entryData->_stringValue); SetWidgetVisiblity(); } @@ -156,15 +226,52 @@ void MacroActionStreamEdit::KeyFrameIntervalChanged( _entryData->_keyFrameInterval = value; } +void MacroActionStreamEdit::StringValueChanged() +{ + if (_loading || !_entryData) { + return; + } + + auto lock = LockContext(); + _entryData->_stringValue = _stringValue->text().toStdString(); + SetWidgetVisiblity(); +} + +void MacroActionStreamEdit::ShowPassword() +{ + SetButtonIcon(_showPassword, ":res/images/visible.svg"); + _stringValue->setEchoMode(QLineEdit::Normal); +} + +void MacroActionStreamEdit::HidePassword() +{ + SetButtonIcon(_showPassword, ":res/images/invisible.svg"); + _stringValue->setEchoMode(QLineEdit::PasswordEchoOnEdit); +} + void MacroActionStreamEdit::SetWidgetVisiblity() { if (!_entryData) { return; } + const auto action = _entryData->_action; _keyFrameInterval->setVisible( - _entryData->_action == - MacroActionStream::Action::KEYFRAME_INTERVAL); + action == MacroActionStream::Action::KEYFRAME_INTERVAL); + _stringValue->setVisible( + action == MacroActionStream::Action::SERVER || + action == MacroActionStream::Action::STREAM_KEY || + action == MacroActionStream::Action::USERNAME || + action == MacroActionStream::Action::PASSWORD); + if (action == MacroActionStream::Action::PASSWORD || + action == MacroActionStream::Action::STREAM_KEY) { + _stringValue->setEchoMode(QLineEdit::PasswordEchoOnEdit); + _showPassword->show(); + HidePassword(); + } else { + _stringValue->setEchoMode(QLineEdit::Normal); + _showPassword->hide(); + } } void MacroActionStreamEdit::ActionChanged(int value) @@ -172,9 +279,12 @@ void MacroActionStreamEdit::ActionChanged(int value) if (_loading || !_entryData) { return; } - - auto lock = LockContext(); - _entryData->_action = static_cast(value); + { + auto lock = LockContext(); + _entryData->_action = + static_cast(value); + } + _stringValue->setText(QString("")); SetWidgetVisiblity(); } diff --git a/src/macro-core/macro-action-streaming.hpp b/src/macro-core/macro-action-streaming.hpp index d299d8ed..93f7eab4 100644 --- a/src/macro-core/macro-action-streaming.hpp +++ b/src/macro-core/macro-action-streaming.hpp @@ -1,6 +1,7 @@ #pragma once #include "macro-action-edit.hpp" #include "variable-spinbox.hpp" +#include "variable-line-edit.hpp" #include #include @@ -26,12 +27,19 @@ public: STOP, START, KEYFRAME_INTERVAL, + SERVER, + STREAM_KEY, + USERNAME, + PASSWORD, }; Action _action = Action::STOP; - NumberVariable _keyFrameInterval = 0; + IntVariable _keyFrameInterval = 0; + StringVariable _stringValue; private: void SetKeyFrameInterval(); + void SetStreamSettingsValue(const char *name, const std::string &value, + bool enableAuth = false); bool CooldownDurationReached(); static std::chrono::high_resolution_clock::time_point s_lastAttempt; @@ -58,10 +66,15 @@ public: private slots: void ActionChanged(int value); void KeyFrameIntervalChanged(const NumberVariable &); + void StringValueChanged(); + void ShowPassword(); + void HidePassword(); protected: QComboBox *_actions; VariableSpinBox *_keyFrameInterval; + VariableLineEdit *_stringValue; + QPushButton *_showPassword; std::shared_ptr _entryData; private: