Skip to content

Commit c7445bf

Browse files
committed
release for audio encoder too
1 parent 33998da commit c7445bf

20 files changed

+200
-76
lines changed

js/module.d.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -773,20 +773,19 @@ export declare const enum EProcessPriority {
773773
BelowNormal = "BelowNormal",
774774
Idle = "Idle"
775775
}
776-
export interface IVideoEncoder extends IConfigurable {
776+
export interface IVideoEncoder extends IConfigurable, IReleasable {
777777
name: string;
778778
readonly type: EVideoEncoderType;
779779
readonly active: boolean;
780780
readonly id: string;
781781
readonly lastError: string;
782-
release(): void;
783782
}
784-
export interface IAudioEncoder {
783+
export interface IAudioEncoder extends IReleasable {
785784
name: string;
786785
bitrate: number;
787786
}
788787
export interface IAudioEncoderFactory {
789-
create(): IAudioEncoder;
788+
create(id: string, name: string): IAudioEncoder;
790789
}
791790
export interface IVideoEncoderFactory {
792791
types(): string[];

js/module.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1676,22 +1676,21 @@ export const enum EProcessPriority {
16761676
Idle = 'Idle'
16771677
}
16781678

1679-
export interface IVideoEncoder extends IConfigurable {
1679+
export interface IVideoEncoder extends IConfigurable, IReleasable {
16801680
name: string,
16811681
readonly type: EVideoEncoderType,
16821682
readonly active: boolean,
16831683
readonly id: string,
1684-
readonly lastError: string,
1685-
release(): void
1684+
readonly lastError: string
16861685
}
16871686

1688-
export interface IAudioEncoder {
1687+
export interface IAudioEncoder extends IReleasable {
16891688
name: string,
16901689
bitrate: number
16911690
}
16921691

16931692
export interface IAudioEncoderFactory {
1694-
create(): IAudioEncoder
1693+
create(id: string, name: string): IAudioEncoder
16951694
}
16961695

16971696
export interface IVideoEncoderFactory {

obs-studio-client/source/audio-encoder.cpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Napi::Object osn::AudioEncoder::Init(Napi::Env env, Napi::Object exports)
3232

3333
InstanceAccessor("name", &osn::AudioEncoder::GetName, &osn::AudioEncoder::SetName),
3434
InstanceAccessor("bitrate", &osn::AudioEncoder::GetBitrate, &osn::AudioEncoder::SetBitrate),
35+
36+
InstanceMethod("release", &osn::AudioEncoder::Release),
3537
});
3638
exports.Set("AudioEncoder", func);
3739
osn::AudioEncoder::constructor = Napi::Persistent(func);
@@ -45,22 +47,32 @@ osn::AudioEncoder::AudioEncoder(const Napi::CallbackInfo &info) : Napi::ObjectWr
4547
Napi::HandleScope scope(env);
4648
size_t length = info.Length();
4749
this->uid = 0;
50+
this->encoderInitialized = false;
4851

4952
if (length <= 0 || !info[0].IsNumber()) {
5053
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
5154
return;
5255
}
5356

5457
this->uid = (uint64_t)info[0].ToNumber().Int64Value();
58+
this->encoderInitialized = true;
5559
}
5660

5761
Napi::Value osn::AudioEncoder::Create(const Napi::CallbackInfo &info)
5862
{
63+
std::string id = "ffmpeg_aac";
64+
std::string name = "audio-encoder";
65+
66+
if (info.Length() >= 2) {
67+
id = info[0].ToString().Utf8Value();
68+
name = info[1].ToString().Utf8Value();
69+
}
70+
5971
auto conn = GetConnection(info);
6072
if (!conn)
6173
return info.Env().Undefined();
6274

63-
std::vector<ipc::value> response = conn->call_synchronous_helper("AudioEncoder", "Create", {});
75+
std::vector<ipc::value> response = conn->call_synchronous_helper("AudioEncoder", "Create", {ipc::value(id), ipc::value(name)});
6476

6577
if (!ValidateResponse(info, response))
6678
return info.Env().Undefined();
@@ -70,6 +82,38 @@ Napi::Value osn::AudioEncoder::Create(const Napi::CallbackInfo &info)
7082
return instance;
7183
}
7284

85+
void osn::AudioEncoder::Finalize(Napi::Env env)
86+
{
87+
if (!this->encoderInitialized)
88+
return;
89+
90+
auto conn = GetConnection(env);
91+
if (!conn)
92+
return;
93+
94+
std::vector<ipc::value> response = conn->call_synchronous_helper("AudioEncoder", "Finalize", {ipc::value(this->uid)});
95+
this->encoderInitialized = false;
96+
this->uid = UINT64_MAX;
97+
if (!ValidateResponse(env, response))
98+
return;
99+
}
100+
101+
void osn::AudioEncoder::Release(const Napi::CallbackInfo &info)
102+
{
103+
if (!this->encoderInitialized)
104+
return;
105+
106+
auto conn = GetConnection(info);
107+
if (!conn)
108+
return;
109+
110+
this->encoderInitialized = false;
111+
std::vector<ipc::value> response = conn->call_synchronous_helper("AudioEncoder", "Release", {ipc::value(this->uid)});
112+
this->uid = UINT64_MAX;
113+
if (!ValidateResponse(info, response))
114+
return;
115+
}
116+
73117
Napi::Value osn::AudioEncoder::GetName(const Napi::CallbackInfo &info)
74118
{
75119
auto conn = GetConnection(info);

obs-studio-client/source/audio-encoder.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@ namespace osn {
2424
class AudioEncoder : public Napi::ObjectWrap<osn::AudioEncoder> {
2525
public:
2626
uint64_t uid;
27+
bool encoderInitialized;
2728

2829
public:
2930
static Napi::FunctionReference constructor;
3031
static Napi::Object Init(Napi::Env env, Napi::Object exports);
3132
AudioEncoder(const Napi::CallbackInfo &info);
3233

3334
static Napi::Value Create(const Napi::CallbackInfo &info);
35+
void Finalize(Napi::Env env);
36+
void Release(const Napi::CallbackInfo &info);
3437

3538
Napi::Value GetName(const Napi::CallbackInfo &info);
3639
void SetName(const Napi::CallbackInfo &info, const Napi::Value &value);

obs-studio-client/source/recording.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class Recording : public WorkerSignals, public FileOutput {
3131
std::string className;
3232
Napi::Reference<Napi::Object> videoEncoderRef;
3333
Napi::Reference<Napi::Object> streamingRef;
34+
Napi::Reference<Napi::Object> audioEncoderRef;
3435

3536
Napi::Value GetVideoEncoder(const Napi::CallbackInfo &info);
3637
void SetVideoEncoder(const Napi::CallbackInfo &info, const Napi::Value &value);

obs-studio-client/source/simple-recording.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ void osn::SimpleRecording::ReleaseObjects()
9797

9898
if (!streamingRef.IsEmpty())
9999
streamingRef.Reset();
100+
101+
if (!audioEncoderRef.IsEmpty())
102+
audioEncoderRef.Reset();
100103
}
101104

102105
Napi::Value osn::SimpleRecording::Create(const Napi::CallbackInfo &info)
@@ -161,34 +164,40 @@ void osn::SimpleRecording::SetQuality(const Napi::CallbackInfo &info, const Napi
161164
}
162165

163166
Napi::Value osn::SimpleRecording::GetAudioEncoder(const Napi::CallbackInfo &info)
167+
{
168+
return audioEncoderRef.IsEmpty() ? info.Env().Undefined() : audioEncoderRef.Value();
169+
}
170+
171+
void osn::SimpleRecording::SetAudioEncoder(const Napi::CallbackInfo &info, const Napi::Value &value)
164172
{
165173
auto conn = GetConnection(info);
166174
if (!conn)
167-
return info.Env().Undefined();
168-
169-
std::vector<ipc::value> response = conn->call_synchronous_helper("SimpleRecording", "GetAudioEncoder", {ipc::value(this->uid)});
175+
return;
170176

171-
if (!ValidateResponse(info, response))
172-
return info.Env().Undefined();
177+
if (value.IsNull() || value.IsUndefined()) {
178+
if (!audioEncoderRef.IsEmpty())
179+
audioEncoderRef.Reset();
180+
conn->call(className, "SetAudioEncoder", {ipc::value(this->uid), ipc::value(UINT64_MAX)});
181+
return;
182+
}
173183

174-
auto instance = osn::AudioEncoder::constructor.New({Napi::Number::New(info.Env(), static_cast<double>(response[1].value_union.ui64))});
175-
return instance;
176-
}
184+
Napi::Object obj = value.As<Napi::Object>();
185+
if (!obj.InstanceOf(osn::AudioEncoder::constructor.Value()))
186+
Napi::TypeError::New(info.Env(), "Object is not a AudioEncoder").ThrowAsJavaScriptException();
177187

178-
void osn::SimpleRecording::SetAudioEncoder(const Napi::CallbackInfo &info, const Napi::Value &value)
179-
{
180188
osn::AudioEncoder *encoder = Napi::ObjectWrap<osn::AudioEncoder>::Unwrap(value.ToObject());
181189

182190
if (!encoder) {
183191
Napi::TypeError::New(info.Env(), "Invalid encoder argument").ThrowAsJavaScriptException();
184192
return;
185193
}
186194

187-
auto conn = GetConnection(info);
188-
if (!conn)
189-
return;
190-
191195
conn->call(className, "SetAudioEncoder", {ipc::value(this->uid), ipc::value(encoder->uid)});
196+
197+
if (!audioEncoderRef.IsEmpty())
198+
audioEncoderRef.Reset();
199+
200+
audioEncoderRef = Napi::Persistent(obj);
192201
}
193202

194203
Napi::Value osn::SimpleRecording::GetLowCPU(const Napi::CallbackInfo &info)

obs-studio-client/source/simple-streaming.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ Napi::Object osn::SimpleStreaming::Init(Napi::Env env, Napi::Object exports)
3535
StaticMethod("destroy", &osn::SimpleStreaming::Destroy),
3636

3737
InstanceAccessor("videoEncoder", &osn::SimpleStreaming::GetVideoEncoder, &osn::SimpleStreaming::SetVideoEncoder),
38-
InstanceAccessor("audioEncoder", &osn::SimpleStreaming::GetAudioEncoder, &osn::SimpleStreaming::SetAudioEncoder),
3938
InstanceAccessor("service", &osn::SimpleStreaming::GetService, &osn::SimpleStreaming::SetService),
4039
InstanceAccessor("enforceServiceBitrate", &osn::SimpleStreaming::GetEnforceServiceBirate, &osn::SimpleStreaming::SetEnforceServiceBirate),
4140
InstanceAccessor("enableTwitchVOD", &osn::SimpleStreaming::GetEnableTwitchVOD, &osn::SimpleStreaming::SetEnableTwitchVOD),
@@ -129,17 +128,7 @@ void osn::SimpleStreaming::Destroy(const Napi::CallbackInfo &info)
129128

130129
Napi::Value osn::SimpleStreaming::GetAudioEncoder(const Napi::CallbackInfo &info)
131130
{
132-
auto conn = GetConnection(info);
133-
if (!conn)
134-
return info.Env().Undefined();
135-
136-
std::vector<ipc::value> response = conn->call_synchronous_helper("SimpleStreaming", "GetAudioEncoder", {ipc::value(this->uid)});
137-
138-
if (!ValidateResponse(info, response))
139-
return info.Env().Undefined();
140-
141-
auto instance = osn::AudioEncoder::constructor.New({Napi::Number::New(info.Env(), static_cast<double>(response[1].value_union.ui64))});
142-
return instance;
131+
return audioEncoderRef.IsEmpty() ? info.Env().Undefined() : audioEncoderRef.Value();
143132
}
144133

145134
Napi::Value osn::SimpleStreaming::GetUseAdvanced(const Napi::CallbackInfo &info)
@@ -190,18 +179,34 @@ void osn::SimpleStreaming::SetCustomEncSettings(const Napi::CallbackInfo &info,
190179

191180
void osn::SimpleStreaming::SetAudioEncoder(const Napi::CallbackInfo &info, const Napi::Value &value)
192181
{
182+
auto conn = GetConnection(info);
183+
if (!conn)
184+
return;
185+
186+
if (value.IsNull() || value.IsUndefined()) {
187+
if (!audioEncoderRef.IsEmpty())
188+
audioEncoderRef.Reset();
189+
conn->call(className, "SetAudioEncoder", {ipc::value(this->uid), ipc::value(UINT64_MAX)});
190+
return;
191+
}
192+
193+
Napi::Object obj = value.As<Napi::Object>();
194+
if (!obj.InstanceOf(osn::AudioEncoder::constructor.Value()))
195+
Napi::TypeError::New(info.Env(), "Object is not a AudioEncoder").ThrowAsJavaScriptException();
196+
193197
osn::AudioEncoder *encoder = Napi::ObjectWrap<osn::AudioEncoder>::Unwrap(value.ToObject());
194198

195199
if (!encoder) {
196200
Napi::TypeError::New(info.Env(), "Invalid encoder argument").ThrowAsJavaScriptException();
197201
return;
198202
}
199203

200-
auto conn = GetConnection(info);
201-
if (!conn)
202-
return;
203-
204204
conn->call(className, "SetAudioEncoder", {ipc::value(this->uid), ipc::value(encoder->uid)});
205+
206+
if (!audioEncoderRef.IsEmpty())
207+
audioEncoderRef.Reset();
208+
209+
audioEncoderRef = Napi::Persistent(obj);
205210
}
206211

207212
Napi::Value osn::SimpleStreaming::GetLegacySettings(const Napi::CallbackInfo &info)

obs-studio-client/source/streaming.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ void osn::Streaming::ReleaseObjects()
4141

4242
if (!networkRef.IsEmpty())
4343
networkRef.Reset();
44+
45+
if (!audioEncoderRef.IsEmpty())
46+
audioEncoderRef.Reset();
4447
}
4548

4649
Napi::Value osn::Streaming::GetService(const Napi::CallbackInfo &info)

obs-studio-client/source/streaming.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class Streaming : public WorkerSignals {
3131
std::string className;
3232

3333
Napi::Reference<Napi::Object> videoEncoderRef;
34+
Napi::Reference<Napi::Object> audioEncoderRef;
3435
Napi::Reference<Napi::Object> serviceRef;
3536
Napi::Reference<Napi::Object> delayRef;
3637
Napi::Reference<Napi::Object> reconnectRef;

obs-studio-client/source/video-encoder.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ osn::VideoEncoder::VideoEncoder(const Napi::CallbackInfo &info) : Napi::ObjectWr
5454
Napi::HandleScope scope(env);
5555
size_t length = info.Length();
5656
this->uid = UINT64_MAX;
57-
this->has_encoder = false;
57+
this->encoderInitialized = false;
5858

5959
if (length <= 0 || !info[0].IsNumber()) {
6060
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
6161
return;
6262
}
6363

6464
this->uid = (uint64_t)info[0].ToNumber().Int64Value();
65-
this->has_encoder = true;
65+
this->encoderInitialized = true;
6666
}
6767

6868
Napi::Value osn::VideoEncoder::Create(const Napi::CallbackInfo &info)
@@ -96,15 +96,15 @@ Napi::Value osn::VideoEncoder::Create(const Napi::CallbackInfo &info)
9696

9797
void osn::VideoEncoder::Finalize(Napi::Env env)
9898
{
99-
if (!this->has_encoder)
99+
if (!this->encoderInitialized)
100100
return;
101101

102102
auto conn = GetConnection(env);
103103
if (!conn)
104104
return;
105105

106106
std::vector<ipc::value> response = conn->call_synchronous_helper("VideoEncoder", "Finalize", {ipc::value(this->uid)});
107-
this->has_encoder = false;
107+
this->encoderInitialized = false;
108108
this->uid = UINT64_MAX;
109109
if (!ValidateResponse(env, response))
110110
return;
@@ -211,14 +211,14 @@ Napi::Value osn::VideoEncoder::GetLastError(const Napi::CallbackInfo &info)
211211

212212
void osn::VideoEncoder::Release(const Napi::CallbackInfo &info)
213213
{
214-
if (!this->has_encoder)
214+
if (!this->encoderInitialized)
215215
return;
216216

217217
auto conn = GetConnection(info);
218218
if (!conn)
219219
return;
220220

221-
this->has_encoder = false;
221+
this->encoderInitialized = false;
222222
std::vector<ipc::value> response = conn->call_synchronous_helper("VideoEncoder", "Release", {ipc::value(this->uid)});
223223
this->uid = UINT64_MAX;
224224
if (!ValidateResponse(info, response))

0 commit comments

Comments
 (0)