Skip to content

Commit 3c82fd0

Browse files
author
eddyStreamlabs
authored
Module (#132)
* Add module load/init * Look for modules inside slobs-plugin * Few fixes on the module API * Fixed initialize module * Fix typo * Clarify substr
1 parent adce1f0 commit 3c82fd0

File tree

10 files changed

+577
-9
lines changed

10 files changed

+577
-9
lines changed

js/module.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,8 +660,8 @@ export interface IAudioFactory {
660660
reset(info: IAudioInfo): boolean;
661661
getGlobal(): IAudio;
662662
}
663-
export interface IModuleFactory {
664-
create(binPath: string, dataPath: string): IModule;
663+
export interface IModuleFactory extends IFactoryTypes {
664+
open(binPath: string, dataPath: string): IModule;
665665
loadAll(): void;
666666
addPath(path: string, dataPath: string): void;
667667
logLoaded(): void;

js/module.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1493,8 +1493,8 @@ export interface IAudioFactory {
14931493
}
14941494

14951495

1496-
export interface IModuleFactory {
1497-
create(binPath: string, dataPath: string): IModule;
1496+
export interface IModuleFactory extends IFactoryTypes {
1497+
open(binPath: string, dataPath: string): IModule;
14981498
loadAll(): void;
14991499
addPath(path: string, dataPath: string): void;
15001500
logLoaded(): void;

obs-studio-client/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ SET(PROJECT_SOURCE
6969
"${PROJECT_SOURCE_DIR}/source/main.cpp"
7070
"${PROJECT_SOURCE_DIR}/source/volmeter.cpp" "${PROJECT_SOURCE_DIR}/source/volmeter.hpp"
7171
"${PROJECT_SOURCE_DIR}/source/video.cpp" "${PROJECT_SOURCE_DIR}/source/video.hpp"
72+
"${PROJECT_SOURCE_DIR}/source/module.cpp" "${PROJECT_SOURCE_DIR}/source/module.hpp"
7273
)
7374
SET(PROJECT_LIBRARIES
7475
${NODEJS_LIBRARIES}

obs-studio-client/source/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "transition.hpp"
3030
#include "video.hpp"
3131
#include "volmeter.hpp"
32+
#include "module.hpp"
3233

3334
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 1;
3435

@@ -47,6 +48,7 @@ void main(v8::Local<v8::Object> exports, v8::Local<v8::Value> module, void* priv
4748
osn::Fader::Register(exports);
4849
osn::VolMeter::Register(exports);
4950
osn::Video::Register(exports);
51+
osn::Module::Register(exports);
5052

5153
while (initializerFunctions.size() > 0) {
5254
initializerFunctions.front()(exports);
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
// Client module for the OBS Studio node module.
2+
// Copyright(C) 2017 Streamlabs (General Workings Inc)
3+
//
4+
// This program is free software; you can redistribute it and/or
5+
// modify it under the terms of the GNU General Public License
6+
// as published by the Free Software Foundation; either version 2
7+
// of the License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program; if not, write to the Free Software
16+
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 - 1301, USA.
17+
18+
#include <condition_variable>
19+
#include <mutex>
20+
#include <string>
21+
#include "controller.hpp"
22+
#include "error.hpp"
23+
#include "ipc-value.hpp"
24+
#include "shared.hpp"
25+
#include "utility.hpp"
26+
#include "module.hpp"
27+
28+
osn::Module::Module(uint64_t id)
29+
{
30+
this->moduleId = id;
31+
}
32+
33+
Nan::Persistent<v8::FunctionTemplate> osn::Module::prototype = Nan::Persistent<v8::FunctionTemplate>();
34+
35+
void osn::Module::Register(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target)
36+
{
37+
auto fnctemplate = Nan::New<v8::FunctionTemplate>();
38+
fnctemplate->InstanceTemplate()->SetInternalFieldCount(1);
39+
fnctemplate->SetClassName(Nan::New<v8::String>("Module").ToLocalChecked());
40+
41+
utilv8::SetTemplateField(fnctemplate, "open", Open);
42+
43+
v8::Local<v8::Template> objtemplate = fnctemplate->PrototypeTemplate();
44+
utilv8::SetTemplateField(objtemplate, "initialize", Initialize);
45+
46+
utilv8::SetTemplateAccessorProperty(objtemplate, "name", Name);
47+
utilv8::SetTemplateAccessorProperty(objtemplate, "fileName", FileName);
48+
utilv8::SetTemplateAccessorProperty(objtemplate, "author", Author);
49+
utilv8::SetTemplateAccessorProperty(objtemplate, "description", Description);
50+
utilv8::SetTemplateAccessorProperty(objtemplate, "binaryPath", BinaryPath);
51+
utilv8::SetTemplateAccessorProperty(objtemplate, "dataPath", DataPath);
52+
53+
utilv8::SetObjectField(target, "Module", fnctemplate->GetFunction());
54+
prototype.Reset(fnctemplate);
55+
}
56+
57+
Nan::NAN_METHOD_RETURN_TYPE osn::Module::Open(Nan::NAN_METHOD_ARGS_TYPE info)
58+
{
59+
std::string bin_path, data_path;
60+
61+
ASSERT_INFO_LENGTH(info, 2);
62+
ASSERT_GET_VALUE(info[0], bin_path);
63+
ASSERT_GET_VALUE(info[1], data_path);
64+
65+
auto conn = GetConnection();
66+
if (!conn)
67+
return;
68+
69+
std::vector<ipc::value> response = conn->call_synchronous_helper("Module", "Open", {ipc::value(bin_path), ipc::value(data_path)});
70+
71+
if (!ValidateResponse(response))
72+
return;
73+
74+
osn::Module* obj = new osn::Module(response[1].value_union.ui64);
75+
info.GetReturnValue().Set(osn::Module::Store(obj));
76+
}
77+
78+
Nan::NAN_METHOD_RETURN_TYPE osn::Module::Initialize(Nan::NAN_METHOD_ARGS_TYPE info)
79+
{
80+
osn::Module* module;
81+
if (!utilv8::SafeUnwrap(info, module)) {
82+
return;
83+
}
84+
85+
auto conn = GetConnection();
86+
if (!conn)
87+
return;
88+
89+
std::vector<ipc::value> response =
90+
conn->call_synchronous_helper("Module", "Initialize", {ipc::value(module->moduleId)});
91+
92+
if (!ValidateResponse(response))
93+
return;
94+
95+
info.GetReturnValue().Set(response[1].value_union.i32);
96+
}
97+
98+
Nan::NAN_METHOD_RETURN_TYPE osn::Module::Name(Nan::NAN_METHOD_ARGS_TYPE info)
99+
{
100+
osn::Module* module;
101+
if (!utilv8::SafeUnwrap(info, module)) {
102+
return;
103+
}
104+
105+
auto conn = GetConnection();
106+
if (!conn)
107+
return;
108+
109+
std::vector<ipc::value> response =
110+
conn->call_synchronous_helper("Module", "GetName", {ipc::value(module->moduleId)});
111+
112+
if (!ValidateResponse(response))
113+
return;
114+
115+
info.GetReturnValue().Set(utilv8::ToValue(response[1].value_str));
116+
}
117+
118+
Nan::NAN_METHOD_RETURN_TYPE osn::Module::FileName(Nan::NAN_METHOD_ARGS_TYPE info)
119+
{
120+
osn::Module* module;
121+
if (!utilv8::SafeUnwrap(info, module)) {
122+
return;
123+
}
124+
125+
auto conn = GetConnection();
126+
if (!conn)
127+
return;
128+
129+
std::vector<ipc::value> response =
130+
conn->call_synchronous_helper("Module", "GetFileName", {ipc::value(module->moduleId)});
131+
132+
if (!ValidateResponse(response))
133+
return;
134+
135+
info.GetReturnValue().Set(utilv8::ToValue(response[1].value_str));
136+
}
137+
138+
Nan::NAN_METHOD_RETURN_TYPE osn::Module::Description(Nan::NAN_METHOD_ARGS_TYPE info)
139+
{
140+
osn::Module* module;
141+
if (!utilv8::SafeUnwrap(info, module)) {
142+
return;
143+
}
144+
145+
auto conn = GetConnection();
146+
if (!conn)
147+
return;
148+
149+
std::vector<ipc::value> response =
150+
conn->call_synchronous_helper("Module", "GetDescription", {ipc::value(module->moduleId)});
151+
152+
if (!ValidateResponse(response))
153+
return;
154+
155+
info.GetReturnValue().Set(utilv8::ToValue(response[1].value_str));
156+
}
157+
158+
Nan::NAN_METHOD_RETURN_TYPE osn::Module::Author(Nan::NAN_METHOD_ARGS_TYPE info)
159+
{
160+
osn::Module* module;
161+
if (!utilv8::SafeUnwrap(info, module)) {
162+
return;
163+
}
164+
165+
auto conn = GetConnection();
166+
if (!conn)
167+
return;
168+
169+
std::vector<ipc::value> response =
170+
conn->call_synchronous_helper("Module", "GetAuthor", {ipc::value(module->moduleId)});
171+
172+
if (!ValidateResponse(response))
173+
return;
174+
175+
info.GetReturnValue().Set(utilv8::ToValue(response[1].value_str));
176+
}
177+
178+
Nan::NAN_METHOD_RETURN_TYPE osn::Module::BinaryPath(Nan::NAN_METHOD_ARGS_TYPE info)
179+
{
180+
osn::Module* module;
181+
if (!utilv8::SafeUnwrap(info, module)) {
182+
return;
183+
}
184+
185+
auto conn = GetConnection();
186+
if (!conn)
187+
return;
188+
189+
std::vector<ipc::value> response =
190+
conn->call_synchronous_helper("Module", "GetBinaryPath", {ipc::value(module->moduleId)});
191+
192+
if (!ValidateResponse(response))
193+
return;
194+
195+
info.GetReturnValue().Set(utilv8::ToValue(response[1].value_str));
196+
}
197+
198+
Nan::NAN_METHOD_RETURN_TYPE osn::Module::DataPath(Nan::NAN_METHOD_ARGS_TYPE info)
199+
{
200+
osn::Module* module;
201+
if (!utilv8::SafeUnwrap(info, module)) {
202+
return;
203+
}
204+
205+
auto conn = GetConnection();
206+
if (!conn)
207+
return;
208+
209+
std::vector<ipc::value> response =
210+
conn->call_synchronous_helper("Module", "GetDataPath", {ipc::value(module->moduleId)});
211+
212+
if (!ValidateResponse(response))
213+
return;
214+
215+
info.GetReturnValue().Set(utilv8::ToValue(response[1].value_str));
216+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Client module for the OBS Studio node module.
2+
// Copyright(C) 2017 Streamlabs (General Workings Inc)
3+
//
4+
// This program is free software; you can redistribute it and/or
5+
// modify it under the terms of the GNU General Public License
6+
// as published by the Free Software Foundation; either version 2
7+
// of the License, or (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
12+
// GNU General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program; if not, write to the Free Software
16+
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110 - 1301, USA.
17+
18+
#pragma once
19+
#include <nan.h>
20+
#include <node.h>
21+
#include "utility-v8.hpp"
22+
23+
namespace osn
24+
{
25+
class Module : public utilv8::ManagedObject<osn::Module>, public Nan::ObjectWrap
26+
{
27+
friend class utilv8::ManagedObject<osn::Module>;
28+
29+
public:
30+
uint64_t moduleId;
31+
Module(uint64_t id);
32+
virtual ~Module(){};
33+
34+
// JavaScript
35+
public:
36+
static Nan::Persistent<v8::FunctionTemplate> prototype;
37+
38+
static void Register(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target);
39+
40+
//Functions
41+
static Nan::NAN_METHOD_RETURN_TYPE Open(Nan::NAN_METHOD_ARGS_TYPE info);
42+
static Nan::NAN_METHOD_RETURN_TYPE Initialize(Nan::NAN_METHOD_ARGS_TYPE info);
43+
44+
//Methods
45+
static Nan::NAN_METHOD_RETURN_TYPE Name(Nan::NAN_METHOD_ARGS_TYPE info);
46+
static Nan::NAN_METHOD_RETURN_TYPE FileName(Nan::NAN_METHOD_ARGS_TYPE info);
47+
static Nan::NAN_METHOD_RETURN_TYPE Author(Nan::NAN_METHOD_ARGS_TYPE info);
48+
static Nan::NAN_METHOD_RETURN_TYPE Description(Nan::NAN_METHOD_ARGS_TYPE info);
49+
static Nan::NAN_METHOD_RETURN_TYPE BinaryPath(Nan::NAN_METHOD_ARGS_TYPE info);
50+
static Nan::NAN_METHOD_RETURN_TYPE DataPath(Nan::NAN_METHOD_ARGS_TYPE info);
51+
52+
53+
};
54+
} // namespace osn

obs-studio-server/source/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "osn-transition.hpp"
4242
#include "osn-video.hpp"
4343
#include "osn-volmeter.hpp"
44+
#include "osn-module.hpp"
4445

4546
extern "C" __declspec(dllexport) DWORD NvOptimusEnablement = 1;
4647

@@ -169,6 +170,7 @@ int main(int argc, char* argv[])
169170
osn::VolMeter::Register(myServer);
170171
osn::Properties::Register(myServer);
171172
osn::Video::Register(myServer);
173+
osn::Module::Register(myServer);
172174
OBS_API::Register(myServer);
173175
OBS_content::Register(myServer);
174176
OBS_service::Register(myServer);

obs-studio-server/source/nodeobs_api.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ std::string OBS_currentSceneCollectio
4242
bool useOBS_configFiles = false;
4343
bool isOBS_installedValue;
4444
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
45+
std::string slobs_plugin;
4546

4647
std::string g_moduleDirectory = "";
4748

@@ -427,14 +428,16 @@ void OBS_API::OBS_API_initAPI(
427428
}
428429
pathConfigDirectory = args[0].value_str.c_str();
429430
appdata_path = args[0].value_str.c_str();
430-
appdata_path += "/node-obs/";
431431

432432
/* libobs will use three methods of finding data files:
433433
* 1. ${CWD}/data/libobs <- This doesn't work for us
434434
* 2. ${OBS_DATA_PATH}/libobs <- This works but is inflexible
435435
* 3. getenv(OBS_DATA_PATH) + /libobs <- Can be set anywhere
436436
* on the cli, in the frontend, or the backend. */
437437
obs_add_data_path((g_moduleDirectory + "/libobs/data/libobs/").c_str());
438+
slobs_plugin = appdata_path.substr(0, appdata_path.size() - strlen("/slobs-client"));
439+
slobs_plugin.append("/slobs-plugins");
440+
obs_add_data_path((slobs_plugin + "/data/").c_str());
438441

439442
std::vector<char> userData = std::vector<char>(1024);
440443
os_get_config_path(userData.data(), userData.capacity() - 1, "slobs-client/plugin_config");
@@ -443,7 +446,7 @@ void OBS_API::OBS_API_initAPI(
443446
/* Logging */
444447
string filename = GenerateTimeDateFilename("txt");
445448
string log_path = appdata_path;
446-
log_path.append("/logs/");
449+
log_path.append("/node-obs/logs/");
447450

448451
/* Make sure the path is created
449452
before attempting to make a file there. */
@@ -818,9 +821,10 @@ void OBS_API::openAllModules(void)
818821
{
819822
OBS_service::resetVideoContext(NULL);
820823

821-
std::string plugins_paths[] = {g_moduleDirectory + "/obs-plugins/64bit", g_moduleDirectory + "/obs-plugins"};
824+
std::string plugins_paths[] = {g_moduleDirectory + "/obs-plugins/64bit", g_moduleDirectory + "/obs-plugins", slobs_plugin + "/obs-plugins/64bit"};
822825

823-
std::string plugins_data_paths[] = {g_moduleDirectory + "/data/obs-plugins", plugins_data_paths[0]};
826+
std::string plugins_data_paths[] = {
827+
g_moduleDirectory + "/data/obs-plugins", plugins_data_paths[0], slobs_plugin + "/data/obs-plugins"};
824828

825829
size_t num_paths = sizeof(plugins_paths) / sizeof(plugins_paths[0]);
826830

0 commit comments

Comments
 (0)