noobs 0.0.33 → 0.0.60

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/noobs.node CHANGED
Binary file
Binary file
Binary file
package/index.d.ts CHANGED
@@ -1,3 +1,134 @@
1
+ // OBS Data Types
2
+ export type ObsDataValue = string | number | boolean | ObsData | ObsData[] | null;
3
+
4
+ export interface ObsData {
5
+ [key: string]: ObsDataValue;
6
+ }
7
+
8
+ // OBS Property Types
9
+ export type ObsPropertyType =
10
+ | 'invalid'
11
+ | 'bool'
12
+ | 'int'
13
+ | 'float'
14
+ | 'text'
15
+ | 'path'
16
+ | 'list'
17
+ | 'color'
18
+ | 'button'
19
+ | 'font'
20
+ | 'editable_list'
21
+ | 'frame_rate'
22
+ | 'group'
23
+ | 'color_alpha'
24
+ | 'unknown';
25
+
26
+ export type ObsNumberType = 'scroller' | 'slider';
27
+
28
+ export type ObsTextType = 'default' | 'password' | 'multiline' | 'info';
29
+
30
+ export type ObsPathType = 'file' | 'file_save' | 'directory';
31
+
32
+ export type ObsComboType = 'invalid' | 'editable' | 'list' | 'radio';
33
+
34
+ export type ObsComboFormat = 'invalid' | 'int' | 'float' | 'string';
35
+
36
+ export interface ObsListItem {
37
+ name: string;
38
+ value: string | number;
39
+ disabled: boolean;
40
+ }
41
+
42
+ export interface ObsPropertyBase {
43
+ name: string;
44
+ description: string;
45
+ type: ObsPropertyType;
46
+ enabled: boolean;
47
+ visible: boolean;
48
+ }
49
+
50
+ export interface ObsIntProperty extends ObsPropertyBase {
51
+ type: 'int';
52
+ min: number;
53
+ max: number;
54
+ step: number;
55
+ number_type: ObsNumberType;
56
+ }
57
+
58
+ export interface ObsFloatProperty extends ObsPropertyBase {
59
+ type: 'float';
60
+ min: number;
61
+ max: number;
62
+ step: number;
63
+ number_type: ObsNumberType;
64
+ }
65
+
66
+ export interface ObsTextProperty extends ObsPropertyBase {
67
+ type: 'text';
68
+ text_type: ObsTextType;
69
+ }
70
+
71
+ export interface ObsPathProperty extends ObsPropertyBase {
72
+ type: 'path';
73
+ path_type: ObsPathType;
74
+ filter: string;
75
+ default_path: string;
76
+ }
77
+
78
+ export interface ObsListProperty extends ObsPropertyBase {
79
+ type: 'list';
80
+ combo_type: ObsComboType;
81
+ combo_format: ObsComboFormat;
82
+ items: ObsListItem[];
83
+ }
84
+
85
+ export interface ObsBoolProperty extends ObsPropertyBase {
86
+ type: 'bool';
87
+ }
88
+
89
+ export interface ObsColorProperty extends ObsPropertyBase {
90
+ type: 'color' | 'color_alpha';
91
+ }
92
+
93
+ export interface ObsButtonProperty extends ObsPropertyBase {
94
+ type: 'button';
95
+ }
96
+
97
+ export interface ObsFontProperty extends ObsPropertyBase {
98
+ type: 'font';
99
+ }
100
+
101
+ export interface ObsEditableListProperty extends ObsPropertyBase {
102
+ type: 'editable_list';
103
+ }
104
+
105
+ export interface ObsFrameRateProperty extends ObsPropertyBase {
106
+ type: 'frame_rate';
107
+ }
108
+
109
+ export interface ObsGroupProperty extends ObsPropertyBase {
110
+ type: 'group';
111
+ }
112
+
113
+ export interface ObsGenericProperty extends ObsPropertyBase {
114
+ type: 'invalid' | 'unknown';
115
+ }
116
+
117
+ export type ObsProperty =
118
+ | ObsIntProperty
119
+ | ObsFloatProperty
120
+ | ObsTextProperty
121
+ | ObsPathProperty
122
+ | ObsListProperty
123
+ | ObsBoolProperty
124
+ | ObsColorProperty
125
+ | ObsButtonProperty
126
+ | ObsFontProperty
127
+ | ObsEditableListProperty
128
+ | ObsFrameRateProperty
129
+ | ObsGroupProperty
130
+ | ObsGenericProperty;
131
+
1
132
  export type Signal = {
2
133
  id: string; // Signal identifier, e.g. "stop"
3
134
  code: number; // 0 for success, other values for errors
@@ -21,18 +152,34 @@ interface Noobs {
21
152
  logPath: string,
22
153
  dataPath: string,
23
154
  recordingPath: string,
24
- cb: (signal: Signal) => void
155
+ cb: (signal: Signal) => void,
156
+ buffering: boolean,
25
157
  ): void;
26
158
 
27
159
  Shutdown(): void;
160
+
161
+ // Recording functions
28
162
  StartBuffer(): void;
29
163
  StartRecording(offset: number): void;
30
164
  StopRecording(): void;
31
165
  GetLastRecording(): string;
166
+ SetRecordingDir(recordingPath: string): void;
167
+
168
+ // Source management functions
169
+ CreateSource(name: string, type: string): void;
170
+ DeleteSource(name: string): void;
171
+ GetSourceSettings(name: string): ObsData;
172
+ SetSourceSettings(name: string, settings: ObsData): void;
173
+ GetSourceProperties(name: string): ObsProperty[];
32
174
 
33
- GetSourcePos(src: string): SceneItemPosition & SourceDimensions;
34
- SetSourcePos(src: string, pos: SceneItemPosition): void;
175
+ // Scene management functions
176
+ AddSourceToScene(sourceName: string): void;
177
+ RemoveSourceFromScene(sourceName: string): void;
178
+ GetSourcePos(name: string): SceneItemPosition & SourceDimensions;
179
+ SetSourcePos(name: string, pos: SceneItemPosition): void;
180
+ // TODO: Cropping?
35
181
 
182
+ // Preview functions
36
183
  InitPreview(hwnd: Buffer): void;
37
184
  ShowPreview(x: number, y: number, width: number, height: number): void;
38
185
  HidePreview(): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noobs",
3
- "version": "0.0.33",
3
+ "version": "0.0.60",
4
4
  "description": "A native Node.js addon with libobs bindings for Warcraft Recorder.",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
package/src/main.cpp CHANGED
@@ -1,24 +1,19 @@
1
1
  #include <napi.h>
2
2
  #include <windows.h>
3
- #include <tlhelp32.h>
4
- #include <string>
5
- #include <vector>
6
3
  #include <obs.h>
7
- #include <iostream>
8
- #include <future>
9
- #include <chrono>
10
-
11
4
  #include "obs_interface.h"
5
+ #include "utils.h"
12
6
 
13
7
  ObsInterface* obs = nullptr;
14
8
 
15
9
  Napi::Value ObsInit(const Napi::CallbackInfo& info) {
16
- bool valid = info.Length() == 5 &&
17
- info[0].IsString() && // Plugin path
18
- info[1].IsString() && // Log path
19
- info[2].IsString() && // Data path
20
- info[3].IsString() && // Recording path
21
- info[4].IsFunction(); // JavaScript callback
10
+ bool valid = info.Length() == 6 &&
11
+ info[0].IsString() && // Plugin path
12
+ info[1].IsString() && // Log path
13
+ info[2].IsString() && // Data path
14
+ info[3].IsString() && // Recording path
15
+ info[4].IsFunction() && // JavaScript callback
16
+ info[5].IsBoolean(); // IsBuffer
22
17
 
23
18
  if (!valid) {
24
19
  Napi::Error::New(info.Env(), "Invalid arguments passed to ObsInit").ThrowAsJavaScriptException();
@@ -30,11 +25,12 @@ Napi::Value ObsInit(const Napi::CallbackInfo& info) {
30
25
  std::string dataPath = info[2].As<Napi::String>().Utf8Value();
31
26
  std::string recordingPath = info[3].As<Napi::String>().Utf8Value();
32
27
  Napi::Function fn = info[4].As<Napi::Function>();
28
+ bool isBuffer = info[5].As<Napi::Boolean>().Value();
33
29
 
34
30
  Napi::ThreadSafeFunction jscb =
35
31
  Napi::ThreadSafeFunction::New(info.Env(), fn, "JavaScript callback", 0, 1);
36
32
 
37
- obs = new ObsInterface(pluginPath, logPath, dataPath, recordingPath, jscb);
33
+ obs = new ObsInterface(pluginPath, logPath, dataPath, recordingPath, jscb, isBuffer);
38
34
  return info.Env().Undefined();
39
35
  }
40
36
 
@@ -44,6 +40,24 @@ Napi::Value ObsShutdown(const Napi::CallbackInfo& info) {
44
40
  return info.Env().Undefined();
45
41
  }
46
42
 
43
+ Napi::Value ObsSetRecordingDir(const Napi::CallbackInfo& info) {
44
+ if (!obs) {
45
+ blog(LOG_ERROR, "ObsSetRecordingDir called but obs is not initialized");
46
+ throw std::runtime_error("Obs not initialized");
47
+ }
48
+
49
+ bool valid = info.Length() == 1 && info[0].IsString();
50
+
51
+ if (!valid) {
52
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsSetRecordingDir").ThrowAsJavaScriptException();
53
+ return info.Env().Undefined();
54
+ }
55
+
56
+ std::string recordingPath = info[0].As<Napi::String>().Utf8Value();
57
+ obs->updateRecordingDir(recordingPath);
58
+ return info.Env().Undefined();
59
+ }
60
+
47
61
  Napi::Value ObsStartBuffer(const Napi::CallbackInfo& info) {
48
62
  blog(LOG_INFO, "ObsStartBuffer called");
49
63
 
@@ -157,9 +171,174 @@ Napi::Value ObsHidePreview(const Napi::CallbackInfo& info) {
157
171
  return info.Env().Undefined();
158
172
  }
159
173
 
174
+ Napi::Value ObsCreateSource(const Napi::CallbackInfo& info) {
175
+ if (!obs) {
176
+ blog(LOG_ERROR, "ObsCreateSource called but obs is not initialized");
177
+ throw std::runtime_error("Obs not initialized");
178
+ }
179
+
180
+ bool valid = info.Length() == 2 &&
181
+ info[0].IsString() && // Source name
182
+ info[1].IsString(); // Source type
183
+
184
+ if (!valid) {
185
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsCreateSource").ThrowAsJavaScriptException();
186
+ return info.Env().Undefined();
187
+ }
188
+
189
+ std::string name = info[0].As<Napi::String>().Utf8Value();
190
+ std::string type = info[1].As<Napi::String>().Utf8Value();
191
+
192
+ obs->createSource(name, type);
193
+ return info.Env().Undefined();
194
+ }
195
+
196
+ Napi::Value ObsDeleteSource(const Napi::CallbackInfo& info) {
197
+ if (!obs) {
198
+ blog(LOG_ERROR, "ObsDeleteSource called but obs is not initialized");
199
+ throw std::runtime_error("Obs not initialized");
200
+ }
201
+
202
+ bool valid = info.Length() == 1 && info[0].IsString();
203
+
204
+ if (!valid) {
205
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsDeleteSource").ThrowAsJavaScriptException();
206
+ return info.Env().Undefined();
207
+ }
208
+
209
+ std::string name = info[0].As<Napi::String>().Utf8Value();
210
+ obs->deleteSource(name);
211
+ return info.Env().Undefined();
212
+ }
213
+
214
+ Napi::Value ObsGetSourceSettings(const Napi::CallbackInfo& info) {
215
+ if (!obs) {
216
+ blog(LOG_ERROR, "ObsGetSourceSettings called but obs is not initialized");
217
+ throw std::runtime_error("Obs not initialized");
218
+ }
219
+
220
+ bool valid = info.Length() == 1 && info[0].IsString();
221
+
222
+ if (!valid) {
223
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsGetSourceSettings").ThrowAsJavaScriptException();
224
+ return info.Env().Undefined();
225
+ }
226
+
227
+ std::string name = info[0].As<Napi::String>().Utf8Value();
228
+
229
+ obs_data_t* settings = obs->getSourceSettings(name);
230
+ Napi::Object result = data_to_napi(info.Env(), settings);
231
+ obs_data_release(settings);
232
+
233
+ return result;
234
+ }
235
+
236
+ Napi::Value ObsSetSourceSettings(const Napi::CallbackInfo& info) {
237
+ if (!obs) {
238
+ blog(LOG_ERROR, "ObsSetSourceSettings called but obs is not initialized");
239
+ throw std::runtime_error("Obs not initialized");
240
+ }
241
+
242
+ bool valid = info.Length() == 2 && info[0].IsString() && info[1].IsObject();
243
+
244
+ if (!valid) {
245
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsSetSourceSettings").ThrowAsJavaScriptException();
246
+ return info.Env().Undefined();
247
+ }
248
+
249
+ std::string name = info[0].As<Napi::String>().Utf8Value();
250
+
251
+ Napi::Object obj = info[1].As<Napi::Object>();
252
+ obs_data_t* settings = napi_to_data(obj);
253
+ obs->setSourceSettings(name, settings);
254
+ obs_data_release(settings);
255
+
256
+ return info.Env().Undefined();
257
+ }
258
+
259
+ Napi::Value ObsGetSourceProperties(const Napi::CallbackInfo& info) {
260
+ if (!obs) {
261
+ blog(LOG_ERROR, "ObsGetSourceProperties called but obs is not initialized");
262
+ throw std::runtime_error("Obs not initialized");
263
+ }
264
+
265
+ bool valid = info.Length() == 1 && info[0].IsString();
266
+
267
+ if (!valid) {
268
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsGetSourceProperties").ThrowAsJavaScriptException();
269
+ return info.Env().Undefined();
270
+ }
271
+
272
+ std::string name = info[0].As<Napi::String>().Utf8Value();
273
+ obs_properties_t* properties = obs->getSourceProperties(name);
274
+ Napi::Object result = properties_to_napi(info.Env(), properties);
275
+ obs_properties_destroy(properties);
276
+
277
+ return result;
278
+ }
279
+
280
+ Napi::Value ObsCreateScene(const Napi::CallbackInfo& info) {
281
+ if (!obs) {
282
+ blog(LOG_ERROR, "ObsCreateScene called but obs is not initialized");
283
+ throw std::runtime_error("Obs not initialized");
284
+ }
285
+
286
+ bool valid = info.Length() == 2 &&
287
+ info[0].IsString() && // Scene name
288
+ info[1].IsString(); // Source type
289
+
290
+ if (!valid) {
291
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsCreateScene").ThrowAsJavaScriptException();
292
+ return info.Env().Undefined();
293
+ }
294
+
295
+ std::string name = info[0].As<Napi::String>().Utf8Value();
296
+ std::string type = info[1].As<Napi::String>().Utf8Value();
297
+
298
+ obs->createSource(name, type);
299
+ return info.Env().Undefined();
300
+ }
301
+
302
+ Napi::Value ObsAddSourceToScene(const Napi::CallbackInfo& info) {
303
+ if (!obs) {
304
+ blog(LOG_ERROR, "ObsAddSourceToScene called but obs is not initialized");
305
+ throw std::runtime_error("Obs not initialized");
306
+ }
307
+
308
+ bool valid = info.Length() == 1 && info[0].IsString();
309
+
310
+ if (!valid) {
311
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsAddSourceToScene").ThrowAsJavaScriptException();
312
+ return info.Env().Undefined();
313
+ }
314
+
315
+ std::string name = info[0].As<Napi::String>().Utf8Value();
316
+
317
+ obs->addSourceToScene(name);
318
+ return info.Env().Undefined();
319
+ }
320
+
321
+ Napi::Value ObsRemoveSourceFromScene(const Napi::CallbackInfo& info) {
322
+ if (!obs) {
323
+ blog(LOG_ERROR, "ObsRemoveSourceFromScene called but obs is not initialized");
324
+ throw std::runtime_error("Obs not initialized");
325
+ }
326
+
327
+ bool valid = info.Length() == 1 && info[0].IsString();
328
+
329
+ if (!valid) {
330
+ Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsRemoveSourceFromScene").ThrowAsJavaScriptException();
331
+ return info.Env().Undefined();
332
+ }
333
+
334
+ std::string name = info[0].As<Napi::String>().Utf8Value();
335
+ obs->removeSourceFromScene(name);
336
+ return info.Env().Undefined();
337
+ }
338
+
160
339
  Napi::Value ObsGetSourcePos(const Napi::CallbackInfo& info) {
161
340
  if (!obs) {
162
- blog(LOG_ERROR, "ObsUpdateSource called but obs is not initialized");
341
+ blog(LOG_ERROR, "ObsGetSourcePos called but obs is not initialized");
163
342
  throw std::runtime_error("Obs not initialized");
164
343
  }
165
344
 
@@ -187,16 +366,13 @@ Napi::Value ObsGetSourcePos(const Napi::CallbackInfo& info) {
187
366
 
188
367
  Napi::Value ObsSetSourcePos(const Napi::CallbackInfo& info) {
189
368
  if (!obs) {
190
- blog(LOG_ERROR, "ObsUpdateSource called but obs is not initialized");
369
+ blog(LOG_ERROR, "ObsSetSourcePos called but obs is not initialized");
191
370
  throw std::runtime_error("Obs not initialized");
192
371
  }
193
372
 
194
- bool valid = info.Length() == 5 &&
373
+ bool valid = info.Length() == 2 &&
195
374
  info[0].IsString() && // Source name
196
- info[1].IsNumber() && // X position (px)
197
- info[2].IsNumber() && // Y position (px)
198
- info[3].IsNumber() && // Scale factor (X)
199
- info[4].IsNumber(); // Scale factor (Y)
375
+ info[1].IsObject(); // Position definition.
200
376
 
201
377
  if (!valid) {
202
378
  Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsSetSourcePos").ThrowAsJavaScriptException();
@@ -205,12 +381,13 @@ Napi::Value ObsSetSourcePos(const Napi::CallbackInfo& info) {
205
381
 
206
382
  std::string name = info[0].As<Napi::String>().Utf8Value();
207
383
 
208
- float x = info[1].As<Napi::Number>().FloatValue();
209
- float y = info[2].As<Napi::Number>().FloatValue();
384
+ Napi::Object position = info[1].As<Napi::Object>();
385
+ float x = position.Get("x").As<Napi::Number>().FloatValue();
386
+ float y = position.Get("y").As<Napi::Number>().FloatValue();
210
387
  vec2 pos = { x, y };
211
388
 
212
- float scaleX = info[3].As<Napi::Number>().FloatValue();
213
- float scaleY = info[4].As<Napi::Number>().FloatValue();
389
+ float scaleX = position.Get("scaleX").As<Napi::Number>().FloatValue();
390
+ float scaleY = position.Get("scaleY").As<Napi::Number>().FloatValue();
214
391
  vec2 scale = { scaleX, scaleY };
215
392
 
216
393
  obs->setSourcePos(name, &pos, &scale);
@@ -220,18 +397,28 @@ Napi::Value ObsSetSourcePos(const Napi::CallbackInfo& info) {
220
397
  Napi::Object Init(Napi::Env env, Napi::Object exports) {
221
398
  exports.Set("Init", Napi::Function::New(env, ObsInit));
222
399
  exports.Set("Shutdown", Napi::Function::New(env, ObsShutdown));
400
+ exports.Set("SetRecordingDir", Napi::Function::New(env, ObsSetRecordingDir));
223
401
 
224
402
  exports.Set("StartBuffer", Napi::Function::New(env, ObsStartBuffer));
225
403
  exports.Set("StartRecording", Napi::Function::New(env, ObsStartRecording));
226
404
  exports.Set("StopRecording", Napi::Function::New(env, ObsStopRecording));
227
405
  exports.Set("GetLastRecording", Napi::Function::New(env, ObsGetLastRecording));
228
406
 
407
+ exports.Set("CreateSource", Napi::Function::New(env, ObsCreateSource));
408
+ exports.Set("DeleteSource", Napi::Function::New(env, ObsDeleteSource));
409
+ exports.Set("GetSourceSettings", Napi::Function::New(env, ObsGetSourceSettings));
410
+ exports.Set("SetSourceSettings", Napi::Function::New(env, ObsSetSourceSettings));
411
+ exports.Set("GetSourceProperties", Napi::Function::New(env, ObsGetSourceProperties));
412
+
413
+ exports.Set("AddSourceToScene", Napi::Function::New(env, ObsAddSourceToScene));
414
+ exports.Set("RemoveSourceFromScene", Napi::Function::New(env, ObsRemoveSourceFromScene));
229
415
  exports.Set("GetSourcePos", Napi::Function::New(env, ObsGetSourcePos));
230
416
  exports.Set("SetSourcePos", Napi::Function::New(env, ObsSetSourcePos));
231
417
 
232
418
  exports.Set("InitPreview", Napi::Function::New(env, ObsInitPreview));
233
419
  exports.Set("ShowPreview", Napi::Function::New(env, ObsShowPreview));
234
420
  exports.Set("HidePreview", Napi::Function::New(env, ObsHidePreview));
421
+
235
422
  return exports;
236
423
  }
237
424