noobs 0.0.6

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.
Files changed (185) hide show
  1. package/COPYING +339 -0
  2. package/README.md +46 -0
  3. package/bin/64bit/obs.lib +0 -0
  4. package/binding.gyp +23 -0
  5. package/dist/bin/Qt6Core.dll +0 -0
  6. package/dist/bin/Qt6Gui.dll +0 -0
  7. package/dist/bin/Qt6Network.dll +0 -0
  8. package/dist/bin/Qt6Svg.dll +0 -0
  9. package/dist/bin/Qt6Widgets.dll +0 -0
  10. package/dist/bin/Qt6Xml.dll +0 -0
  11. package/dist/bin/avcodec-61.dll +0 -0
  12. package/dist/bin/avdevice-61.dll +0 -0
  13. package/dist/bin/avfilter-10.dll +0 -0
  14. package/dist/bin/avformat-61.dll +0 -0
  15. package/dist/bin/avutil-59.dll +0 -0
  16. package/dist/bin/datachannel.dll +0 -0
  17. package/dist/bin/libcurl.dll +0 -0
  18. package/dist/bin/libobs-d3d11.dll +0 -0
  19. package/dist/bin/libobs-opengl.dll +0 -0
  20. package/dist/bin/libobs-winrt.dll +0 -0
  21. package/dist/bin/librist.dll +0 -0
  22. package/dist/bin/libx264-164.dll +0 -0
  23. package/dist/bin/lua51.dll +0 -0
  24. package/dist/bin/obs-amf-test.exe +0 -0
  25. package/dist/bin/obs-ffmpeg-mux.exe +0 -0
  26. package/dist/bin/obs-frontend-api.dll +0 -0
  27. package/dist/bin/obs-scripting.dll +0 -0
  28. package/dist/bin/obs.dll +0 -0
  29. package/dist/bin/srt.dll +0 -0
  30. package/dist/bin/swresample-5.dll +0 -0
  31. package/dist/bin/swscale-8.dll +0 -0
  32. package/dist/bin/w32-pthreads.dll +0 -0
  33. package/dist/bin/zlib.dll +0 -0
  34. package/dist/effects/area.effect +250 -0
  35. package/dist/effects/bicubic_scale.effect +236 -0
  36. package/dist/effects/bilinear_lowres_scale.effect +123 -0
  37. package/dist/effects/color.effect +172 -0
  38. package/dist/effects/default.effect +254 -0
  39. package/dist/effects/default_rect.effect +84 -0
  40. package/dist/effects/deinterlace_base.effect +325 -0
  41. package/dist/effects/deinterlace_blend.effect +21 -0
  42. package/dist/effects/deinterlace_blend_2x.effect +21 -0
  43. package/dist/effects/deinterlace_discard.effect +21 -0
  44. package/dist/effects/deinterlace_discard_2x.effect +21 -0
  45. package/dist/effects/deinterlace_linear.effect +21 -0
  46. package/dist/effects/deinterlace_linear_2x.effect +21 -0
  47. package/dist/effects/deinterlace_yadif.effect +21 -0
  48. package/dist/effects/deinterlace_yadif_2x.effect +21 -0
  49. package/dist/effects/format_conversion.effect +1823 -0
  50. package/dist/effects/lanczos_scale.effect +292 -0
  51. package/dist/effects/opaque.effect +159 -0
  52. package/dist/effects/premultiplied_alpha.effect +38 -0
  53. package/dist/effects/repeat.effect +36 -0
  54. package/dist/effects/solid.effect +80 -0
  55. package/dist/noobs.node +0 -0
  56. package/dist/plugins/obs-ffmpeg.dll +0 -0
  57. package/dist/plugins/obs-x264.dll +0 -0
  58. package/dist/plugins/win-capture.dll +0 -0
  59. package/include/audio-monitoring/osx/mac-helpers.h +13 -0
  60. package/include/audio-monitoring/pulse/pulseaudio-wrapper.h +212 -0
  61. package/include/audio-monitoring/win32/wasapi-output.h +22 -0
  62. package/include/callback/calldata.h +195 -0
  63. package/include/callback/decl.h +61 -0
  64. package/include/callback/proc.h +52 -0
  65. package/include/callback/signal.h +73 -0
  66. package/include/graphics/axisang.h +65 -0
  67. package/include/graphics/bounds.h +108 -0
  68. package/include/graphics/device-exports.h +177 -0
  69. package/include/graphics/effect-parser.h +290 -0
  70. package/include/graphics/effect.h +190 -0
  71. package/include/graphics/graphics-internal.h +335 -0
  72. package/include/graphics/graphics.h +1024 -0
  73. package/include/graphics/half.h +100 -0
  74. package/include/graphics/image-file.h +124 -0
  75. package/include/graphics/input.h +34 -0
  76. package/include/graphics/libnsgif/libnsgif.h +142 -0
  77. package/include/graphics/math-defs.h +45 -0
  78. package/include/graphics/math-extra.h +61 -0
  79. package/include/graphics/matrix3.h +98 -0
  80. package/include/graphics/matrix4.h +102 -0
  81. package/include/graphics/plane.h +85 -0
  82. package/include/graphics/quat.h +170 -0
  83. package/include/graphics/shader-parser.h +273 -0
  84. package/include/graphics/srgb.h +177 -0
  85. package/include/graphics/vec2.h +148 -0
  86. package/include/graphics/vec3.h +224 -0
  87. package/include/graphics/vec4.h +241 -0
  88. package/include/media-io/audio-io.h +228 -0
  89. package/include/media-io/audio-math.h +43 -0
  90. package/include/media-io/audio-resampler.h +44 -0
  91. package/include/media-io/format-conversion.h +50 -0
  92. package/include/media-io/frame-rate.h +29 -0
  93. package/include/media-io/media-io-defs.h +20 -0
  94. package/include/media-io/media-remux.h +37 -0
  95. package/include/media-io/video-frame.h +64 -0
  96. package/include/media-io/video-io.h +338 -0
  97. package/include/media-io/video-scaler.h +43 -0
  98. package/include/obs-audio-controls.h +250 -0
  99. package/include/obs-av1.h +47 -0
  100. package/include/obs-avc.h +55 -0
  101. package/include/obs-config.h +52 -0
  102. package/include/obs-data.h +311 -0
  103. package/include/obs-defs.h +52 -0
  104. package/include/obs-encoder.h +361 -0
  105. package/include/obs-ffmpeg-compat.h +13 -0
  106. package/include/obs-hevc.h +81 -0
  107. package/include/obs-hotkey.h +271 -0
  108. package/include/obs-hotkeys.h +653 -0
  109. package/include/obs-interaction.h +56 -0
  110. package/include/obs-internal.h +1459 -0
  111. package/include/obs-missing-files.h +53 -0
  112. package/include/obs-module.h +181 -0
  113. package/include/obs-nal.h +37 -0
  114. package/include/obs-nix-platform.h +53 -0
  115. package/include/obs-nix-wayland.h +24 -0
  116. package/include/obs-nix-x11.h +22 -0
  117. package/include/obs-nix.h +42 -0
  118. package/include/obs-output.h +96 -0
  119. package/include/obs-properties.h +364 -0
  120. package/include/obs-scene.h +127 -0
  121. package/include/obs-service.h +115 -0
  122. package/include/obs-source.h +568 -0
  123. package/include/obs.h +2608 -0
  124. package/include/obsconfig.h +13 -0
  125. package/include/obsversion.h +5 -0
  126. package/include/util/apple/cfstring-utils.h +16 -0
  127. package/include/util/array-serializer.h +37 -0
  128. package/include/util/base.h +97 -0
  129. package/include/util/bitstream.h +28 -0
  130. package/include/util/bmem.h +94 -0
  131. package/include/util/buffered-file-serializer.h +32 -0
  132. package/include/util/c99defs.h +75 -0
  133. package/include/util/cf-lexer.h +199 -0
  134. package/include/util/cf-parser.h +281 -0
  135. package/include/util/circlebuf.h +319 -0
  136. package/include/util/config-file.h +103 -0
  137. package/include/util/crc32.h +29 -0
  138. package/include/util/curl/curl-helper.h +35 -0
  139. package/include/util/darray.h +606 -0
  140. package/include/util/deque.h +319 -0
  141. package/include/util/dstr.h +320 -0
  142. package/include/util/file-serializer.h +34 -0
  143. package/include/util/lexer.h +273 -0
  144. package/include/util/pipe.h +52 -0
  145. package/include/util/platform.h +223 -0
  146. package/include/util/profiler.h +97 -0
  147. package/include/util/serializer.h +158 -0
  148. package/include/util/simde/check.h +285 -0
  149. package/include/util/simde/debug-trap.h +117 -0
  150. package/include/util/simde/hedley.h +2123 -0
  151. package/include/util/simde/simde-align.h +481 -0
  152. package/include/util/simde/simde-arch.h +537 -0
  153. package/include/util/simde/simde-common.h +918 -0
  154. package/include/util/simde/simde-constify.h +925 -0
  155. package/include/util/simde/simde-detect-clang.h +114 -0
  156. package/include/util/simde/simde-diagnostic.h +447 -0
  157. package/include/util/simde/simde-features.h +550 -0
  158. package/include/util/simde/simde-math.h +1858 -0
  159. package/include/util/simde/x86/mmx.h +2456 -0
  160. package/include/util/simde/x86/sse.h +4479 -0
  161. package/include/util/simde/x86/sse2.h +7549 -0
  162. package/include/util/source-profiler.h +66 -0
  163. package/include/util/sse-intrin.h +32 -0
  164. package/include/util/task.h +22 -0
  165. package/include/util/text-lookup.h +45 -0
  166. package/include/util/threading-posix.h +77 -0
  167. package/include/util/threading-windows.h +142 -0
  168. package/include/util/threading.h +103 -0
  169. package/include/util/utf8.h +35 -0
  170. package/include/util/uthash.h +34 -0
  171. package/include/util/util_uint128.h +108 -0
  172. package/include/util/util_uint64.h +34 -0
  173. package/include/util/windows/device-enum.h +14 -0
  174. package/include/util/windows/obfuscate.h +16 -0
  175. package/include/util/windows/win-registry.h +37 -0
  176. package/include/util/windows/win-version.h +57 -0
  177. package/include/util/windows/window-helpers.h +47 -0
  178. package/index.d.ts +38 -0
  179. package/index.js +8 -0
  180. package/package.json +31 -0
  181. package/src/main.cpp +321 -0
  182. package/src/obs_interface.cpp +605 -0
  183. package/src/obs_interface.h +74 -0
  184. package/src/utils.cpp +80 -0
  185. package/src/utils.h +3 -0
@@ -0,0 +1,34 @@
1
+ /*
2
+ * Copyright (c) 2020 Hans Petter Selasky <hps@selasky.org>
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #pragma once
18
+
19
+ #if defined(_MSC_VER) && defined(_M_X64)
20
+ #include <intrin.h>
21
+ #endif
22
+
23
+ static inline uint64_t util_mul_div64(uint64_t num, uint64_t mul, uint64_t div)
24
+ {
25
+ #if defined(_MSC_VER) && defined(_M_X64) && (_MSC_VER >= 1920)
26
+ unsigned __int64 high;
27
+ const unsigned __int64 low = _umul128(num, mul, &high);
28
+ unsigned __int64 rem;
29
+ return _udiv128(high, low, div, &rem);
30
+ #else
31
+ const uint64_t rem = num % div;
32
+ return (num / div) * mul + (rem * mul) / div;
33
+ #endif
34
+ }
@@ -0,0 +1,14 @@
1
+ #pragma once
2
+
3
+ #include "../c99defs.h"
4
+
5
+ #ifdef __cplusplus
6
+ extern "C" {
7
+ #endif
8
+
9
+ typedef bool (*device_luid_cb)(void *param, uint32_t idx, uint64_t luid);
10
+ EXPORT void enum_graphics_device_luids(device_luid_cb device_luid, void *param);
11
+
12
+ #ifdef __cplusplus
13
+ }
14
+ #endif
@@ -0,0 +1,16 @@
1
+ #pragma once
2
+
3
+ #include "../c99defs.h"
4
+ #include <Windows.h>
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ /* this is a workaround to A/Vs going crazy whenever certain functions (such as
11
+ * OpenProcess) are used */
12
+ void *ms_get_obfuscated_func(HMODULE module, const char *str, uint64_t val);
13
+
14
+ #ifdef __cplusplus
15
+ }
16
+ #endif
@@ -0,0 +1,37 @@
1
+ /*
2
+ * Copyright (c) 2023 Lain Bailey <lain@obsproject.com>
3
+ * Copyright (c) 2017 Ryan Foster <RytoEX@gmail.com>
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+
18
+ #pragma once
19
+
20
+ #include <windows.h>
21
+ #include "../c99defs.h"
22
+
23
+ #ifdef __cplusplus
24
+ extern "C" {
25
+ #endif
26
+
27
+ struct reg_dword {
28
+ LSTATUS status;
29
+ DWORD size;
30
+ DWORD return_value;
31
+ };
32
+
33
+ EXPORT void get_reg_dword(HKEY hkey, LPCWSTR sub_key, LPCWSTR value_name, struct reg_dword *info);
34
+
35
+ #ifdef __cplusplus
36
+ }
37
+ #endif
@@ -0,0 +1,57 @@
1
+ /*
2
+ * Copyright (c) 2023 Lain Bailey <lain@obsproject.com>
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #pragma once
18
+
19
+ #include "../c99defs.h"
20
+
21
+ #ifdef __cplusplus
22
+ extern "C" {
23
+ #endif
24
+
25
+ struct win_version_info {
26
+ int major;
27
+ int minor;
28
+ int build;
29
+ int revis;
30
+ };
31
+
32
+ static inline int win_version_compare(const struct win_version_info *dst, const struct win_version_info *src)
33
+ {
34
+ if (dst->major > src->major)
35
+ return 1;
36
+ if (dst->major == src->major) {
37
+ if (dst->minor > src->minor)
38
+ return 1;
39
+ if (dst->minor == src->minor) {
40
+ if (dst->build > src->build)
41
+ return 1;
42
+ if (dst->build == src->build)
43
+ return 0;
44
+ }
45
+ }
46
+ return -1;
47
+ }
48
+
49
+ EXPORT bool is_64_bit_windows(void);
50
+ EXPORT bool is_arm64_windows(void);
51
+ EXPORT bool get_dll_ver(const wchar_t *lib, struct win_version_info *info);
52
+ EXPORT void get_win_ver(struct win_version_info *info);
53
+ EXPORT uint32_t get_win_ver_int(void);
54
+
55
+ #ifdef __cplusplus
56
+ }
57
+ #endif
@@ -0,0 +1,47 @@
1
+ #pragma once
2
+
3
+ #include <obs-properties.h>
4
+ #include <util/c99defs.h>
5
+ #include <util/dstr.h>
6
+ #include <Windows.h>
7
+
8
+ #ifdef __cplusplus
9
+ extern "C" {
10
+ #endif
11
+
12
+ enum window_priority {
13
+ WINDOW_PRIORITY_CLASS,
14
+ WINDOW_PRIORITY_TITLE,
15
+ WINDOW_PRIORITY_EXE,
16
+ };
17
+
18
+ enum window_search_mode {
19
+ INCLUDE_MINIMIZED,
20
+ EXCLUDE_MINIMIZED,
21
+ };
22
+
23
+ EXPORT bool ms_get_window_exe(struct dstr *name, HWND window);
24
+ EXPORT void ms_get_window_title(struct dstr *name, HWND hwnd);
25
+ EXPORT void ms_get_window_class(struct dstr *window_class, HWND hwnd);
26
+ EXPORT bool ms_is_uwp_window(HWND hwnd);
27
+ EXPORT HWND ms_get_uwp_actual_window(HWND parent);
28
+
29
+ typedef bool (*add_window_cb)(const char *title, const char *window_class, const char *exe);
30
+
31
+ EXPORT void ms_fill_window_list(obs_property_t *p, enum window_search_mode mode, add_window_cb callback);
32
+
33
+ EXPORT void ms_build_window_strings(const char *str, char **window_class, char **title, char **exe);
34
+
35
+ EXPORT bool ms_check_window_property_setting(obs_properties_t *ppts, obs_property_t *p, obs_data_t *settings,
36
+ const char *val, size_t idx);
37
+
38
+ EXPORT void ms_build_window_strings(const char *str, char **window_class, char **title, char **exe);
39
+
40
+ EXPORT HWND ms_find_window(enum window_search_mode mode, enum window_priority priority, const char *window_class,
41
+ const char *title, const char *exe);
42
+ EXPORT HWND ms_find_window_top_level(enum window_search_mode mode, enum window_priority priority,
43
+ const char *window_class, const char *title, const char *exe);
44
+
45
+ #ifdef __cplusplus
46
+ }
47
+ #endif
package/index.d.ts ADDED
@@ -0,0 +1,38 @@
1
+ interface ProcessInfo {
2
+ name: string;
3
+ pid: number;
4
+ parentPid: number;
5
+ threads: number;
6
+ }
7
+
8
+ type Signal = { // TODO export type?
9
+ id: string;
10
+ code: number;
11
+ }
12
+
13
+ interface Noobs {
14
+ getUptime(): number;
15
+ listProcesses(): Promise<ProcessInfo[]>;
16
+
17
+ ObsInit(
18
+ pluginPath: string,
19
+ logPath: string,
20
+ dataPath: string,
21
+ recordingPath: string,
22
+ cb: (signal: Signal) => void
23
+ ): void;
24
+
25
+ ObsShutdown(): void;
26
+ ObsStartBuffer(): void;
27
+ ObsStartRecording(offset: number): void;
28
+ ObsStopRecording(): void;
29
+ ObsGetLastRecording(): string;
30
+
31
+ ObsShowPreview(hwnd: Buffer): void;
32
+ ObsHidePreview(): void;
33
+ ObsResizePreview(width: number, height: number): void;
34
+ ObsMovePreview(x: number, y: number): void;
35
+ }
36
+
37
+ declare const noobs: Noobs;
38
+ export = noobs;
package/index.js ADDED
@@ -0,0 +1,8 @@
1
+ const path = require('path');
2
+
3
+ process.env.Path += ";";
4
+ process.env.Path += path.resolve(__dirname, 'dist', 'bin');
5
+
6
+ const packageName = 'noobs.node';
7
+ const noobs = require(`./dist/${packageName}`)
8
+ module.exports = noobs;
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "noobs",
3
+ "version": "0.0.6",
4
+ "description": "A native Node.js addon with libobs bindings for Warcraft Recorder.",
5
+ "main": "index.js",
6
+ "types": "index.d.ts",
7
+ "engines": {
8
+ "node": ">=14.0.0"
9
+ },
10
+ "scripts": {
11
+ "build": "node-gyp rebuild && node dist.js"
12
+ },
13
+ "files": [
14
+ "index.js",
15
+ "index.d.ts",
16
+ "binding.gyp",
17
+ "bin/64bit/obs.lib",
18
+ "src/**/*",
19
+ "include/**/*",
20
+ "dist/**/*"
21
+ ],
22
+ "author": "Warcraft Recorder LTD",
23
+ "license": "ISC",
24
+ "devDependencies": {
25
+ "@types/node": "^24.1.0",
26
+ "node-gyp": "^11.2.0"
27
+ },
28
+ "dependencies": {
29
+ "node-addon-api": "^8.4.0"
30
+ }
31
+ }
package/src/main.cpp ADDED
@@ -0,0 +1,321 @@
1
+ #include <napi.h>
2
+ #include <windows.h>
3
+ #include <tlhelp32.h>
4
+ #include <string>
5
+ #include <vector>
6
+ #include <obs.h>
7
+ #include <iostream>
8
+ #include <future>
9
+ #include <chrono>
10
+
11
+ #include "obs_interface.h"
12
+
13
+ ObsInterface* obs = nullptr;
14
+
15
+ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
16
+ if (uMsg == WM_DESTROY) {
17
+ PostQuitMessage(0);
18
+ return 0;
19
+ }
20
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
21
+ }
22
+
23
+
24
+ void WindowThread(std::promise<HWND> hwndPromise) {
25
+ const wchar_t CLASS_NAME[] = L"MyWindowClass";
26
+ HINSTANCE hInstance = GetModuleHandle(nullptr);
27
+
28
+ WNDCLASSW wc = {};
29
+ wc.lpfnWndProc = WindowProc;
30
+ wc.hInstance = hInstance;
31
+ wc.lpszClassName = CLASS_NAME;
32
+ RegisterClassW(&wc);
33
+
34
+ HWND hwnd = CreateWindowExW(
35
+ 0, CLASS_NAME, L"My Window",
36
+ WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 800, 600,
37
+ nullptr, nullptr, hInstance, nullptr
38
+ );
39
+
40
+ hwndPromise.set_value(hwnd); // Send hwnd back to main thread
41
+ ShowWindow(hwnd, SW_SHOW);
42
+
43
+ MSG msg = {};
44
+ while (GetMessage(&msg, nullptr, 0, 0)) {
45
+ TranslateMessage(&msg);
46
+ DispatchMessage(&msg);
47
+ }
48
+ }
49
+
50
+ Napi::Value ObsInit(const Napi::CallbackInfo& info) {
51
+ bool valid = info.Length() == 5 &&
52
+ info[0].IsString() && // Plugin path
53
+ info[1].IsString() && // Log path
54
+ info[2].IsString() && // Data path
55
+ info[3].IsString() && // Recording path
56
+ info[4].IsFunction(); // JavaScript callback
57
+
58
+ if (!valid) {
59
+ Napi::Error::New(info.Env(), "Invalid arguments passed to ObsInit").ThrowAsJavaScriptException();
60
+ return info.Env().Undefined();
61
+ }
62
+
63
+ std::string pluginPath = info[0].As<Napi::String>().Utf8Value();
64
+ std::string logPath = info[1].As<Napi::String>().Utf8Value();
65
+ std::string dataPath = info[2].As<Napi::String>().Utf8Value();
66
+ std::string recordingPath = info[3].As<Napi::String>().Utf8Value();
67
+ Napi::Function fn = info[4].As<Napi::Function>();
68
+
69
+ Napi::ThreadSafeFunction jscb =
70
+ Napi::ThreadSafeFunction::New(info.Env(), fn, "JavaScript callback", 0, 1);
71
+
72
+ obs = new ObsInterface(pluginPath, logPath, dataPath, recordingPath, jscb);
73
+ return info.Env().Undefined();
74
+ }
75
+
76
+
77
+ Napi::Value ObsShutdown(const Napi::CallbackInfo& info) {
78
+ delete obs;
79
+ obs = nullptr;
80
+ return info.Env().Undefined();
81
+ }
82
+
83
+ Napi::Value ObsStartBuffer(const Napi::CallbackInfo& info) {
84
+ blog(LOG_INFO, "ObsStartBuffer called");
85
+
86
+ if (!obs)
87
+ throw std::runtime_error("Obs not initialized");
88
+
89
+ obs->startBuffering();
90
+ return info.Env().Undefined();
91
+ }
92
+
93
+ Napi::Value ObsStartRecording(const Napi::CallbackInfo& info) {
94
+ if (!obs) {
95
+ throw std::runtime_error("Obs not initialized");
96
+ }
97
+
98
+ int offset = 0;
99
+
100
+ if (info.Length() == 1 && info[0].IsNumber()) {
101
+ offset = info[0].As<Napi::Number>().Int32Value();
102
+ }
103
+
104
+ obs->startRecording(offset);
105
+ return info.Env().Undefined();
106
+ }
107
+
108
+ Napi::Value ObsStopRecording(const Napi::CallbackInfo& info) {
109
+ if (!obs)
110
+ throw std::runtime_error("Obs not initialized");
111
+
112
+ obs->stopRecording();
113
+ return info.Env().Undefined();
114
+ }
115
+
116
+ Napi::Value ObsGetLastRecording(const Napi::CallbackInfo& info) {
117
+ if (!obs)
118
+ throw std::runtime_error("Obs not initialized");
119
+
120
+ std::string lastRecording = obs->getLastRecording();
121
+ return Napi::String::New(info.Env(), lastRecording);
122
+ }
123
+
124
+ Napi::Value ObsShowPreview(const Napi::CallbackInfo& info) {
125
+ blog(LOG_INFO, "ObsShowPreview called");
126
+
127
+ if (!obs)
128
+ throw std::runtime_error("Obs not initialized");
129
+
130
+ if (info.Length() < 1 || !info[0].IsBuffer()) {
131
+ Napi::TypeError::New(info.Env(), "Expected HWND as Buffer").ThrowAsJavaScriptException();
132
+ return info.Env().Undefined();
133
+ }
134
+
135
+ Napi::Buffer<uint8_t> buffer = info[0].As<Napi::Buffer<uint8_t>>();
136
+
137
+ if (buffer.Length() < sizeof(HWND)) {
138
+ Napi::TypeError::New(info.Env(), "Buffer too small for HWND").ThrowAsJavaScriptException();
139
+ return info.Env().Undefined();
140
+ } else {
141
+ blog(LOG_INFO, "ObsShowPreview buffer length: %zu", buffer.Length());
142
+ blog(LOG_INFO, "ObsShowPreview hwnd length: %zu", sizeof(HWND));
143
+ }
144
+
145
+ // Union to safely read the bytes
146
+ union {
147
+ uint8_t bytes[8];
148
+ uint64_t value;
149
+ HWND hwnd;
150
+ } hwndUnion;
151
+
152
+ memcpy(hwndUnion.bytes, buffer.Data(), sizeof(hwndUnion.bytes));
153
+
154
+ obs->showPreview(hwndUnion.hwnd);
155
+ return info.Env().Undefined();
156
+ }
157
+
158
+ Napi::Value ObsResizePreview(const Napi::CallbackInfo& info) {
159
+ if (!obs)
160
+ throw std::runtime_error("Obs not initialized");
161
+
162
+ if (info.Length() < 2) {
163
+ Napi::TypeError::New(info.Env(), "Expected width and height").ThrowAsJavaScriptException();
164
+ return info.Env().Undefined();
165
+ }
166
+
167
+ int width = info[0].As<Napi::Number>().Int32Value();
168
+ int height = info[1].As<Napi::Number>().Int32Value();
169
+
170
+ obs->resizePreview(width, height);
171
+ return info.Env().Undefined();
172
+ }
173
+
174
+ Napi::Value ObsMovePreview(const Napi::CallbackInfo& info) {
175
+ if (!obs)
176
+ throw std::runtime_error("Obs not initialized");
177
+
178
+ if (info.Length() < 2) {
179
+ Napi::TypeError::New(info.Env(), "Expected x and y").ThrowAsJavaScriptException();
180
+ return info.Env().Undefined();
181
+ }
182
+
183
+ int x = info[0].As<Napi::Number>().Int32Value();
184
+ int y = info[1].As<Napi::Number>().Int32Value();
185
+
186
+ obs->movePreview(x, y);
187
+ return info.Env().Undefined();
188
+ }
189
+
190
+ Napi::Value ObsHidePreview(const Napi::CallbackInfo& info) {
191
+ if (!obs)
192
+ throw std::runtime_error("Obs not initialized");
193
+
194
+ obs->hidePreview();
195
+ return info.Env().Undefined();
196
+ }
197
+
198
+
199
+ Napi::Number GetUptime(const Napi::CallbackInfo& info) {
200
+ DWORD ticks = GetTickCount();
201
+ return Napi::Number::New(info.Env(), static_cast<double>(ticks));
202
+ }
203
+
204
+ class ProcessListWorker : public Napi::AsyncWorker {
205
+ public:
206
+ ProcessListWorker(Napi::Function& callback)
207
+ : Napi::AsyncWorker(callback) {}
208
+
209
+ ~ProcessListWorker() {}
210
+
211
+ // This runs on a background thread - won't block JS
212
+ void Execute() override {
213
+ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
214
+ if (snapshot == INVALID_HANDLE_VALUE) {
215
+ SetError("Failed to create process snapshot");
216
+ return;
217
+ }
218
+
219
+ PROCESSENTRY32W pe32;
220
+ pe32.dwSize = sizeof(PROCESSENTRY32W);
221
+
222
+ if (!Process32FirstW(snapshot, &pe32)) {
223
+ CloseHandle(snapshot);
224
+ SetError("Failed to get first process");
225
+ return;
226
+ }
227
+
228
+ do {
229
+ ProcessInfo info;
230
+
231
+ // Convert wide string to UTF-8
232
+ int utf8Length = WideCharToMultiByte(CP_UTF8, 0, pe32.szExeFile, -1, nullptr, 0, nullptr, nullptr);
233
+ if (utf8Length > 0) {
234
+ std::vector<char> utf8Buffer(utf8Length);
235
+ WideCharToMultiByte(CP_UTF8, 0, pe32.szExeFile, -1, utf8Buffer.data(), utf8Length, nullptr, nullptr);
236
+
237
+ info.name = std::string(utf8Buffer.data());
238
+ info.pid = pe32.th32ProcessID;
239
+ info.parentPid = pe32.th32ParentProcessID;
240
+ info.threads = pe32.cntThreads;
241
+
242
+ processes.push_back(info);
243
+ }
244
+ } while (Process32NextW(snapshot, &pe32));
245
+
246
+ CloseHandle(snapshot);
247
+ }
248
+
249
+ // This runs back on the main thread
250
+ void OnOK() override {
251
+ Napi::HandleScope scope(Env());
252
+ Napi::Array result = Napi::Array::New(Env());
253
+
254
+ for (size_t i = 0; i < processes.size(); i++) {
255
+ Napi::Object process = Napi::Object::New(Env());
256
+ process.Set("name", Napi::String::New(Env(), processes[i].name));
257
+ process.Set("pid", Napi::Number::New(Env(), processes[i].pid));
258
+ process.Set("parentPid", Napi::Number::New(Env(), processes[i].parentPid));
259
+ process.Set("threads", Napi::Number::New(Env(), processes[i].threads));
260
+ result.Set(i, process);
261
+ }
262
+
263
+ Callback().Call({Env().Null(), result});
264
+ }
265
+
266
+ void OnError(const Napi::Error& e) override {
267
+ Napi::HandleScope scope(Env());
268
+ Callback().Call({e.Value(), Env().Undefined()});
269
+ }
270
+
271
+ private:
272
+ struct ProcessInfo {
273
+ std::string name;
274
+ DWORD pid;
275
+ DWORD parentPid;
276
+ DWORD threads;
277
+ };
278
+
279
+ std::vector<ProcessInfo> processes;
280
+ };
281
+
282
+ Napi::Value ListProcesses(const Napi::CallbackInfo& info) {
283
+ Napi::Env env = info.Env();
284
+ auto deferred = Napi::Promise::Deferred::New(env);
285
+
286
+ auto callback = Napi::Function::New(env, [deferred](const Napi::CallbackInfo& info) {
287
+ if (!info[0].IsNull()) {
288
+ // Error case
289
+ deferred.Reject(info[0]);
290
+ } else {
291
+ // Success case
292
+ deferred.Resolve(info[1]);
293
+ }
294
+ return info.Env().Undefined();
295
+ });
296
+
297
+ ProcessListWorker* worker = new ProcessListWorker(callback);
298
+ worker->Queue();
299
+
300
+ return deferred.Promise();
301
+ }
302
+
303
+ Napi::Object Init(Napi::Env env, Napi::Object exports) {
304
+ exports.Set("ObsInit", Napi::Function::New(env, ObsInit));
305
+ exports.Set("ObsShutdown", Napi::Function::New(env, ObsShutdown));
306
+ exports.Set("ObsStartBuffer", Napi::Function::New(env, ObsStartBuffer));
307
+ exports.Set("ObsStartRecording", Napi::Function::New(env, ObsStartRecording));
308
+ exports.Set("ObsStopRecording", Napi::Function::New(env, ObsStopRecording));
309
+ exports.Set("ObsGetLastRecording", Napi::Function::New(env, ObsGetLastRecording));
310
+
311
+ exports.Set("ObsShowPreview", Napi::Function::New(env, ObsShowPreview));
312
+ exports.Set("ObsHidePreview", Napi::Function::New(env, ObsHidePreview));
313
+ exports.Set("ObsResizePreview", Napi::Function::New(env, ObsResizePreview));
314
+ exports.Set("ObsMovePreview", Napi::Function::New(env, ObsMovePreview));
315
+
316
+ exports.Set("getUptime", Napi::Function::New(env, GetUptime));
317
+ exports.Set("listProcesses", Napi::Function::New(env, ListProcesses));
318
+ return exports;
319
+ }
320
+
321
+ NODE_API_MODULE(addon, Init)