noobs 0.0.66 → 0.0.84
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 +0 -0
- package/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/main.cpp +11 -0
- package/src/obs_interface.cpp +92 -25
- package/src/obs_interface.h +1 -0
package/dist/noobs.node
CHANGED
|
Binary file
|
package/index.d.ts
CHANGED
package/package.json
CHANGED
package/src/main.cpp
CHANGED
|
@@ -195,6 +195,16 @@ Napi::Value ObsHidePreview(const Napi::CallbackInfo& info) {
|
|
|
195
195
|
return info.Env().Undefined();
|
|
196
196
|
}
|
|
197
197
|
|
|
198
|
+
Napi::Value ObsGetPreviewScaleFactor(const Napi::CallbackInfo& info) {
|
|
199
|
+
if (!obs) {
|
|
200
|
+
blog(LOG_ERROR, "ObsGetPreviewScaleFactor called but obs is not initialized");
|
|
201
|
+
throw std::runtime_error("Obs not initialized");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
float scaleFactor = obs->getPreviewScaleFactor();
|
|
205
|
+
return Napi::Number::New(info.Env(), scaleFactor);
|
|
206
|
+
}
|
|
207
|
+
|
|
198
208
|
Napi::Value ObsCreateSource(const Napi::CallbackInfo& info) {
|
|
199
209
|
if (!obs) {
|
|
200
210
|
blog(LOG_ERROR, "ObsCreateSource called but obs is not initialized");
|
|
@@ -443,6 +453,7 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
|
443
453
|
exports.Set("InitPreview", Napi::Function::New(env, ObsInitPreview));
|
|
444
454
|
exports.Set("ShowPreview", Napi::Function::New(env, ObsShowPreview));
|
|
445
455
|
exports.Set("HidePreview", Napi::Function::New(env, ObsHidePreview));
|
|
456
|
+
exports.Set("GetPreviewScaleFactor", Napi::Function::New(env, ObsGetPreviewScaleFactor));
|
|
446
457
|
|
|
447
458
|
return exports;
|
|
448
459
|
}
|
package/src/obs_interface.cpp
CHANGED
|
@@ -124,6 +124,11 @@ void ObsInterface::reset_video() {
|
|
|
124
124
|
|
|
125
125
|
int success = obs_reset_video(&ovi);
|
|
126
126
|
|
|
127
|
+
obs_enter_graphics();
|
|
128
|
+
int dt = gs_get_device_type();
|
|
129
|
+
blog(LOG_INFO, "Device type = %d", dt); // should be 1 for D3D11
|
|
130
|
+
obs_leave_graphics();
|
|
131
|
+
|
|
127
132
|
if (success != OBS_VIDEO_SUCCESS) {
|
|
128
133
|
blog(LOG_ERROR, "Failed to reset video!");
|
|
129
134
|
throw std::runtime_error("Failed to reset video!");
|
|
@@ -163,7 +168,14 @@ void ObsInterface::init_obs(const std::string& pluginPath, const std::string& da
|
|
|
163
168
|
dp += '/';
|
|
164
169
|
}
|
|
165
170
|
|
|
166
|
-
|
|
171
|
+
// We need this before resetting video and audio to ensure the effects
|
|
172
|
+
// are available. The function is deprecated in libobs but it works for
|
|
173
|
+
// now.
|
|
174
|
+
obs_add_data_path(dp.c_str());
|
|
175
|
+
|
|
176
|
+
// This must come before loading modules to initialize D3D11.
|
|
177
|
+
reset_video();
|
|
178
|
+
reset_audio();
|
|
167
179
|
|
|
168
180
|
std::vector<std::string> modules = {
|
|
169
181
|
"obs-x264.dll",
|
|
@@ -185,9 +197,6 @@ void ObsInterface::init_obs(const std::string& pluginPath, const std::string& da
|
|
|
185
197
|
list_input_types();
|
|
186
198
|
list_output_types();
|
|
187
199
|
|
|
188
|
-
reset_video();
|
|
189
|
-
reset_audio();
|
|
190
|
-
|
|
191
200
|
blog(LOG_INFO, "Exit init_obs");
|
|
192
201
|
}
|
|
193
202
|
|
|
@@ -285,9 +294,9 @@ void ObsInterface::create_video_encoders() {
|
|
|
285
294
|
|
|
286
295
|
blog(LOG_INFO, "Set file video encoder settings");
|
|
287
296
|
obs_data_t* venc_settings = obs_data_create();
|
|
288
|
-
obs_data_set_string(venc_settings, "preset", "speed"); // Faster preset
|
|
297
|
+
// obs_data_set_string(venc_settings, "preset", "speed"); // Faster preset
|
|
289
298
|
obs_data_set_string(venc_settings, "rate_control", "CRF");
|
|
290
|
-
obs_data_set_int(venc_settings, "crf",
|
|
299
|
+
obs_data_set_int(venc_settings, "crf", 22);
|
|
291
300
|
obs_data_set_string(venc_settings, "profile", "main");
|
|
292
301
|
obs_data_set_int(venc_settings, "keyint_sec", 1); // Set keyframe interval to 1 second
|
|
293
302
|
|
|
@@ -513,6 +522,12 @@ bool draw_box(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
|
|
|
513
522
|
float width = obs_source_get_width(src) * scale.x;
|
|
514
523
|
float height = obs_source_get_height(src) * scale.y;
|
|
515
524
|
|
|
525
|
+
if (width <= 0 || height <= 0) {
|
|
526
|
+
// Don't want to call gs_draw_sprite with zero width or height.
|
|
527
|
+
// It is obviously nonsense and leads to log spam. Just return early.
|
|
528
|
+
return true;
|
|
529
|
+
}
|
|
530
|
+
|
|
516
531
|
// Draw rectangle around the source using the position and size
|
|
517
532
|
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID);
|
|
518
533
|
gs_eparam_t *color = gs_effect_get_param_by_name(solid, "color");
|
|
@@ -530,25 +545,25 @@ bool draw_box(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
|
|
|
530
545
|
// Top border
|
|
531
546
|
gs_matrix_push();
|
|
532
547
|
gs_matrix_translate3f(pos.x, pos.y, 0.0f);
|
|
533
|
-
gs_draw_sprite(nullptr, 0, width,
|
|
548
|
+
gs_draw_sprite(nullptr, 0, width, 4.0f);
|
|
534
549
|
gs_matrix_pop();
|
|
535
550
|
|
|
536
551
|
// Bottom border
|
|
537
552
|
gs_matrix_push();
|
|
538
|
-
gs_matrix_translate3f(pos.x, pos.y + height -
|
|
539
|
-
gs_draw_sprite(nullptr, 0, width,
|
|
553
|
+
gs_matrix_translate3f(pos.x, pos.y + height - 4.0f, 0.0f);
|
|
554
|
+
gs_draw_sprite(nullptr, 0, width, 4.0f);
|
|
540
555
|
gs_matrix_pop();
|
|
541
556
|
|
|
542
557
|
// Left border
|
|
543
558
|
gs_matrix_push();
|
|
544
559
|
gs_matrix_translate3f(pos.x, pos.y, 0.0f);
|
|
545
|
-
gs_draw_sprite(nullptr, 0,
|
|
560
|
+
gs_draw_sprite(nullptr, 0, 4.0f, height);
|
|
546
561
|
gs_matrix_pop();
|
|
547
562
|
|
|
548
563
|
// Right border
|
|
549
564
|
gs_matrix_push();
|
|
550
|
-
gs_matrix_translate3f(pos.x + width -
|
|
551
|
-
gs_draw_sprite(nullptr, 0,
|
|
565
|
+
gs_matrix_translate3f(pos.x + width - 4.0f, pos.y, 0.0f);
|
|
566
|
+
gs_draw_sprite(nullptr, 0, 4.0f, height);
|
|
552
567
|
gs_matrix_pop();
|
|
553
568
|
|
|
554
569
|
gs_matrix_pop();
|
|
@@ -560,18 +575,42 @@ bool draw_box(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
|
|
|
560
575
|
}
|
|
561
576
|
|
|
562
577
|
void draw_callback(void* data, uint32_t cx, uint32_t cy) {
|
|
563
|
-
|
|
564
|
-
|
|
578
|
+
obs_video_info ovi;
|
|
579
|
+
obs_get_video_info(&ovi);
|
|
580
|
+
|
|
581
|
+
float scaleX = float(cx) / float(ovi.base_width);
|
|
582
|
+
float scaleY = float(cy) / float(ovi.base_height);
|
|
583
|
+
|
|
584
|
+
float previewScale;
|
|
585
|
+
|
|
586
|
+
// Pick the limiting scale factor.
|
|
587
|
+
if (scaleX < scaleY) {
|
|
588
|
+
previewScale = scaleX;
|
|
589
|
+
} else {
|
|
590
|
+
previewScale = scaleY;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
int previewCX = int(previewScale * ovi.base_width);
|
|
594
|
+
int previewCY = int(previewScale * ovi.base_height);
|
|
595
|
+
int previewX = (cx - previewCX) / 2;
|
|
596
|
+
int previewY = (cy - previewCY) / 2;
|
|
597
|
+
|
|
598
|
+
gs_viewport_push();
|
|
599
|
+
gs_projection_push();
|
|
600
|
+
|
|
601
|
+
gs_ortho(0.0f, float(ovi.base_width), 0.0f, float(ovi.base_height), -100.0f, 100.0f);
|
|
602
|
+
gs_set_viewport(previewX, previewY, previewCX, previewCY);
|
|
565
603
|
|
|
566
|
-
//
|
|
567
|
-
|
|
568
|
-
gs_ortho(0.0f, float(cx), 0.0f, float(cy), -100.0f, 100.0f);
|
|
569
|
-
gs_set_viewport(0, 0, cx, cy);
|
|
604
|
+
// Renders the scene now the graphics context is setup.
|
|
605
|
+
obs_render_main_texture();
|
|
570
606
|
|
|
571
|
-
//
|
|
607
|
+
// Draw boxes around sources.
|
|
572
608
|
obs_scene_t* scene = obs_get_scene_by_name("WCR Scene");
|
|
573
609
|
obs_scene_enum_items(scene, draw_box, NULL);
|
|
574
610
|
obs_scene_release(scene);
|
|
611
|
+
|
|
612
|
+
gs_projection_pop();
|
|
613
|
+
gs_viewport_pop();
|
|
575
614
|
}
|
|
576
615
|
|
|
577
616
|
void ObsInterface::initPreview(HWND parent) {
|
|
@@ -632,13 +671,15 @@ void ObsInterface::showPreview(int x, int y, int width, int height) {
|
|
|
632
671
|
return;
|
|
633
672
|
}
|
|
634
673
|
|
|
674
|
+
blog(LOG_INFO, "Showing preview child window at (%d, %d) with size (%d x %d)", x, y, width, height);
|
|
675
|
+
|
|
635
676
|
// Resize and move the existing child window.
|
|
636
677
|
bool success = SetWindowPos(
|
|
637
678
|
preview_hwnd, // Handle to the child window
|
|
638
679
|
NULL, // No Z-order change
|
|
639
680
|
x, y, // New position (x, y)
|
|
640
681
|
width, height, // New size (width, height)
|
|
641
|
-
|
|
682
|
+
SWP_NOACTIVATE // Flags
|
|
642
683
|
);
|
|
643
684
|
|
|
644
685
|
if (!success) {
|
|
@@ -646,6 +687,10 @@ void ObsInterface::showPreview(int x, int y, int width, int height) {
|
|
|
646
687
|
return;
|
|
647
688
|
}
|
|
648
689
|
|
|
690
|
+
uint32_t w, h;
|
|
691
|
+
obs_display_size(display, &w, &h); // Get the display size to match the video context.
|
|
692
|
+
blog(LOG_INFO, "Current Display size set to (%d x %d)", w, h);
|
|
693
|
+
|
|
649
694
|
obs_display_resize(display, width, height);
|
|
650
695
|
ShowWindow(preview_hwnd, SW_SHOW);
|
|
651
696
|
obs_display_set_enabled(display, true);
|
|
@@ -662,6 +707,33 @@ void ObsInterface::hidePreview() {
|
|
|
662
707
|
obs_display_set_enabled(display, false);
|
|
663
708
|
}
|
|
664
709
|
|
|
710
|
+
float ObsInterface::getPreviewScaleFactor() {
|
|
711
|
+
if (!display) {
|
|
712
|
+
blog(LOG_WARNING, "Display not initialized");
|
|
713
|
+
return 1.0f; // Default scale
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
obs_video_info ovi;
|
|
717
|
+
obs_get_video_info(&ovi);
|
|
718
|
+
|
|
719
|
+
uint32_t width, height;
|
|
720
|
+
obs_display_size(display, &width, &height);
|
|
721
|
+
|
|
722
|
+
float scaleX = float(width) / float(ovi.base_width);
|
|
723
|
+
float scaleY = float(height) / float(ovi.base_height);
|
|
724
|
+
|
|
725
|
+
float previewScale;
|
|
726
|
+
|
|
727
|
+
// Pick the limiting scale factor.
|
|
728
|
+
if (scaleX < scaleY) {
|
|
729
|
+
previewScale = scaleX;
|
|
730
|
+
} else {
|
|
731
|
+
previewScale = scaleY;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
return previewScale;
|
|
735
|
+
}
|
|
736
|
+
|
|
665
737
|
ObsInterface::ObsInterface(
|
|
666
738
|
const std::string& pluginPath,
|
|
667
739
|
const std::string& logPath,
|
|
@@ -916,8 +988,6 @@ void ObsInterface::removeSourceFromScene(std::string name) {
|
|
|
916
988
|
|
|
917
989
|
void ObsInterface::getSourcePos(std::string name, vec2* pos, vec2* size, vec2* scale)
|
|
918
990
|
{
|
|
919
|
-
blog(LOG_INFO, "ObsInterface::getSourcePos called");
|
|
920
|
-
|
|
921
991
|
obs_source_t *src = obs_get_source_by_name(name.c_str());
|
|
922
992
|
obs_sceneitem_t *item = obs_scene_find_source(scene, name.c_str());
|
|
923
993
|
|
|
@@ -937,12 +1007,9 @@ void ObsInterface::getSourcePos(std::string name, vec2* pos, vec2* size, vec2* s
|
|
|
937
1007
|
// Pre-scaled sizes.
|
|
938
1008
|
size->x = obs_source_get_width(src);
|
|
939
1009
|
size->y = obs_source_get_height(src);
|
|
940
|
-
|
|
941
|
-
blog(LOG_INFO, "ObsInterface::getSourcePos exited");
|
|
942
1010
|
}
|
|
943
1011
|
|
|
944
1012
|
void ObsInterface::setSourcePos(std::string name, vec2* pos, vec2* scale) {
|
|
945
|
-
blog(LOG_INFO, "ObsInterface::moveSource called");
|
|
946
1013
|
obs_sceneitem_t *item = obs_scene_find_source(scene, name.c_str());
|
|
947
1014
|
|
|
948
1015
|
if (!item) {
|
package/src/obs_interface.h
CHANGED
|
@@ -40,6 +40,7 @@ class ObsInterface {
|
|
|
40
40
|
void initPreview(HWND parent); // Must call this before showPreview to setup resources.
|
|
41
41
|
void showPreview(int x, int y, int width, int height); // Also used for moving and resizing.
|
|
42
42
|
void hidePreview(); // Hide the preview display.
|
|
43
|
+
float getPreviewScaleFactor(); // Get the current scale factor of the preview.
|
|
43
44
|
|
|
44
45
|
std::vector<std::string> get_available_video_encoders();
|
|
45
46
|
|