noobs 0.0.30 → 0.0.31

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
package/index.d.ts CHANGED
@@ -4,7 +4,7 @@ type Signal = { // TODO export type?
4
4
  }
5
5
 
6
6
  interface Noobs {
7
- ObsInit(
7
+ Init(
8
8
  pluginPath: string,
9
9
  logPath: string,
10
10
  dataPath: string,
@@ -12,15 +12,17 @@ interface Noobs {
12
12
  cb: (signal: Signal) => void
13
13
  ): void;
14
14
 
15
- ObsShutdown(): void;
16
- ObsStartBuffer(): void;
17
- ObsStartRecording(offset: number): void;
18
- ObsStopRecording(): void;
19
- ObsGetLastRecording(): string;
15
+ Shutdown(): void;
16
+ StartBuffer(): void;
17
+ StartRecording(offset: number): void;
18
+ StopRecording(): void;
19
+ GetLastRecording(): string;
20
20
 
21
- ObsInitPreview(hwnd: Buffer): void;
22
- ObsShowPreview(x: number, y: number, width: number, height: number): void;
23
- ObsHidePreview(): void;
21
+ UpdateSource(x: number, y: number, scale: number): void;
22
+
23
+ InitPreview(hwnd: Buffer): void;
24
+ ShowPreview(x: number, y: number, width: number, height: number): void;
25
+ HidePreview(): void;
24
26
  }
25
27
 
26
28
  declare const noobs: Noobs;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noobs",
3
- "version": "0.0.30",
3
+ "version": "0.0.31",
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
@@ -157,18 +157,39 @@ Napi::Value ObsHidePreview(const Napi::CallbackInfo& info) {
157
157
  return info.Env().Undefined();
158
158
  }
159
159
 
160
+ Napi::Value ObsUpdateSourcePos(const Napi::CallbackInfo& info) {
161
+ if (!obs) {
162
+ blog(LOG_ERROR, "ObsUpdateSource called but obs is not initialized");
163
+ throw std::runtime_error("Obs not initialized");
164
+ }
165
+
166
+ bool valid = info.Length() == 3 &&
167
+ info[0].IsNumber() && // X position (px)
168
+ info[1].IsNumber() && // Y position (px)
169
+ info[2].IsNumber(); // Scale (multiplier)
170
+
171
+ int x = info[0].As<Napi::Number>().Int32Value();
172
+ int y = info[1].As<Napi::Number>().Int32Value();
173
+ float scale = info[2].As<Napi::Number>().FloatValue();
174
+
175
+ obs->updateSourcePos(x, y, scale);
176
+ return info.Env().Undefined();
177
+ }
178
+
160
179
  Napi::Object Init(Napi::Env env, Napi::Object exports) {
161
- exports.Set("ObsInit", Napi::Function::New(env, ObsInit));
162
- exports.Set("ObsShutdown", Napi::Function::New(env, ObsShutdown));
180
+ exports.Set("Init", Napi::Function::New(env, ObsInit));
181
+ exports.Set("Shutdown", Napi::Function::New(env, ObsShutdown));
182
+
183
+ exports.Set("StartBuffer", Napi::Function::New(env, ObsStartBuffer));
184
+ exports.Set("StartRecording", Napi::Function::New(env, ObsStartRecording));
185
+ exports.Set("StopRecording", Napi::Function::New(env, ObsStopRecording));
186
+ exports.Set("GetLastRecording", Napi::Function::New(env, ObsGetLastRecording));
163
187
 
164
- exports.Set("ObsStartBuffer", Napi::Function::New(env, ObsStartBuffer));
165
- exports.Set("ObsStartRecording", Napi::Function::New(env, ObsStartRecording));
166
- exports.Set("ObsStopRecording", Napi::Function::New(env, ObsStopRecording));
167
- exports.Set("ObsGetLastRecording", Napi::Function::New(env, ObsGetLastRecording));
188
+ exports.Set("UpdateSourcePos", Napi::Function::New(env, ObsUpdateSourcePos));
168
189
 
169
- exports.Set("ObsInitPreview", Napi::Function::New(env, ObsInitPreview));
170
- exports.Set("ObsShowPreview", Napi::Function::New(env, ObsShowPreview));
171
- exports.Set("ObsHidePreview", Napi::Function::New(env, ObsHidePreview));
190
+ exports.Set("InitPreview", Napi::Function::New(env, ObsInitPreview));
191
+ exports.Set("ShowPreview", Napi::Function::New(env, ObsShowPreview));
192
+ exports.Set("HidePreview", Napi::Function::New(env, ObsHidePreview));
172
193
  return exports;
173
194
  }
174
195
 
@@ -178,15 +178,26 @@ void ObsInterface::init_obs(const std::string& pluginPath, const std::string& da
178
178
  blog(LOG_INFO, "Exit init_obs");
179
179
  }
180
180
 
181
- obs_output_t* ObsInterface::create_output(const std::string& recordingPath) {
181
+ void ObsInterface::configure_output(const std::string& recordingPath) {
182
182
  blog(LOG_INFO, "Create output");
183
- obs_output_t *output = obs_output_create("replay_buffer", "recording_output", NULL, NULL);
183
+
184
+ if (output && obs_output_active(output)) {
185
+ blog(LOG_ERROR, "Tried to recreate active output");
186
+ throw std::runtime_error("Failed to create output!");
187
+ }
188
+
189
+ if (output) {
190
+ blog(LOG_DEBUG, "Releasing output");
191
+ obs_output_release(output);
192
+ }
193
+
194
+ output = obs_output_create("replay_buffer", "recording_output", NULL, NULL);
184
195
 
185
196
  if (!output) {
186
197
  blog(LOG_ERROR, "Failed to create output!");
187
198
  throw std::runtime_error("Failed to create output!");
188
199
  }
189
-
200
+
190
201
  blog(LOG_INFO, "Set output settings");
191
202
  obs_data_t *settings = obs_data_create();
192
203
  obs_data_set_int(settings, "max_time_sec", 60);
@@ -197,7 +208,24 @@ obs_output_t* ObsInterface::create_output(const std::string& recordingPath) {
197
208
  obs_output_update(output, settings);
198
209
  obs_data_release(settings);
199
210
 
200
- blog(LOG_INFO, "Create venc");
211
+ // Add the signal handler callback.
212
+ create_signal_handlers(output);
213
+ }
214
+
215
+ void ObsInterface::configure_video_encoder() {
216
+ blog(LOG_INFO, "Create video encoder");
217
+
218
+ if (!output) {
219
+ blog(LOG_ERROR, "No output on configure_video_encoder");
220
+ throw std::runtime_error("Failed to create video encoder!");
221
+ }
222
+
223
+ if (video_encoder) {
224
+ blog(LOG_DEBUG, "Releasing video encoder");
225
+ obs_encoder_release(video_encoder);
226
+ video_encoder = nullptr;
227
+ }
228
+
201
229
  video_encoder = obs_video_encoder_create("obs_x264", "simple_h264_stream", NULL, NULL);
202
230
 
203
231
  if (!video_encoder) {
@@ -208,15 +236,28 @@ obs_output_t* ObsInterface::create_output(const std::string& recordingPath) {
208
236
  blog(LOG_INFO, "Set video encoder settings");
209
237
  obs_data_t* venc_settings = obs_data_create();
210
238
  obs_data_set_string(venc_settings, "preset", "speed"); // Faster preset
211
- //obs_data_set_int(amf_settings, "bitrate", 2500);
212
239
  obs_data_set_string(venc_settings, "rate_control", "CRF");
213
240
  obs_data_set_int(venc_settings, "crf", 30);
214
241
  obs_data_set_string(venc_settings, "profile", "main");
215
242
  obs_data_set_int(venc_settings, "keyint_sec", 1); // Set keyframe interval to 1 second
216
243
  obs_encoder_update(video_encoder, venc_settings);
217
244
  obs_data_release(venc_settings);
245
+ }
246
+
247
+ void ObsInterface::configure_audio_encoder() {
248
+ blog(LOG_INFO, "Create audio encoder");
249
+
250
+ if (!output) {
251
+ blog(LOG_ERROR, "No output on configure_audio_encoder");
252
+ throw std::runtime_error("Failed to create audio encoder!");
253
+ }
254
+
255
+ if (audio_encoder) {
256
+ blog(LOG_DEBUG, "Releasing audio encoder");
257
+ obs_encoder_release(audio_encoder);
258
+ audio_encoder = nullptr;
259
+ }
218
260
 
219
- blog(LOG_INFO, "Create aenc");
220
261
  audio_encoder = obs_audio_encoder_create("ffmpeg_aac", "simple_aac", NULL, 0, NULL);
221
262
 
222
263
  if (!audio_encoder) {
@@ -235,40 +276,50 @@ obs_output_t* ObsInterface::create_output(const std::string& recordingPath) {
235
276
 
236
277
  obs_encoder_set_video(video_encoder, obs_get_video());
237
278
  obs_encoder_set_audio(audio_encoder, obs_get_audio());
238
-
239
- return output;
240
279
  }
241
280
 
242
- obs_scene_t* ObsInterface::create_scene() {
243
- blog(LOG_INFO, "Create scene and src");
244
- obs_scene_t *scene = obs_scene_create("WCR Scene");
281
+ void ObsInterface::configure_scene() {
282
+ blog(LOG_INFO, "Configure scene");
283
+
284
+ if (scene) {
285
+ blog(LOG_DEBUG, "Releasing scene");
286
+ obs_scene_release(scene);
287
+ scene = nullptr;
288
+ }
289
+
290
+ scene = obs_scene_create("WCR Scene");
245
291
 
246
- if (!scene)
292
+ if (!scene) {
293
+ blog(LOG_ERROR, "Failed to create scene!");
247
294
  throw std::runtime_error("Failed to create scene!");
295
+ }
248
296
 
249
297
  obs_source_t *scene_source = obs_scene_get_source(scene);
250
298
 
251
- if (!scene_source)
252
- throw std::runtime_error("Failed to get scene src!");
299
+ if (!scene_source) {
300
+ blog(LOG_ERROR, "Failed to get scene source!");
301
+ throw std::runtime_error("Failed to get scene source!");
302
+ }
253
303
 
254
- obs_set_output_source(0, scene_source); // 0 = video track
255
- return scene;
304
+ obs_set_output_source(0, scene_source); // 0 = video track
305
+ obs_scene_add(scene, video_source);
256
306
  }
257
307
 
258
- obs_source_t* ObsInterface::create_video_source() {
259
- blog(LOG_INFO, "Create display capture source");
308
+ void ObsInterface::configure_video_source() {
309
+ blog(LOG_INFO, "Create monitor capture source");
310
+
260
311
  // Create settings for monitor capture
261
312
  obs_data_t *monitor_settings = obs_data_create();
262
313
  obs_data_set_int(monitor_settings, "monitor", 0); // Monitor 0
263
314
  obs_data_set_bool(monitor_settings, "capture_cursor", true);
264
315
 
265
- obs_source_t *source = obs_source_create("monitor_capture", "Monitor", monitor_settings, NULL);
316
+ video_source = obs_source_create("monitor_capture", "video_source", monitor_settings, NULL);
266
317
  obs_data_release(monitor_settings);
267
318
 
268
- if (!source)
319
+ if (!video_source) {
320
+ blog(LOG_ERROR, "Failed to create video source!");
269
321
  throw std::runtime_error("Failed to create video source!");
270
-
271
- return source;
322
+ }
272
323
  }
273
324
 
274
325
  void call_jscb(Napi::Env env, Napi::Function cb, SignalData* sd) {
@@ -428,15 +479,15 @@ ObsInterface::ObsInterface(
428
479
  // Initialize OBS and load required modules.
429
480
  init_obs(pluginPath, dataPath);
430
481
 
431
- // Create the resources we rely on.
432
- output = create_output(recordingPath);
433
- scene = create_scene();
434
- video_source = create_video_source();
435
- obs_scene_add(scene, video_source);
436
-
437
- // Add the signal handler callback.
482
+ // Setup callback function.
438
483
  jscb = cb;
439
- create_signal_handlers(output);
484
+
485
+ // Create the resources we rely on.
486
+ configure_output(recordingPath);
487
+ configure_video_encoder();
488
+ configure_audio_encoder();
489
+ configure_video_source();
490
+ configure_scene();
440
491
  }
441
492
 
442
493
  ObsInterface::~ObsInterface() {
@@ -560,4 +611,20 @@ std::string ObsInterface::getLastRecording() {
560
611
 
561
612
  blog(LOG_INFO, "return path: %s", path.c_str());
562
613
  return path;
614
+ }
615
+
616
+ void ObsInterface::updateSourcePos(int x, int y, float scale) {
617
+ blog(LOG_INFO, "ObsInterface::moveSource called at (%d, %d)", x, y);
618
+ obs_sceneitem_t *item = obs_scene_find_source(scene, "video_source");
619
+
620
+ if (!item) {
621
+ blog(LOG_ERROR, "Did not find scene item for video source");
622
+ return;
623
+ }
624
+
625
+ struct vec2 pos = { (float)x, (float)y };
626
+ obs_sceneitem_set_pos(item, &pos);
627
+
628
+ struct vec2 scalep = { scale, scale };
629
+ obs_sceneitem_set_scale(item, &scalep);
563
630
  }
@@ -24,6 +24,8 @@ class ObsInterface {
24
24
  void stopRecording();
25
25
  std::string getLastRecording();
26
26
 
27
+ void updateSourcePos(int x, int y, float scale);
28
+
27
29
  void initPreview(HWND parent); // Must call this before showPreview to setup resources.
28
30
  void showPreview(int x, int y, int width, int height); // Also used for moving and resizing.
29
31
  void hidePreview();
@@ -65,7 +67,9 @@ class ObsInterface {
65
67
  void list_input_types();
66
68
  void list_output_types();
67
69
 
68
- obs_output_t* create_output(const std::string& recordingPath);
69
- obs_scene_t* create_scene();
70
- obs_source_t* create_video_source();
70
+ void configure_output(const std::string& recordingPath);
71
+ void configure_video_encoder();
72
+ void configure_audio_encoder();
73
+ void configure_scene();
74
+ void configure_video_source();
71
75
  };