noobs 0.0.187 → 0.0.200
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/README.md +2 -0
- package/dist/bin/obs.dll +0 -0
- package/dist/noobs.node +0 -0
- package/dist/obs-plugins/obs-ffmpeg.dll +0 -0
- package/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/main.cpp +23 -0
- package/src/obs_interface.cpp +55 -16
- package/src/obs_interface.h +4 -0
package/README.md
CHANGED
package/dist/bin/obs.dll
CHANGED
|
Binary file
|
package/dist/noobs.node
CHANGED
|
Binary file
|
|
Binary file
|
package/index.d.ts
CHANGED
|
@@ -171,6 +171,7 @@ interface Noobs {
|
|
|
171
171
|
|
|
172
172
|
// Recording functions.
|
|
173
173
|
SetBuffering(buffering: boolean): void; // In buffering mode, the recording is stored in memory and can be converted to a file later.
|
|
174
|
+
SetFragmentation(fragmented: boolean): void; // Use fragmented MP4.
|
|
174
175
|
StartBuffer(): void;
|
|
175
176
|
StartRecording(offset: number): void;
|
|
176
177
|
StopRecording(): void;
|
package/package.json
CHANGED
package/src/main.cpp
CHANGED
|
@@ -156,6 +156,28 @@ Napi::Value ObsSetBuffering(const Napi::CallbackInfo& info) {
|
|
|
156
156
|
return info.Env().Undefined();
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
+
Napi::Value ObsSetFragmentation(const Napi::CallbackInfo& info) {
|
|
160
|
+
blog(LOG_INFO, "ObsSetFragmentation called");
|
|
161
|
+
|
|
162
|
+
if (!obs) {
|
|
163
|
+
blog(LOG_ERROR, "ObsSetFragmentation called but obs is not initialized");
|
|
164
|
+
Napi::Error::New(info.Env(), "Obs not initialized").ThrowAsJavaScriptException();
|
|
165
|
+
return info.Env().Undefined();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
bool valid = info.Length() == 1 && info[0].IsBoolean();
|
|
169
|
+
|
|
170
|
+
if (!valid) {
|
|
171
|
+
Napi::TypeError::New(info.Env(), "Invalid arguments passed to ObsSetFragmentation").ThrowAsJavaScriptException();
|
|
172
|
+
return info.Env().Undefined();
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
bool fragmented = info[0].As<Napi::Boolean>().Value();
|
|
176
|
+
obs->setFragmentation(fragmented);
|
|
177
|
+
|
|
178
|
+
return info.Env().Undefined();
|
|
179
|
+
}
|
|
180
|
+
|
|
159
181
|
Napi::Value ObsStartBuffer(const Napi::CallbackInfo& info) {
|
|
160
182
|
blog(LOG_INFO, "ObsStartBuffer called");
|
|
161
183
|
|
|
@@ -678,6 +700,7 @@ Napi::Object Init(Napi::Env env, Napi::Object exports) {
|
|
|
678
700
|
exports.Set("SetVideoEncoder", Napi::Function::New(env, ObsSetVideoEncoder));
|
|
679
701
|
|
|
680
702
|
exports.Set("SetBuffering", Napi::Function::New(env, ObsSetBuffering));
|
|
703
|
+
exports.Set("SetFragmentation", Napi::Function::New(env, ObsSetFragmentation));
|
|
681
704
|
exports.Set("StartBuffer", Napi::Function::New(env, ObsStartBuffer));
|
|
682
705
|
exports.Set("StartRecording", Napi::Function::New(env, ObsStartRecording));
|
|
683
706
|
exports.Set("StopRecording", Napi::Function::New(env, ObsStopRecording));
|
package/src/obs_interface.cpp
CHANGED
|
@@ -23,6 +23,10 @@ void call_jscb(Napi::Env env, Napi::Function cb, SignalData* sd) {
|
|
|
23
23
|
obj.Set("error", Napi::String::New(env, sd->error.value()));
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
if (sd->path.has_value()) {
|
|
27
|
+
obj.Set("path", Napi::String::New(env, sd->path.value()));
|
|
28
|
+
}
|
|
29
|
+
|
|
26
30
|
cb.Call({ obj });
|
|
27
31
|
delete sd;
|
|
28
32
|
}
|
|
@@ -271,6 +275,12 @@ void ObsInterface::create_output() {
|
|
|
271
275
|
unbuffered_output_filename = filename;
|
|
272
276
|
}
|
|
273
277
|
|
|
278
|
+
if (fragmented && file_extension == "mp4") {
|
|
279
|
+
blog(LOG_INFO, "Fragmentation enabled");
|
|
280
|
+
std::string mux_frag = "movflags=frag_keyframe+empty_moov+delay_moov";
|
|
281
|
+
obs_data_set_string(settings, "muxer_settings", mux_frag.c_str());
|
|
282
|
+
}
|
|
283
|
+
|
|
274
284
|
obs_output_update(output, settings);
|
|
275
285
|
obs_data_release(settings);
|
|
276
286
|
connect_signal_handlers(output);
|
|
@@ -591,25 +601,40 @@ obs_properties_t* ObsInterface::getSourceProperties(std::string name) {
|
|
|
591
601
|
}
|
|
592
602
|
|
|
593
603
|
void ObsInterface::output_signal_handler(void *data, calldata_t *cd) {
|
|
594
|
-
|
|
595
|
-
|
|
604
|
+
SignalContext* ctx = static_cast<SignalContext*>(data);
|
|
605
|
+
ObsInterface* self = ctx->self;
|
|
606
|
+
SignalData* sd;
|
|
596
607
|
|
|
597
|
-
|
|
608
|
+
blog(LOG_INFO, "Handling %s signal from libobs", ctx->id.c_str());
|
|
598
609
|
|
|
599
|
-
if (
|
|
600
|
-
|
|
601
|
-
}
|
|
610
|
+
if (ctx->id == "converted") {
|
|
611
|
+
const char *path = calldata_string(cd, "file");
|
|
602
612
|
|
|
603
|
-
|
|
604
|
-
|
|
613
|
+
sd = new SignalData{
|
|
614
|
+
"output",
|
|
615
|
+
"converted",
|
|
616
|
+
0, // Never actually get a code for a converted signal, so just set it to 0.
|
|
617
|
+
std::nullopt, // No value, that's only used for volmeters.
|
|
618
|
+
std::nullopt, // Never expect errors here.
|
|
619
|
+
std::string(path),
|
|
620
|
+
};
|
|
621
|
+
} else {
|
|
622
|
+
long long code = calldata_int(cd, "code");
|
|
623
|
+
const char *err = calldata_string(cd, "last_error");
|
|
624
|
+
std::optional<std::string> error;
|
|
605
625
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
626
|
+
if (err) {
|
|
627
|
+
error = std::string(err);
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
sd = new SignalData{
|
|
631
|
+
"output",
|
|
632
|
+
ctx->id.c_str(),
|
|
633
|
+
code,
|
|
634
|
+
std::nullopt, // No value, that's only used for volmeters.
|
|
635
|
+
error,
|
|
636
|
+
};
|
|
637
|
+
}
|
|
613
638
|
|
|
614
639
|
self->jscb.NonBlockingCall(sd, call_jscb);
|
|
615
640
|
}
|
|
@@ -622,6 +647,7 @@ void ObsInterface::connect_signal_handlers(obs_output_t *output) {
|
|
|
622
647
|
signal_handler_connect(sh, "stop", output_signal_handler, stop_ctx);
|
|
623
648
|
signal_handler_connect(sh, "activate", output_signal_handler, activate_ctx);
|
|
624
649
|
signal_handler_connect(sh, "deactivate", output_signal_handler, deactivate_ctx);
|
|
650
|
+
signal_handler_connect(sh, "converted", output_signal_handler, converted_ctx);
|
|
625
651
|
}
|
|
626
652
|
|
|
627
653
|
void ObsInterface::disconnect_signal_handlers(obs_output_t *output) {
|
|
@@ -631,7 +657,8 @@ void ObsInterface::disconnect_signal_handlers(obs_output_t *output) {
|
|
|
631
657
|
signal_handler_disconnect(sh, "stopping", output_signal_handler, stopping_ctx);
|
|
632
658
|
signal_handler_disconnect(sh, "stop", output_signal_handler, stop_ctx);
|
|
633
659
|
signal_handler_disconnect(sh, "activate", output_signal_handler, activate_ctx);
|
|
634
|
-
signal_handler_disconnect(sh, "deactivate
|
|
660
|
+
signal_handler_disconnect(sh, "deactivate", output_signal_handler, deactivate_ctx);
|
|
661
|
+
signal_handler_disconnect(sh, "converted ", output_signal_handler, converted_ctx);
|
|
635
662
|
}
|
|
636
663
|
|
|
637
664
|
bool draw_source_outline(obs_scene_t *scene, obs_sceneitem_t *item, void *p) {
|
|
@@ -949,6 +976,7 @@ ObsInterface::ObsInterface(
|
|
|
949
976
|
stop_ctx = new SignalContext{ this, "stop" };
|
|
950
977
|
activate_ctx = new SignalContext{this, "activate"};
|
|
951
978
|
deactivate_ctx = new SignalContext{this, "deactivate"};
|
|
979
|
+
converted_ctx = new SignalContext{this, "converted"};
|
|
952
980
|
|
|
953
981
|
// Create the resources we rely on.
|
|
954
982
|
create_scene();
|
|
@@ -981,6 +1009,7 @@ ObsInterface::~ObsInterface() {
|
|
|
981
1009
|
delete stop_ctx;
|
|
982
1010
|
delete activate_ctx;
|
|
983
1011
|
delete deactivate_ctx;
|
|
1012
|
+
delete converted_ctx;
|
|
984
1013
|
|
|
985
1014
|
for (auto& kv : sources) {
|
|
986
1015
|
std::string name = kv.first;
|
|
@@ -1047,6 +1076,16 @@ void ObsInterface::setBuffering(bool value) {
|
|
|
1047
1076
|
create_output();
|
|
1048
1077
|
}
|
|
1049
1078
|
|
|
1079
|
+
void ObsInterface::setFragmentation(bool value) {
|
|
1080
|
+
if (obs_output_active(output)) {
|
|
1081
|
+
blog(LOG_ERROR, "Cannot change fragmentation state while output is active");
|
|
1082
|
+
throw new std::runtime_error("Cannot change fragmentation state while output is active");
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
fragmented = value;
|
|
1086
|
+
create_output();
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1050
1089
|
void ObsInterface::startBuffering() {
|
|
1051
1090
|
blog(LOG_INFO, "ObsInterface::startBuffering called");
|
|
1052
1091
|
|
package/src/obs_interface.h
CHANGED
|
@@ -19,6 +19,7 @@ struct SignalData {
|
|
|
19
19
|
long long code;
|
|
20
20
|
std::optional<float> value;
|
|
21
21
|
std::optional<std::string> error;
|
|
22
|
+
std::optional<std::string> path; // used by converted signal handler
|
|
22
23
|
};
|
|
23
24
|
|
|
24
25
|
struct SignalContext {
|
|
@@ -52,6 +53,7 @@ class ObsInterface {
|
|
|
52
53
|
void forceStopRecording(); // Force stop the recording, this will not save the current recording.
|
|
53
54
|
std::string getLastRecording(); // Get the last recorded file path.
|
|
54
55
|
void setBuffering(bool buffer); // Enable or disable buffering.
|
|
56
|
+
void setFragmentation(bool fragmented); // Enable or disable fragmented MP4.
|
|
55
57
|
void setRecordingCfg(const std::string& recordingPath, const std::string& fileExtension); // Set the recording path.
|
|
56
58
|
void setVideoContext(int fps, int width, int height); // Reset video settings.
|
|
57
59
|
|
|
@@ -108,6 +110,7 @@ class ObsInterface {
|
|
|
108
110
|
std::string file_extension = "mp4"; // File extension for recordings.
|
|
109
111
|
|
|
110
112
|
bool buffering = false; // Whether we are buffering the recording in memory.
|
|
113
|
+
bool fragmented = false; // Use fragmented MP4.
|
|
111
114
|
bool drawSourceOutline = false; // Draw red outline around source
|
|
112
115
|
void init_obs(const std::string& distPath);
|
|
113
116
|
int reset_video(int fps, int width, int height);
|
|
@@ -122,6 +125,7 @@ class ObsInterface {
|
|
|
122
125
|
SignalContext* stop_ctx;
|
|
123
126
|
SignalContext* activate_ctx;
|
|
124
127
|
SignalContext* deactivate_ctx;
|
|
128
|
+
SignalContext* converted_ctx;
|
|
125
129
|
static void output_signal_handler(void *data, calldata_t *cd);
|
|
126
130
|
|
|
127
131
|
void list_encoders(obs_encoder_type type = OBS_ENCODER_VIDEO);
|