node-datachannel 0.8.0 → 0.9.0
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/.github/workflows/npm-publish-manual.yml +1 -1
- package/CMakeLists.txt +2 -2
- package/lib/index.d.cts +1 -0
- package/lib/index.d.ts +1 -0
- package/package.json +2 -2
- package/src/data-channel-wrapper.cpp +4 -0
- package/src/media-audio-wrapper.cpp +5 -6
- package/src/media-rtcpreceivingsession-wrapper.cpp +3 -4
- package/src/media-track-wrapper.cpp +27 -0
- package/src/media-track-wrapper.h +1 -0
- package/src/media-video-wrapper.cpp +6 -8
- package/src/peer-connection-wrapper.cpp +25 -14
- package/src/thread-safe-callback.cpp +11 -10
- package/src/thread-safe-callback.h +3 -4
- package/src/web-socket-wrapper.cpp +6 -2
package/CMakeLists.txt
CHANGED
|
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.15)
|
|
|
2
2
|
cmake_policy(SET CMP0091 NEW)
|
|
3
3
|
cmake_policy(SET CMP0042 NEW)
|
|
4
4
|
|
|
5
|
-
project(node_datachannel VERSION 0.
|
|
5
|
+
project(node_datachannel VERSION 0.9.0)
|
|
6
6
|
|
|
7
7
|
# -Dnapi_build_version=8
|
|
8
8
|
add_definitions(-DNAPI_VERSION=8)
|
|
@@ -29,7 +29,7 @@ include(FetchContent)
|
|
|
29
29
|
FetchContent_Declare(
|
|
30
30
|
libdatachannel
|
|
31
31
|
GIT_REPOSITORY https://github.com/paullouisageneau/libdatachannel.git
|
|
32
|
-
GIT_TAG "v0.
|
|
32
|
+
GIT_TAG "v0.21.0"
|
|
33
33
|
)
|
|
34
34
|
|
|
35
35
|
option(NO_MEDIA "Disable media transport support in libdatachannel" OFF)
|
package/lib/index.d.cts
CHANGED
|
@@ -180,6 +180,7 @@ export class Track {
|
|
|
180
180
|
isClosed(): boolean;
|
|
181
181
|
bufferedAmount(): number;
|
|
182
182
|
maxMessageSize(): number;
|
|
183
|
+
requestBitrate(bitRate: number): boolean;
|
|
183
184
|
setBufferedAmountLowThreshold(newSize: number): void;
|
|
184
185
|
requestKeyframe(): boolean;
|
|
185
186
|
setMediaHandler(handler: RtcpReceivingSession): void;
|
package/lib/index.d.ts
CHANGED
|
@@ -180,6 +180,7 @@ export class Track {
|
|
|
180
180
|
isClosed(): boolean;
|
|
181
181
|
bufferedAmount(): number;
|
|
182
182
|
maxMessageSize(): number;
|
|
183
|
+
requestBitrate(bitRate: number): boolean;
|
|
183
184
|
setBufferedAmountLowThreshold(newSize: number): void;
|
|
184
185
|
requestKeyframe(): boolean;
|
|
185
186
|
setMediaHandler(handler: RtcpReceivingSession): void;
|
package/package.json
CHANGED
|
@@ -58,6 +58,10 @@ DataChannelWrapper::DataChannelWrapper(const Napi::CallbackInfo &info) : Napi::O
|
|
|
58
58
|
PLOG_DEBUG << "Constructor called";
|
|
59
59
|
mDataChannelPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::DataChannel>>>().Data());
|
|
60
60
|
PLOG_DEBUG << "Data Channel created";
|
|
61
|
+
|
|
62
|
+
// Closed callback must be set to trigger cleanup
|
|
63
|
+
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo&){}));
|
|
64
|
+
|
|
61
65
|
instances.insert(this);
|
|
62
66
|
}
|
|
63
67
|
|
|
@@ -390,9 +390,8 @@ void AudioWrapper::setBitrate(const Napi::CallbackInfo &info)
|
|
|
390
390
|
return;
|
|
391
391
|
}
|
|
392
392
|
|
|
393
|
-
int
|
|
394
|
-
|
|
395
|
-
mAudioPtr->setBitrate(bitRate);
|
|
393
|
+
unsigned int bitrate = static_cast<uint32_t>(info[0].As<Napi::Number>().ToNumber());
|
|
394
|
+
mAudioPtr->setBitrate(bitrate);
|
|
396
395
|
}
|
|
397
396
|
|
|
398
397
|
Napi::Value AudioWrapper::getBitrate(const Napi::CallbackInfo &info)
|
|
@@ -428,9 +427,9 @@ void AudioWrapper::addRTXCodec(const Napi::CallbackInfo &info)
|
|
|
428
427
|
return;
|
|
429
428
|
}
|
|
430
429
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
unsigned int clockRate = static_cast<
|
|
430
|
+
int payloadType = static_cast<int32_t>(info[0].As<Napi::Number>().ToNumber());
|
|
431
|
+
int originalPayloadType = static_cast<int32_t>(info[1].As<Napi::Number>().ToNumber());
|
|
432
|
+
unsigned int clockRate = static_cast<uint32_t>(info[2].As<Napi::Number>().ToNumber());
|
|
434
433
|
|
|
435
434
|
mAudioPtr->addRtxCodec(payloadType, originalPayloadType, clockRate);
|
|
436
435
|
}
|
|
@@ -51,13 +51,12 @@ void RtcpReceivingSessionWrapper::requestBitrate(const Napi::CallbackInfo &info)
|
|
|
51
51
|
return;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
unsigned int
|
|
55
|
-
|
|
56
|
-
mSessionPtr->requestBitrate(bitRate);
|
|
54
|
+
unsigned int bitrate = static_cast<uint32_t>(info[0].As<Napi::Number>().ToNumber());
|
|
55
|
+
mSessionPtr->requestBitrate(bitrate);
|
|
57
56
|
}
|
|
58
57
|
|
|
59
58
|
Napi::Value RtcpReceivingSessionWrapper::requestKeyframe(const Napi::CallbackInfo &info)
|
|
60
59
|
{
|
|
61
60
|
Napi::Env env = info.Env();
|
|
62
61
|
return Napi::Boolean::New(env, mSessionPtr->requestKeyframe());
|
|
63
|
-
}
|
|
62
|
+
}
|
|
@@ -39,6 +39,7 @@ Napi::Object TrackWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
|
39
39
|
InstanceMethod("isOpen", &TrackWrapper::isOpen),
|
|
40
40
|
InstanceMethod("isClosed", &TrackWrapper::isClosed),
|
|
41
41
|
InstanceMethod("maxMessageSize", &TrackWrapper::maxMessageSize),
|
|
42
|
+
InstanceMethod("requestBitrate", &TrackWrapper::requestBitrate),
|
|
42
43
|
InstanceMethod("requestKeyframe", &TrackWrapper::requestKeyframe),
|
|
43
44
|
InstanceMethod("setMediaHandler", &TrackWrapper::setMediaHandler),
|
|
44
45
|
InstanceMethod("onOpen", &TrackWrapper::onOpen),
|
|
@@ -56,7 +57,12 @@ Napi::Object TrackWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
|
56
57
|
|
|
57
58
|
TrackWrapper::TrackWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<TrackWrapper>(info)
|
|
58
59
|
{
|
|
60
|
+
PLOG_DEBUG << "Constructor called";
|
|
59
61
|
mTrackPtr = *(info[0].As<Napi::External<std::shared_ptr<rtc::Track>>>().Data());
|
|
62
|
+
PLOG_DEBUG << "Track created";
|
|
63
|
+
|
|
64
|
+
// Closed callback must be set to trigger cleanup
|
|
65
|
+
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo&){}));
|
|
60
66
|
|
|
61
67
|
instances.insert(this);
|
|
62
68
|
}
|
|
@@ -237,6 +243,27 @@ Napi::Value TrackWrapper::maxMessageSize(const Napi::CallbackInfo &info)
|
|
|
237
243
|
}
|
|
238
244
|
}
|
|
239
245
|
|
|
246
|
+
Napi::Value TrackWrapper::requestBitrate(const Napi::CallbackInfo &info)
|
|
247
|
+
{
|
|
248
|
+
if (!mTrackPtr)
|
|
249
|
+
{
|
|
250
|
+
Napi::Error::New(info.Env(), "requestBitrate() called on destroyed track").ThrowAsJavaScriptException();
|
|
251
|
+
return info.Env().Null();
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
Napi::Env env = info.Env();
|
|
255
|
+
int length = info.Length();
|
|
256
|
+
|
|
257
|
+
if (length < 1 || !info[0].IsNumber())
|
|
258
|
+
{
|
|
259
|
+
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
|
|
260
|
+
return info.Env().Null();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
unsigned int bitrate = static_cast<uint32_t>(info[0].As<Napi::Number>());
|
|
264
|
+
return Napi::Boolean::New(env, mTrackPtr->requestBitrate(bitrate));
|
|
265
|
+
}
|
|
266
|
+
|
|
240
267
|
Napi::Value TrackWrapper::requestKeyframe(const Napi::CallbackInfo &info)
|
|
241
268
|
{
|
|
242
269
|
if (!mTrackPtr)
|
|
@@ -30,6 +30,7 @@ public:
|
|
|
30
30
|
Napi::Value isOpen(const Napi::CallbackInfo &info);
|
|
31
31
|
Napi::Value isClosed(const Napi::CallbackInfo &info);
|
|
32
32
|
Napi::Value maxMessageSize(const Napi::CallbackInfo &info);
|
|
33
|
+
Napi::Value requestBitrate(const Napi::CallbackInfo &info);
|
|
33
34
|
Napi::Value requestKeyframe(const Napi::CallbackInfo &info);
|
|
34
35
|
void setMediaHandler(const Napi::CallbackInfo &info);
|
|
35
36
|
|
|
@@ -423,14 +423,12 @@ void VideoWrapper::setBitrate(const Napi::CallbackInfo &info)
|
|
|
423
423
|
return;
|
|
424
424
|
}
|
|
425
425
|
|
|
426
|
-
int
|
|
427
|
-
|
|
428
|
-
mVideoPtr->setBitrate(bitRate);
|
|
426
|
+
unsigned int bitrate = info[0].As<Napi::Number>().ToNumber().Uint32Value();
|
|
427
|
+
mVideoPtr->setBitrate(bitrate);
|
|
429
428
|
}
|
|
430
429
|
|
|
431
430
|
Napi::Value VideoWrapper::getBitrate(const Napi::CallbackInfo &info)
|
|
432
431
|
{
|
|
433
|
-
|
|
434
432
|
return Napi::Number::New(info.Env(), mVideoPtr->bitrate());
|
|
435
433
|
}
|
|
436
434
|
|
|
@@ -445,7 +443,7 @@ Napi::Value VideoWrapper::hasPayloadType(const Napi::CallbackInfo &info)
|
|
|
445
443
|
return env.Null();
|
|
446
444
|
}
|
|
447
445
|
|
|
448
|
-
int payloadType = static_cast<
|
|
446
|
+
int payloadType = static_cast<int32_t>(info[0].As<Napi::Number>().ToNumber());
|
|
449
447
|
|
|
450
448
|
return Napi::Boolean::New(env, mVideoPtr->hasPayloadType(payloadType));
|
|
451
449
|
}
|
|
@@ -461,9 +459,9 @@ void VideoWrapper::addRTXCodec(const Napi::CallbackInfo &info)
|
|
|
461
459
|
return;
|
|
462
460
|
}
|
|
463
461
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
unsigned int clockRate = static_cast<
|
|
462
|
+
int payloadType = static_cast<int32_t>(info[0].As<Napi::Number>().ToNumber());
|
|
463
|
+
int originalPayloadType = static_cast<int32_t>(info[1].As<Napi::Number>().ToNumber());
|
|
464
|
+
unsigned int clockRate = static_cast<uint32_t>(info[2].As<Napi::Number>().ToNumber());
|
|
467
465
|
|
|
468
466
|
mVideoPtr->addRtxCodec(payloadType, originalPayloadType, clockRate);
|
|
469
467
|
}
|
|
@@ -237,7 +237,7 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
237
237
|
// Create peer-connection
|
|
238
238
|
try
|
|
239
239
|
{
|
|
240
|
-
PLOG_DEBUG << "Creating a new
|
|
240
|
+
PLOG_DEBUG << "Creating a new Peer Connection";
|
|
241
241
|
mRtcPeerConnPtr = std::make_unique<rtc::PeerConnection>(rtcConfig);
|
|
242
242
|
}
|
|
243
243
|
catch (std::exception &ex)
|
|
@@ -246,6 +246,11 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
246
246
|
return;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
+
PLOG_DEBUG << "Peer Connection created";
|
|
250
|
+
|
|
251
|
+
// State change callback must be set to trigger cleanup on close
|
|
252
|
+
mOnStateChangeCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo&){}));
|
|
253
|
+
|
|
249
254
|
instances.insert(this);
|
|
250
255
|
}
|
|
251
256
|
|
|
@@ -552,10 +557,10 @@ Napi::Value PeerConnectionWrapper::createDataChannel(const Napi::CallbackInfo &i
|
|
|
552
557
|
switch (reliability.Get("type").As<Napi::Number>().Uint32Value())
|
|
553
558
|
{
|
|
554
559
|
case 1:
|
|
555
|
-
init.reliability.rexmit =
|
|
560
|
+
init.reliability.rexmit = int(reliability.Get("rexmit").As<Napi::Number>().ToNumber().Uint32Value());
|
|
556
561
|
break;
|
|
557
562
|
case 2:
|
|
558
|
-
init.reliability.rexmit = std::chrono::milliseconds(reliability.Get("rexmit").As<Napi::Number>().
|
|
563
|
+
init.reliability.rexmit = std::chrono::milliseconds(reliability.Get("rexmit").As<Napi::Number>().Int32Value());
|
|
559
564
|
break;
|
|
560
565
|
}
|
|
561
566
|
}
|
|
@@ -572,25 +577,31 @@ Napi::Value PeerConnectionWrapper::createDataChannel(const Napi::CallbackInfo &i
|
|
|
572
577
|
init.reliability.unordered = !initConfig.Get("ordered").As<Napi::Boolean>();
|
|
573
578
|
}
|
|
574
579
|
|
|
575
|
-
|
|
580
|
+
|
|
581
|
+
if (!initConfig.Get("maxPacketLifeTime").IsUndefined() && !initConfig.Get("maxPacketLifeTime").IsNull() &&
|
|
582
|
+
!initConfig.Get("maxRetransmits").IsUndefined() && !initConfig.Get("maxRetransmits").IsNull())
|
|
576
583
|
{
|
|
577
584
|
Napi::TypeError::New(env, "Wrong DataChannel Init Config, maxPacketLifeTime and maxRetransmits are exclusive").ThrowAsJavaScriptException();
|
|
578
585
|
return info.Env().Null();
|
|
579
586
|
}
|
|
580
587
|
|
|
581
|
-
if (initConfig.Get("maxPacketLifeTime").
|
|
588
|
+
if (!initConfig.Get("maxPacketLifeTime").IsUndefined() && !initConfig.Get("maxPacketLifeTime").IsNull())
|
|
582
589
|
{
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
init.reliability.
|
|
589
|
-
init.reliability.rexmit = int(initConfig.Get("maxRetransmits").As<Napi::Number>().Uint32Value());
|
|
590
|
+
if (!initConfig.Get("maxPacketLifeTime").IsNumber())
|
|
591
|
+
{
|
|
592
|
+
Napi::TypeError::New(env, "Wrong DataChannel Init Config (maxPacketLifeTime)").ThrowAsJavaScriptException();
|
|
593
|
+
return info.Env().Null();
|
|
594
|
+
}
|
|
595
|
+
init.reliability.maxPacketLifeTime = std::chrono::milliseconds(initConfig.Get("maxPacketLifeTime").As<Napi::Number>().Uint32Value());
|
|
590
596
|
}
|
|
591
|
-
else
|
|
597
|
+
else if (!initConfig.Get("maxRetransmits").IsUndefined() && !initConfig.Get("maxRetransmits").IsNull())
|
|
592
598
|
{
|
|
593
|
-
|
|
599
|
+
if (!initConfig.Get("maxRetransmits").IsNumber())
|
|
600
|
+
{
|
|
601
|
+
Napi::TypeError::New(env, "Wrong DataChannel Init Config (maxRetransmits)").ThrowAsJavaScriptException();
|
|
602
|
+
return info.Env().Null();
|
|
603
|
+
}
|
|
604
|
+
init.reliability.maxRetransmits = int(initConfig.Get("maxRetransmits").As<Napi::Number>().Int32Value());
|
|
594
605
|
}
|
|
595
606
|
}
|
|
596
607
|
|
|
@@ -9,16 +9,16 @@ const char *ThreadSafeCallback::CancelException::what() const throw()
|
|
|
9
9
|
|
|
10
10
|
ThreadSafeCallback::ThreadSafeCallback(Napi::Function callback)
|
|
11
11
|
{
|
|
12
|
-
if (!callback.IsFunction())
|
|
13
|
-
throw Napi::Error::New(callback.Env(), "Callback must be a function");
|
|
14
|
-
|
|
15
12
|
Napi::Env env = callback.Env();
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
if (!callback.IsFunction())
|
|
15
|
+
throw Napi::Error::New(env, "Callback must be a function");
|
|
16
|
+
|
|
18
17
|
tsfn = tsfn_t::New(env,
|
|
19
18
|
std::move(callback),
|
|
20
19
|
"ThreadSafeCallback callback",
|
|
21
|
-
0,
|
|
20
|
+
0, // unlimited queue
|
|
21
|
+
1);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
ThreadSafeCallback::~ThreadSafeCallback()
|
|
@@ -38,10 +38,10 @@ void ThreadSafeCallback::call(arg_func_t argFunc, cleanup_func_t cleanupFunc)
|
|
|
38
38
|
|
|
39
39
|
void ThreadSafeCallback::callbackFunc(Napi::Env env,
|
|
40
40
|
Napi::Function callback,
|
|
41
|
-
|
|
41
|
+
ContextType *context,
|
|
42
42
|
CallbackData *data)
|
|
43
43
|
{
|
|
44
|
-
// if env is gone
|
|
44
|
+
// if env is gone, it could mean this cb was destroyed. See issue#176
|
|
45
45
|
if (!data || !env)
|
|
46
46
|
return;
|
|
47
47
|
|
|
@@ -59,9 +59,10 @@ void ThreadSafeCallback::callbackFunc(Napi::Env env,
|
|
|
59
59
|
return;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
if (
|
|
62
|
+
if (callback)
|
|
63
63
|
{
|
|
64
|
-
callback.Call(
|
|
65
|
-
cleanup();
|
|
64
|
+
callback.Call(args);
|
|
66
65
|
}
|
|
66
|
+
|
|
67
|
+
cleanup();
|
|
67
68
|
}
|
|
@@ -30,6 +30,7 @@ public:
|
|
|
30
30
|
};
|
|
31
31
|
|
|
32
32
|
private:
|
|
33
|
+
using ContextType = std::nullptr_t;
|
|
33
34
|
struct CallbackData
|
|
34
35
|
{
|
|
35
36
|
arg_func_t argFunc;
|
|
@@ -38,12 +39,10 @@ private:
|
|
|
38
39
|
|
|
39
40
|
static void callbackFunc(Napi::Env env,
|
|
40
41
|
Napi::Function callback,
|
|
41
|
-
|
|
42
|
+
ContextType *context,
|
|
42
43
|
CallbackData *data);
|
|
43
44
|
|
|
44
|
-
using tsfn_t = Napi::TypedThreadSafeFunction<
|
|
45
|
-
|
|
46
|
-
Napi::Reference<Napi::Value> receiver;
|
|
45
|
+
using tsfn_t = Napi::TypedThreadSafeFunction<ContextType, CallbackData, callbackFunc>;
|
|
47
46
|
tsfn_t tsfn;
|
|
48
47
|
};
|
|
49
48
|
|
|
@@ -238,6 +238,10 @@ WebSocketWrapper::WebSocketWrapper(const Napi::CallbackInfo &info) : Napi::Objec
|
|
|
238
238
|
}
|
|
239
239
|
|
|
240
240
|
PLOG_DEBUG << "WebSocket created";
|
|
241
|
+
|
|
242
|
+
// Closed callback must set to trigger cleanup
|
|
243
|
+
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo&){}));
|
|
244
|
+
|
|
241
245
|
instances.insert(this);
|
|
242
246
|
}
|
|
243
247
|
|
|
@@ -471,7 +475,7 @@ Napi::Value WebSocketWrapper::remoteAddress(const Napi::CallbackInfo &info)
|
|
|
471
475
|
|
|
472
476
|
if (!mWebSocketPtr)
|
|
473
477
|
{
|
|
474
|
-
return env.Undefined();
|
|
478
|
+
return env.Undefined();
|
|
475
479
|
}
|
|
476
480
|
|
|
477
481
|
try
|
|
@@ -500,7 +504,7 @@ Napi::Value WebSocketWrapper::path(const Napi::CallbackInfo &info)
|
|
|
500
504
|
|
|
501
505
|
if (!mWebSocketPtr)
|
|
502
506
|
{
|
|
503
|
-
return env.Undefined();
|
|
507
|
+
return env.Undefined();
|
|
504
508
|
}
|
|
505
509
|
|
|
506
510
|
try
|