noobs 0.0.32 → 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.
@@ -6,6 +6,12 @@
6
6
  #include "obs_interface.h"
7
7
  #include <vector>
8
8
  #include <thread>
9
+ #include <iostream>
10
+ #include <map>
11
+ #include <string>
12
+ #include <graphics/matrix4.h>
13
+ #include <graphics/vec4.h>
14
+ #include <util/platform.h>
9
15
 
10
16
  std::vector<std::string> ObsInterface::get_available_video_encoders()
11
17
  {
@@ -158,7 +164,14 @@ void ObsInterface::init_obs(const std::string& pluginPath, const std::string& da
158
164
  }
159
165
 
160
166
  obs_add_data_path(dp.c_str()); // This is deprecated in libobs but it works for now.
161
- std::vector<std::string> modules = { "obs-x264.dll", "obs-ffmpeg.dll", "win-capture.dll" };
167
+
168
+ std::vector<std::string> modules = {
169
+ "obs-x264.dll",
170
+ "obs-ffmpeg.dll",
171
+ "win-capture.dll", // Required for basically all forms of capture on Windows.
172
+ "image-source.dll", // Required for image sources.
173
+ "win-wasapi.dll" // Required for WASAPI audio input.
174
+ };
162
175
 
163
176
  for (const auto& module : modules) {
164
177
  std::string path = pluginPath + "/" + module;
@@ -178,33 +191,46 @@ void ObsInterface::init_obs(const std::string& pluginPath, const std::string& da
178
191
  blog(LOG_INFO, "Exit init_obs");
179
192
  }
180
193
 
181
- void ObsInterface::configure_output(const std::string& recordingPath) {
194
+ void ObsInterface::create_output(const std::string& recordingPath, bool buffering) {
182
195
  blog(LOG_INFO, "Create output");
183
196
 
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
197
  if (output) {
190
198
  blog(LOG_DEBUG, "Releasing output");
191
199
  obs_output_release(output);
192
200
  }
193
201
 
194
- output = obs_output_create("replay_buffer", "recording_output", NULL, NULL);
202
+ if (buffering) {
203
+ blog(LOG_INFO, "Creating replay buffer output");
204
+ output = obs_output_create("replay_buffer", "recording_output", NULL, NULL);
205
+ } else {
206
+ blog(LOG_INFO, "Creating file output");
207
+ output = obs_output_create("ffmpeg_muxer", "recording_output", NULL, NULL);
208
+ }
195
209
 
196
210
  if (!output) {
197
211
  blog(LOG_ERROR, "Failed to create output!");
198
212
  throw std::runtime_error("Failed to create output!");
199
213
  }
200
-
201
- blog(LOG_INFO, "Set output settings");
214
+
202
215
  obs_data_t *settings = obs_data_create();
203
- obs_data_set_int(settings, "max_time_sec", 60);
204
- obs_data_set_int(settings, "max_size_mb", 1024);
205
- obs_data_set_string(settings, "directory", recordingPath.c_str());
206
- obs_data_set_string(settings, "format", "%CCYY-%MM-%DD %hh-%mm-%ss");
207
- obs_data_set_string(settings, "extension", "mp4");
216
+
217
+ if (buffering) {
218
+ blog(LOG_INFO, "Set replay_buffer settings");
219
+ obs_data_set_int(settings, "max_time_sec", 60);
220
+ obs_data_set_int(settings, "max_size_mb", 1024);
221
+ obs_data_set_string(settings, "directory", recordingPath.c_str());
222
+ obs_data_set_string(settings, "format", "%CCYY-%MM-%DD %hh-%mm-%ss");
223
+ obs_data_set_string(settings, "extension", "mp4");
224
+ } else {
225
+ blog(LOG_INFO, "Set ffmpeg_muxer settings");
226
+ obs_data_set_string(settings, "extension", "mp4");
227
+ // Apparently need to specify the exact path for ffmpeg_muxer.
228
+ // TODO add something to auto generate this ?
229
+ obs_data_set_string(settings, "path", (recordingPath + "/noobs.mp4").c_str());
230
+ recording_path = recordingPath + "/noobs.mp4";
231
+ }
232
+
233
+ // Apply and release the settings.
208
234
  obs_output_update(output, settings);
209
235
  obs_data_release(settings);
210
236
 
@@ -212,6 +238,32 @@ void ObsInterface::configure_output(const std::string& recordingPath) {
212
238
  create_signal_handlers(output);
213
239
  }
214
240
 
241
+ void ObsInterface::updateRecordingDir(const std::string& recordingPath) {
242
+ blog(LOG_INFO, "Updating recording directory");
243
+
244
+ if (!output) {
245
+ blog(LOG_ERROR, "No output to update recording directory");
246
+ throw std::runtime_error("Output not initialized");
247
+ }
248
+
249
+ // check its not active
250
+ if (obs_output_active(output)) {
251
+ blog(LOG_ERROR, "Output is active, cannot update recording path");
252
+ throw std::runtime_error("Output is active, cannot update recording path");
253
+ }
254
+
255
+ obs_data_t *settings = obs_output_get_settings(output);
256
+
257
+ if (!settings) {
258
+ blog(LOG_ERROR, "Failed to get output settings");
259
+ throw std::runtime_error("Failed to get output settings");
260
+ }
261
+
262
+ obs_data_set_string(settings, "directory", recordingPath.c_str());
263
+ obs_output_update(output, settings);
264
+ obs_data_release(settings);
265
+ }
266
+
215
267
  void ObsInterface::configure_video_encoder() {
216
268
  blog(LOG_INFO, "Create video encoder");
217
269
 
@@ -278,15 +330,8 @@ void ObsInterface::configure_audio_encoder() {
278
330
  obs_encoder_set_audio(audio_encoder, obs_get_audio());
279
331
  }
280
332
 
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
-
333
+ void ObsInterface::create_scene() {
334
+ blog(LOG_INFO, "Create scene");
290
335
  scene = obs_scene_create("WCR Scene");
291
336
 
292
337
  if (!scene) {
@@ -302,24 +347,85 @@ void ObsInterface::configure_scene() {
302
347
  }
303
348
 
304
349
  obs_set_output_source(0, scene_source); // 0 = video track
305
- obs_scene_add(scene, video_source);
306
350
  }
307
351
 
308
- void ObsInterface::configure_video_source() {
309
- blog(LOG_INFO, "Create monitor capture source");
352
+ void ObsInterface::createSource(std::string name, std::string type) {
353
+ blog(LOG_INFO, "Create source: %s of type %s", name.c_str(), type.c_str());
354
+
355
+ obs_source_t *source = obs_source_create(
356
+ type.c_str(),
357
+ name.c_str(),
358
+ NULL, // No settings.
359
+ NULL // No hotkey data.
360
+ );
361
+
362
+ if (!source) {
363
+ blog(LOG_ERROR, "Failed to create source: %s", name.c_str());
364
+ throw std::runtime_error("Failed to create source!");
365
+ }
366
+ }
367
+
368
+ void ObsInterface::deleteSource(std::string name) {
369
+ blog(LOG_INFO, "Delete source: %s", name.c_str());
370
+ obs_source_t *source = obs_get_source_by_name(name.c_str());
371
+
372
+ if (!source) {
373
+ blog(LOG_WARNING, "Source not found: %s", name.c_str());
374
+ return; // Source not found, nothing to delete.
375
+ }
376
+
377
+ obs_source_release(source);
378
+ blog(LOG_INFO, "Source deleted: %s", name.c_str());
379
+ }
380
+
381
+ obs_data_t* ObsInterface::getSourceSettings(std::string name) {
382
+ blog(LOG_INFO, "Get source settings for: %s", name.c_str());
383
+ obs_source_t *source = obs_get_source_by_name(name.c_str());
384
+
385
+ if (!source) {
386
+ blog(LOG_ERROR, "Source not found: %s", name.c_str());
387
+ throw std::runtime_error("Source not found!");
388
+ }
389
+
390
+ obs_data_t *settings = obs_source_get_settings(source);
391
+
392
+ if (!settings) {
393
+ blog(LOG_ERROR, "Failed to get settings for source: %s", name.c_str());
394
+ throw std::runtime_error("Failed to get source settings!");
395
+ }
396
+
397
+ return settings;
398
+ }
399
+
400
+ void ObsInterface::setSourceSettings(std::string name, obs_data_t* settings) {
401
+ blog(LOG_INFO, "Set source settings for: %s", name.c_str());
402
+ obs_source_t *source = obs_get_source_by_name(name.c_str());
403
+
404
+ if (!source) {
405
+ blog(LOG_ERROR, "Source not found: %s", name.c_str());
406
+ throw std::runtime_error("Source not found!");
407
+ }
408
+
409
+ obs_source_update(source, settings);
410
+ }
411
+
412
+ obs_properties_t* ObsInterface::getSourceProperties(std::string name) {
413
+ blog(LOG_INFO, "Get source properties for: %s", name.c_str());
414
+ obs_source_t *source = obs_get_source_by_name(name.c_str());
310
415
 
311
- // Create settings for monitor capture
312
- obs_data_t *monitor_settings = obs_data_create();
313
- obs_data_set_int(monitor_settings, "monitor", 0); // Monitor 0
314
- obs_data_set_bool(monitor_settings, "capture_cursor", true);
416
+ if (!source) {
417
+ blog(LOG_ERROR, "Source not found: %s", name.c_str());
418
+ throw std::runtime_error("Source not found!");
419
+ }
315
420
 
316
- video_source = obs_source_create("monitor_capture", "video_source", monitor_settings, NULL);
317
- obs_data_release(monitor_settings);
421
+ obs_properties_t *props = obs_source_properties(source);
318
422
 
319
- if (!video_source) {
320
- blog(LOG_ERROR, "Failed to create video source!");
321
- throw std::runtime_error("Failed to create video source!");
423
+ if (!props) {
424
+ blog(LOG_ERROR, "Failed to get properties for source: %s", name.c_str());
425
+ throw std::runtime_error("Failed to get source properties!");
322
426
  }
427
+
428
+ return props;
323
429
  }
324
430
 
325
431
  void call_jscb(Napi::Env env, Napi::Function cb, SignalData* sd) {
@@ -374,8 +480,84 @@ void ObsInterface::create_signal_handlers(obs_output_t *output) {
374
480
  signal_handler_connect(sh, "saved", output_signal_handler_saved, this);
375
481
  }
376
482
 
483
+ bool draw_box(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
484
+ // Get the item position and size
485
+ vec2 pos; vec2 scale;
486
+
487
+ obs_sceneitem_get_pos(item, &pos);
488
+ obs_sceneitem_get_scale(item, &scale);
489
+
490
+ obs_source_t *src = obs_sceneitem_get_source(item);
491
+ uint32_t sizex = obs_source_get_width(src);
492
+ uint32_t sizey = obs_source_get_height(src);
493
+
494
+ // Calculate actual size with scaling
495
+ float width = sizex * scale.x;
496
+ float height = sizey * scale.y;
497
+
498
+ // Draw rectangle around the source using the position and size
499
+ gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID);
500
+ gs_eparam_t *color = gs_effect_get_param_by_name(solid, "color");
501
+ gs_technique_t *tech = gs_effect_get_technique(solid, "Solid");
502
+
503
+ vec4 col = {0.733f, 0.267f, 0.125f, 1.0f}; // #BB4420
504
+ gs_effect_set_vec4(color, &col);
505
+
506
+ gs_technique_begin(tech);
507
+ gs_technique_begin_pass(tech, 0);
508
+
509
+ gs_matrix_push();
510
+ gs_matrix_identity();
511
+
512
+ // Top border
513
+ gs_matrix_push();
514
+ gs_matrix_translate3f(pos.x, pos.y, 0.0f);
515
+ //gs_matrix_scale3f(width, 1.0f, 1.0f);
516
+ gs_draw_sprite(nullptr, 0, width, 1.0f);
517
+ gs_matrix_pop();
518
+
519
+ // Bottom border
520
+ gs_matrix_push();
521
+ gs_matrix_translate3f(pos.x, pos.y + height - 1.0f, 0.0f);
522
+ // gs_matrix_scale3f(width, 1.0f, 1.0f);
523
+ gs_draw_sprite(nullptr, 0, width, 1.0f);
524
+ gs_matrix_pop();
525
+
526
+ // Left border
527
+ gs_matrix_push();
528
+ gs_matrix_translate3f(pos.x, pos.y, 0.0f);
529
+ // gs_matrix_scale3f(1.0f, height, 1.0f);
530
+ gs_draw_sprite(nullptr, 0, 1.0f, height);
531
+ gs_matrix_pop();
532
+
533
+ // Right border
534
+ gs_matrix_push();
535
+ gs_matrix_translate3f(pos.x + width - 1.0f, pos.y, 0.0f);
536
+ // gs_matrix_scale3f(1.0f, height, 1.0f);
537
+ gs_draw_sprite(nullptr, 0, 1.0f, height);
538
+ gs_matrix_pop();
539
+
540
+ gs_matrix_pop();
541
+
542
+ gs_technique_end_pass(tech);
543
+ gs_technique_end(tech);
544
+
545
+ return true;
546
+ }
547
+
377
548
  void draw_callback(void* data, uint32_t cx, uint32_t cy) {
549
+ // Initially, draw the OBS scene texture
378
550
  obs_render_main_texture();
551
+
552
+ // This is some AI code that would draw a rectangle (and works).
553
+ // Set projection and viewport
554
+ gs_ortho(0.0f, float(cx), 0.0f, float(cy), -100.0f, 100.0f);
555
+ gs_set_viewport(0, 0, cx, cy);
556
+
557
+ // This was me trying to understand what OSN does.
558
+ obs_scene_t* scene = obs_get_scene_by_name("WCR Scene");
559
+ obs_scene_enum_items(scene, draw_box, NULL);
560
+ obs_scene_release(scene);
379
561
  }
380
562
 
381
563
  void ObsInterface::initPreview(HWND parent) {
@@ -470,7 +652,8 @@ ObsInterface::ObsInterface(
470
652
  const std::string& logPath,
471
653
  const std::string& dataPath,
472
654
  const std::string& recordingPath,
473
- Napi::ThreadSafeFunction cb
655
+ Napi::ThreadSafeFunction cb,
656
+ bool buffering
474
657
  ) {
475
658
  // Setup logs first so we have logs for the initialization.
476
659
  base_set_log_handler(log_handler, (void*)logPath.c_str());
@@ -483,11 +666,11 @@ ObsInterface::ObsInterface(
483
666
  jscb = cb;
484
667
 
485
668
  // Create the resources we rely on.
486
- configure_output(recordingPath);
669
+ create_output(recordingPath, buffering);
670
+ create_scene();
671
+
487
672
  configure_video_encoder();
488
673
  configure_audio_encoder();
489
- configure_video_source();
490
- configure_scene();
491
674
  }
492
675
 
493
676
  ObsInterface::~ObsInterface() {
@@ -557,26 +740,52 @@ void ObsInterface::startBuffering() {
557
740
 
558
741
  void ObsInterface::startRecording(int offset) {
559
742
  blog(LOG_INFO, "ObsInterface::startRecording enter");
560
- bool is_active = obs_output_active(output);
561
743
 
562
- if (!is_active) {
563
- blog(LOG_ERROR, "Buffer is not active");
564
- throw std::runtime_error("Buffer is not active");
565
- }
744
+ const char* type = obs_output_get_id(output);
566
745
 
567
- blog(LOG_INFO, "calling save proc handler");
568
- calldata cd;
569
- calldata_init(&cd);
570
- calldata_set_int(&cd, "offset_seconds", offset);
571
- proc_handler_t *ph = obs_output_get_proc_handler(output);
572
- bool success = proc_handler_call(ph, "convert", &cd);
573
- calldata_free(&cd);
746
+ if (strcmp(type, "replay_buffer") == 0) {
747
+ bool is_active = obs_output_active(output);
574
748
 
575
- if (!success) {
576
- throw std::runtime_error("Failed to call convert procedure handler");
749
+ if (!is_active) {
750
+ blog(LOG_WARNING, "Buffer is not active");
751
+ throw std::runtime_error("Buffer is not active");
752
+ }
753
+
754
+ blog(LOG_INFO, "calling save proc handler");
755
+ calldata cd;
756
+ calldata_init(&cd);
757
+ calldata_set_int(&cd, "offset_seconds", offset);
758
+ proc_handler_t *ph = obs_output_get_proc_handler(output);
759
+ bool success = proc_handler_call(ph, "convert", &cd);
760
+ calldata_free(&cd);
761
+
762
+ if (!success) {
763
+ throw std::runtime_error("Failed to call convert procedure handler");
764
+ }
765
+ } else if (strcmp(type, "ffmpeg_muxer") == 0) {
766
+ blog(LOG_INFO, "Starting ffmpeg_muxer output");
767
+
768
+ bool is_active = obs_output_active(output);
769
+
770
+ if (is_active) {
771
+ blog(LOG_WARNING, "Output already active");
772
+ return;
773
+ }
774
+
775
+ blog(LOG_WARNING, "Call start");
776
+ bool success = obs_output_start(output);
777
+
778
+ if (!success) {
779
+ const char *err = obs_output_get_last_error(output);
780
+ blog(LOG_ERROR, "Failed to start recording: %s", err ? err : "Unknown error");
781
+ throw std::runtime_error("Failed to start recording");
782
+ }
783
+ } else {
784
+ blog(LOG_ERROR, "Unknown output type: %s", type);
785
+ throw std::runtime_error("Unknown output type!");
577
786
  }
578
787
 
579
- blog(LOG_INFO, "ObsInterface::startRecording exit");
788
+ blog(LOG_INFO, "ObsInterface::startRecording exit");
580
789
  }
581
790
 
582
791
  void ObsInterface::stopRecording() {
@@ -597,10 +806,26 @@ std::string ObsInterface::getLastRecording() {
597
806
  calldata cd;
598
807
  calldata_init(&cd);
599
808
  proc_handler_t *ph = obs_output_get_proc_handler(output);
600
- bool success = proc_handler_call(ph, "get_last_replay", &cd);
809
+
810
+ const char* type = obs_output_get_id(output);
811
+
812
+
813
+
814
+ if (strcmp(type, "ffmpeg_muxer") == 0) {
815
+ return recording_path;
816
+ }
817
+
818
+ bool success;
819
+
820
+ if (strcmp(type, "replay_buffer") != 0) {
821
+ blog(LOG_ERROR, "Unknown output type: %s", type);
822
+ throw std::runtime_error("Unknown output type!");
823
+ }
601
824
 
602
825
  if (!success) {
603
- blog(LOG_ERROR, "Failed to call get_last_replay procedure handler");
826
+ blog(LOG_ERROR, "Failed to call procedure handler");
827
+ const char *err = obs_output_get_last_error(output);
828
+ blog(LOG_ERROR, "%s", err ? err : "Unknown error");
604
829
  calldata_free(&cd);
605
830
  return "";
606
831
  }
@@ -613,6 +838,43 @@ std::string ObsInterface::getLastRecording() {
613
838
  return path;
614
839
  }
615
840
 
841
+ void ObsInterface::addSourceToScene(std::string name) {
842
+ blog(LOG_INFO, "ObsInterface::addSourceToScene called for source: %s", name.c_str());
843
+
844
+ obs_source_t *src = obs_get_source_by_name(name.c_str());
845
+
846
+ if (!src) {
847
+ blog(LOG_WARNING, "Did not find source for video source: %s", name.c_str());
848
+ return;
849
+ }
850
+
851
+ // TODO refuse to add twice?
852
+
853
+ obs_sceneitem_t *item = obs_scene_add(scene, src);
854
+
855
+ if (!item) {
856
+ blog(LOG_ERROR, "Failed to add source to scene: %s", name.c_str());
857
+ obs_source_release(src);
858
+ return;
859
+ }
860
+
861
+ blog(LOG_INFO, "ObsInterface::addSourceToScene exited");
862
+ }
863
+
864
+ void ObsInterface::removeSourceFromScene(std::string name) {
865
+ blog(LOG_INFO, "ObsInterface::removeSourceFromScene called for source: %s", name.c_str());
866
+
867
+ obs_sceneitem_t *item = obs_scene_find_source(scene, name.c_str());
868
+
869
+ if (!item) {
870
+ blog(LOG_WARNING, "Did not find scene item for video source: %s", name.c_str());
871
+ return;
872
+ }
873
+
874
+ obs_sceneitem_remove(item);
875
+ blog(LOG_INFO, "ObsInterface::removeSourceFromScene exited");
876
+ }
877
+
616
878
  void ObsInterface::getSourcePos(std::string name, vec2* pos, vec2* size, vec2* scale)
617
879
  {
618
880
  blog(LOG_INFO, "ObsInterface::getSourcePos called");
@@ -621,12 +883,12 @@ void ObsInterface::getSourcePos(std::string name, vec2* pos, vec2* size, vec2* s
621
883
  obs_sceneitem_t *item = obs_scene_find_source(scene, name.c_str());
622
884
 
623
885
  if (!src) {
624
- blog(LOG_ERROR, "Did not find source for video ");
886
+ blog(LOG_WARNING, "Did not find source for video source: %s", name);
625
887
  return;
626
888
  }
627
889
 
628
890
  if (!item) {
629
- blog(LOG_ERROR, "Did not find scene item for video source");
891
+ blog(LOG_WARNING, "Did not find scene item for video source: %s", name);
630
892
  return;
631
893
  }
632
894
 
@@ -645,7 +907,7 @@ void ObsInterface::setSourcePos(std::string name, vec2* pos, vec2* scale) {
645
907
  obs_sceneitem_t *item = obs_scene_find_source(scene, name.c_str());
646
908
 
647
909
  if (!item) {
648
- blog(LOG_ERROR, "Did not find scene item for video source");
910
+ blog(LOG_WARNING, "Did not find scene item for video source: %s", name);
649
911
  return;
650
912
  }
651
913
 
@@ -10,26 +10,36 @@ struct SignalData {
10
10
  class ObsInterface {
11
11
  public:
12
12
  ObsInterface(
13
- const std::string& pluginPath, // where to look for plugins
14
- const std::string& logPath, // where to write logs to
15
- const std::string& dataPath, // where to look for effects
16
- const std::string& recordingPath, // where to save recordings
17
- Napi::ThreadSafeFunction cb // JavaScript callback
13
+ const std::string& pluginPath, // Where to look for plugins
14
+ const std::string& logPath, // Where to write logs to
15
+ const std::string& dataPath, // Where to look for effects
16
+ const std::string& recordingPath, // Where to save recordings
17
+ Napi::ThreadSafeFunction cb, // JavaScript callback
18
+ bool buffering // Whether to enable buffering the recording in memory
18
19
  );
19
20
 
20
21
  ~ObsInterface();
21
22
 
22
- void startBuffering();
23
- void startRecording(int offset);
24
- void stopRecording();
25
- std::string getLastRecording();
23
+ void startBuffering(); // Start buffering to memory.
24
+ void startRecording(int offset); // Convert the active buffered recording to a real one.
25
+ void stopRecording(); // Stop the recording.
26
+ std::string getLastRecording(); // Get the last recorded file path.
27
+ void updateRecordingDir(const std::string& recordingPath); // Output must not be active when calling this.
26
28
 
29
+ void createSource(std::string name, std::string type); // Create a new source
30
+ void deleteSource(std::string name); // Release a source.
31
+ obs_data_t* getSourceSettings(std::string name); // Get the current settings.
32
+ void setSourceSettings(std::string name, obs_data_t* settings); // Set settings.
33
+ obs_properties_t* getSourceProperties(std::string name); // Get the settings schema.
34
+
35
+ void addSourceToScene(std::string name); // Add source to scene.
36
+ void removeSourceFromScene(std::string name); // Remove source from scene.
27
37
  void getSourcePos(std::string name, vec2* pos, vec2* size, vec2* scale); // Size is returned to allow clients to calculate scale.
28
38
  void setSourcePos(std::string name, vec2* pos, vec2* scale); // Size does not get set here because it's set by the source itself.
29
39
 
30
40
  void initPreview(HWND parent); // Must call this before showPreview to setup resources.
31
41
  void showPreview(int x, int y, int width, int height); // Also used for moving and resizing.
32
- void hidePreview();
42
+ void hidePreview(); // Hide the preview display.
33
43
 
34
44
  std::vector<std::string> get_available_video_encoders();
35
45
 
@@ -50,6 +60,7 @@ class ObsInterface {
50
60
  obs_display_t *display = nullptr;
51
61
  HWND preview_hwnd = nullptr; // window handle for scene preview
52
62
  Napi::ThreadSafeFunction jscb; // javascript callback
63
+ std::string recording_path = "";
53
64
 
54
65
  void init_obs(const std::string& pluginPath, const std::string& dataPath);
55
66
  void reset_video();
@@ -68,9 +79,9 @@ class ObsInterface {
68
79
  void list_input_types();
69
80
  void list_output_types();
70
81
 
71
- void configure_output(const std::string& recordingPath);
82
+ void create_scene();
83
+ void create_output(const std::string& recordingPath, bool buffering);
84
+
72
85
  void configure_video_encoder();
73
86
  void configure_audio_encoder();
74
- void configure_scene();
75
- void configure_video_source();
76
87
  };