Add option to assign screenshot to variable

This commit is contained in:
WarmUpTill 2024-09-29 12:40:40 +02:00 committed by WarmUpTill
parent f863909f34
commit 72b2a7a07a
9 changed files with 94 additions and 60 deletions

View File

@ -529,7 +529,7 @@ AdvSceneSwitcher.action.screenshot.type.source="Quelle"
AdvSceneSwitcher.action.screenshot.type.scene="Szene"
AdvSceneSwitcher.action.screenshot.mainOutput="OBS's Haupt-Ausgabe"
AdvSceneSwitcher.action.screenshot.blackscreenNote="Quellen oder Szenen, die nicht immer gerendert werden, können dazu führen, dass einige Teile der Screenshots leer bleiben."
AdvSceneSwitcher.action.screenshot.entry="Screenshot{{targetType}}{{sources}}{{scenes}}und speichere in{{saveType}}Pfad"
AdvSceneSwitcher.action.screenshot.entry="Screenshot{{targetType}}{{sources}}{{scenes}}und speichere in{{saveType}}{{variables}}Pfad"
AdvSceneSwitcher.action.profile="Profil"
AdvSceneSwitcher.action.profile.entry="Aktives Profil umschalten auf {{profiles}}"
AdvSceneSwitcher.action.sceneCollection="Szenensammlung"

View File

@ -1002,13 +1002,14 @@ AdvSceneSwitcher.action.systray.icon="Icon:"
AdvSceneSwitcher.action.systray.iconHint="Leave blank to use the default icon"
AdvSceneSwitcher.action.systray.disabled="System tray notifications seem to be disabled in the OBS settings!"
AdvSceneSwitcher.action.screenshot="Screenshot"
AdvSceneSwitcher.action.screenshot.save.default="Default"
AdvSceneSwitcher.action.screenshot.save.custom="Custom"
AdvSceneSwitcher.action.screenshot.save.default="Default OBS path"
AdvSceneSwitcher.action.screenshot.save.custom="Custom file path"
AdvSceneSwitcher.action.screenshot.save.variable="Variable (base64 encoded PNG)"
AdvSceneSwitcher.action.screenshot.type.source="Source"
AdvSceneSwitcher.action.screenshot.type.scene="Scene"
AdvSceneSwitcher.action.screenshot.mainOutput="OBS's main output"
AdvSceneSwitcher.action.screenshot.blackscreenNote="Sources or scenes, which are not always rendered, may result in some parts of screenshots to remain blank."
AdvSceneSwitcher.action.screenshot.entry="Screenshot{{targetType}}{{sources}}{{scenes}}and save to{{saveType}}location"
AdvSceneSwitcher.action.screenshot.entry="Screenshot{{targetType}}{{sources}}{{scenes}}and save to{{saveType}}{{variables}}"
AdvSceneSwitcher.action.profile="Profile"
AdvSceneSwitcher.action.profile.entry="Switch active profile to{{profiles}}"
AdvSceneSwitcher.action.sceneCollection="Scene collection"

View File

@ -649,7 +649,7 @@ AdvSceneSwitcher.action.screenshot.type.source="Source"
AdvSceneSwitcher.action.screenshot.type.scene="Scène"
AdvSceneSwitcher.action.screenshot.mainOutput="Sortie principale d'OBS"
AdvSceneSwitcher.action.screenshot.blackscreenNote="Les sources ou les scènes qui ne sont pas toujours rendues peuvent entraîner des parties de captures d'écran vides."
AdvSceneSwitcher.action.screenshot.entry="Capturer{{targetType}}{{sources}}{{scenes}}et enregistrer à l'emplacement{{saveType}}"
AdvSceneSwitcher.action.screenshot.entry="Capturer{{targetType}}{{sources}}{{scenes}}et enregistrer à l'emplacement{{saveType}}{{variables}}"
AdvSceneSwitcher.action.profile="Profil"
AdvSceneSwitcher.action.profile.entry="Changer le profil actif vers{{profiles}}"
AdvSceneSwitcher.action.sceneCollection="Collection de scènes"

View File

@ -981,7 +981,7 @@ AdvSceneSwitcher.action.screenshot.save.custom="カスタム"
AdvSceneSwitcher.action.screenshot.type.scene="シーン"
AdvSceneSwitcher.action.screenshot.mainOutput="OBSの主な出力"
AdvSceneSwitcher.action.screenshot.blackscreenNote="常にレンダリングされるわけではないソースやシーンにより、スクリーンショットの一部が空白のままになる場合があります。"
AdvSceneSwitcher.action.screenshot.entry="スクリーンショット{{targetType}}{{sources}}{{scenes}}を作成し、{{saveType}}の場所に保存します"
AdvSceneSwitcher.action.screenshot.entry="スクリーンショット{{targetType}}{{sources}}{{scenes}}を作成し、{{saveType}}{{variables}}の場所に保存します"
AdvSceneSwitcher.action.profile="プロファイル"
AdvSceneSwitcher.action.profile.entry="アクティブなプロファイルを{{profiles}}に切り替えます"
; AdvSceneSwitcher.action.sceneCollection="Scene collection"

View File

@ -963,7 +963,7 @@ AdvSceneSwitcher.action.screenshot.type.source="Fonte"
AdvSceneSwitcher.action.screenshot.type.scene="Cena"
AdvSceneSwitcher.action.screenshot.mainOutput="Saída principal do OBS"
AdvSceneSwitcher.action.screenshot.blackscreenNote="Fontes ou cenas, que nem sempre são renderizadas, podem resultar em algumas partes das capturas de tela permanecendo em branco."
AdvSceneSwitcher.action.screenshot.entry="Captura de tela{{targetType}}{{sources}}{{scenes}}e salvar em{{saveType}}localização"
AdvSceneSwitcher.action.screenshot.entry="Captura de tela{{targetType}}{{sources}}{{scenes}}e salvar em{{saveType}}{{variables}}localização"
AdvSceneSwitcher.action.profile="Perfil"
AdvSceneSwitcher.action.profile.entry="Mudar perfil ativo para{{profiles}}"
AdvSceneSwitcher.action.sceneCollection="Coleção de cenas"

View File

@ -590,7 +590,7 @@ AdvSceneSwitcher.action.screenshot.type.source="来源"
AdvSceneSwitcher.action.screenshot.type.scene="场景"
AdvSceneSwitcher.action.screenshot.mainOutput="OBS 预览画面"
AdvSceneSwitcher.action.screenshot.blackscreenNote="源和场景并不总是呈现,可能会导致屏幕截图的某些部分保持空白。"
AdvSceneSwitcher.action.screenshot.entry="截图{{targetType}}{{sources}}{{scenes}}保存在{{saveType}}位置"
AdvSceneSwitcher.action.screenshot.entry="截图{{targetType}}{{sources}}{{scenes}}保存在{{saveType}}{{variables}}位置"
AdvSceneSwitcher.action.profile="配置文件"
AdvSceneSwitcher.action.profile.entry="将活动配置文件切换到 {{profiles}}"
AdvSceneSwitcher.action.sceneCollection="场景集合"

View File

@ -36,7 +36,7 @@ public:
EXPORT std::optional<int> IntValue() const;
std::string GetPreviousValue() const { return _previousValue; };
std::string GetDefaultValue() const { return _defaultValue; }
void SetValue(const std::string &value);
EXPORT void SetValue(const std::string &value);
void SetValue(double value);
SaveAction GetSaveAction() const { return _saveAction; }
int GetValueChangeCount() const { return _valueChangeCount; }
@ -112,7 +112,7 @@ EXPORT Variable *GetVariableByName(const std::string &name);
EXPORT Variable *GetVariableByQString(const QString &name);
EXPORT std::weak_ptr<Variable> GetWeakVariableByName(const std::string &name);
EXPORT std::weak_ptr<Variable> GetWeakVariableByQString(const QString &name);
std::string GetWeakVariableName(std::weak_ptr<Variable>);
EXPORT std::string GetWeakVariableName(std::weak_ptr<Variable>);
EXPORT QStringList GetVariablesNameList();
void SaveVariables(obs_data_t *obj);

View File

@ -3,6 +3,8 @@
#include "selection-helpers.hpp"
#include <obs-frontend-api.h>
#include <QBuffer>
#include <QByteArray>
namespace advss {
@ -13,28 +15,49 @@ bool MacroActionScreenshot::_registered = MacroActionFactory::Register(
{MacroActionScreenshot::Create, MacroActionScreenshotEdit::Create,
"AdvSceneSwitcher.action.screenshot"});
void MacroActionScreenshot::FrontendScreenshot(OBSWeakSource &source)
void MacroActionScreenshot::FrontendScreenshot(OBSWeakSource &source) const
{
#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(26, 0, 0)
if (source) {
auto s = obs_weak_source_get_source(source);
auto s = OBSGetStrongRef(source);
obs_frontend_take_source_screenshot(s);
obs_source_release(s);
} else {
obs_frontend_take_screenshot();
}
#endif
}
void MacroActionScreenshot::CustomScreenshot(OBSWeakSource &source)
void MacroActionScreenshot::CustomScreenshot(OBSWeakSource &source) const
{
if (!source && _targetType == TargetType::SCENE) {
return;
}
auto s = obs_weak_source_get_source(source);
_screenshot.~Screenshot();
new (&_screenshot) Screenshot(s, QRect(), false, 0, true, _path);
obs_source_release(s);
auto s = OBSGetStrongRef(source);
Screenshot screenshot(s, QRect(), true, 3000, true, _path);
}
void MacroActionScreenshot::VariableScreenshot(OBSWeakSource &source) const
{
if (!source && _targetType == TargetType::SCENE) {
return;
}
auto variable = _variable.lock();
if (!variable) {
return;
}
auto s = OBSGetStrongRef(source);
Screenshot screenshot(s, QRect(), true, 3000);
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
if (!screenshot.GetImage().save(&buffer, "PNG")) {
blog(LOG_WARNING, "Failed to save screenshot to variable!");
}
variable->SetValue(byteArray.toBase64().toStdString());
}
bool MacroActionScreenshot::PerformAction()
@ -52,12 +75,15 @@ bool MacroActionScreenshot::PerformAction()
}
switch (_saveType) {
case MacroActionScreenshot::SaveType::OBS_DEFAULT:
case MacroActionScreenshot::SaveType::OBS_DEFAULT_PATH:
FrontendScreenshot(source);
break;
case MacroActionScreenshot::SaveType::CUSTOM:
case MacroActionScreenshot::SaveType::CUSTOM_PATH:
CustomScreenshot(source);
break;
case MacroActionScreenshot::SaveType::VARIABLE:
VariableScreenshot(source);
break;
default:
break;
}
@ -90,6 +116,8 @@ bool MacroActionScreenshot::Save(obs_data_t *obj) const
obs_data_set_int(obj, "saveType", static_cast<int>(_saveType));
obs_data_set_int(obj, "targetType", static_cast<int>(_targetType));
_path.Save(obj, "savePath");
obs_data_set_string(obj, "variable",
GetWeakVariableName(_variable).c_str());
obs_data_set_int(obj, "version", 1);
return true;
}
@ -103,6 +131,8 @@ bool MacroActionScreenshot::Load(obs_data_t *obj)
_targetType =
static_cast<TargetType>(obs_data_get_int(obj, "targetType"));
_path.Load(obj, "savePath");
_variable =
GetWeakVariableByName(obs_data_get_string(obj, "variableName"));
// TODO: Remove fallback for older versions
if (!obs_data_has_user_value(obj, "version")) {
@ -151,6 +181,8 @@ static void populateSaveTypeSelection(QComboBox *list)
"AdvSceneSwitcher.action.screenshot.save.default"));
list->addItem(obs_module_text(
"AdvSceneSwitcher.action.screenshot.save.custom"));
list->addItem(obs_module_text(
"AdvSceneSwitcher.action.screenshot.save.variable"));
}
static void populateTargetTypeSelection(QComboBox *list)
@ -170,7 +202,8 @@ MacroActionScreenshotEdit::MacroActionScreenshotEdit(
_sources(new SourceSelectionWidget(this, QStringList(), true)),
_saveType(new QComboBox()),
_targetType(new QComboBox()),
_savePath(new FileSelection(FileSelection::Type::WRITE, this))
_savePath(new FileSelection(FileSelection::Type::WRITE, this)),
_variables(new VariableSelection(this))
{
setToolTip(obs_module_text(
"AdvSceneSwitcher.action.screenshot.blackscreenNote"));
@ -192,19 +225,20 @@ MacroActionScreenshotEdit::MacroActionScreenshotEdit(
SLOT(TargetTypeChanged(int)));
QWidget::connect(_savePath, SIGNAL(PathChanged(const QString &)), this,
SLOT(PathChanged(const QString &)));
QWidget::connect(_variables, SIGNAL(SelectionChanged(const QString &)),
this, SLOT(VariableChanged(const QString &)));
QHBoxLayout *layout = new QHBoxLayout;
std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
{"{{sources}}", _sources},
{"{{scenes}}", _scenes},
{"{{saveType}}", _saveType},
{"{{targetType}}", _targetType},
};
auto layout = new QHBoxLayout;
PlaceWidgets(
obs_module_text("AdvSceneSwitcher.action.screenshot.entry"),
layout, widgetPlaceholders);
layout,
{{"{{sources}}", _sources},
{"{{scenes}}", _scenes},
{"{{saveType}}", _saveType},
{"{{targetType}}", _targetType},
{"{{variables}}", _variables}});
QVBoxLayout *mainLayout = new QVBoxLayout;
auto mainLayout = new QVBoxLayout;
mainLayout->addLayout(layout);
mainLayout->addWidget(_savePath);
setLayout(mainLayout);
@ -225,6 +259,7 @@ void MacroActionScreenshotEdit::UpdateEntryData()
_saveType->setCurrentIndex(static_cast<int>(_entryData->_saveType));
_targetType->setCurrentIndex(static_cast<int>(_entryData->_targetType));
_savePath->SetPath(_entryData->_path);
_variables->SetVariable(_entryData->_variable);
SetWidgetVisibility();
}
@ -258,39 +293,42 @@ void MacroActionScreenshotEdit::TargetTypeChanged(int index)
void MacroActionScreenshotEdit::PathChanged(const QString &text)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_path = text.toStdString();
}
void MacroActionScreenshotEdit::SourceChanged(const SourceSelection &source)
{
if (_loading || !_entryData) {
return;
}
auto lock = LockContext();
GUARD_LOADING_AND_LOCK();
_entryData->_source = source;
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroActionScreenshotEdit::VariableChanged(const QString &text)
{
GUARD_LOADING_AND_LOCK();
_entryData->_variable = GetWeakVariableByQString(text);
emit HeaderInfoChanged(
QString::fromStdString(_entryData->GetShortDesc()));
}
void MacroActionScreenshotEdit::SetWidgetVisibility()
{
if (!_entryData) {
return;
}
_savePath->setVisible(_entryData->_saveType ==
MacroActionScreenshot::SaveType::CUSTOM);
MacroActionScreenshot::SaveType::CUSTOM_PATH);
_sources->setVisible(_entryData->_targetType ==
MacroActionScreenshot::TargetType::SOURCE);
_scenes->setVisible(_entryData->_targetType ==
MacroActionScreenshot::TargetType::SCENE);
_variables->setVisible(_entryData->_saveType ==
MacroActionScreenshot::SaveType::VARIABLE);
adjustSize();
updateGeometry();
}
} // namespace advss

View File

@ -4,6 +4,7 @@
#include "scene-selection.hpp"
#include "screenshot-helper.hpp"
#include "source-selection.hpp"
#include "variable.hpp"
#include <QComboBox>
@ -22,27 +23,20 @@ public:
std::shared_ptr<MacroAction> Copy() const;
void ResolveVariablesToFixedValues();
enum class SaveType {
OBS_DEFAULT,
CUSTOM,
};
SaveType _saveType = SaveType::OBS_DEFAULT;
enum class SaveType { OBS_DEFAULT_PATH, CUSTOM_PATH, VARIABLE };
SaveType _saveType = SaveType::OBS_DEFAULT_PATH;
enum class TargetType {
SOURCE,
SCENE,
MAIN_OUTPUT,
};
enum class TargetType { SOURCE, SCENE, MAIN_OUTPUT };
TargetType _targetType = TargetType::SOURCE;
SceneSelection _scene;
SourceSelection _source;
StringVariable _path = obs_module_text("AdvSceneSwitcher.enterPath");
std::weak_ptr<Variable> _variable;
private:
void FrontendScreenshot(OBSWeakSource &);
void CustomScreenshot(OBSWeakSource &);
Screenshot _screenshot;
void FrontendScreenshot(OBSWeakSource &) const;
void CustomScreenshot(OBSWeakSource &) const;
void VariableScreenshot(OBSWeakSource &) const;
static bool _registered;
static const std::string id;
@ -70,20 +64,21 @@ private slots:
void SaveTypeChanged(int index);
void TargetTypeChanged(int index);
void PathChanged(const QString &text);
void VariableChanged(const QString &);
signals:
void HeaderInfoChanged(const QString &);
protected:
private:
void SetWidgetVisibility();
SceneSelectionWidget *_scenes;
SourceSelectionWidget *_sources;
QComboBox *_saveType;
QComboBox *_targetType;
FileSelection *_savePath;
VariableSelection *_variables;
std::shared_ptr<MacroActionScreenshot> _entryData;
private:
void SetWidgetVisibility();
bool _loading = true;
};