node-datachannel 0.1.14 → 0.2.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/CMakeLists.txt +8 -3
- package/README.md +222 -64
- package/examples/README.md +24 -2
- package/examples/media/main.html +45 -0
- package/examples/media/media.js +54 -0
- package/lib/index.d.ts +96 -1
- package/package.json +7 -2
- package/src/data-channel-wrapper.cpp +32 -80
- package/src/data-channel-wrapper.h +0 -3
- package/src/main.cpp +8 -0
- package/src/media-audio-wrapper.cpp +457 -0
- package/src/media-audio-wrapper.h +54 -0
- package/src/media-direction.cpp +43 -0
- package/src/media-direction.h +10 -0
- package/src/media-rtcpreceivingsession-wrapper.cpp +63 -0
- package/src/media-rtcpreceivingsession-wrapper.h +36 -0
- package/src/media-track-wrapper.cpp +333 -0
- package/src/media-track-wrapper.h +58 -0
- package/src/media-video-wrapper.cpp +490 -0
- package/src/media-video-wrapper.h +56 -0
- package/src/peer-connection-wrapper.cpp +173 -33
- package/src/peer-connection-wrapper.h +7 -1
- package/src/rtc-wrapper.cpp +2 -0
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
#include "peer-connection-wrapper.h"
|
|
2
2
|
#include "data-channel-wrapper.h"
|
|
3
|
+
#include "media-track-wrapper.h"
|
|
4
|
+
#include "media-video-wrapper.h"
|
|
5
|
+
#include "media-audio-wrapper.h"
|
|
3
6
|
|
|
4
7
|
#include <sstream>
|
|
5
8
|
|
|
6
9
|
Napi::FunctionReference PeerConnectionWrapper::constructor;
|
|
7
|
-
std::unordered_set<PeerConnectionWrapper*> PeerConnectionWrapper::instances;
|
|
10
|
+
std::unordered_set<PeerConnectionWrapper *> PeerConnectionWrapper::instances;
|
|
8
11
|
|
|
9
12
|
void PeerConnectionWrapper::CloseAll()
|
|
10
13
|
{
|
|
11
14
|
auto copy(instances);
|
|
12
|
-
for(auto inst : copy)
|
|
15
|
+
for (auto inst : copy)
|
|
13
16
|
inst->doClose();
|
|
14
17
|
}
|
|
15
18
|
|
|
@@ -20,19 +23,26 @@ Napi::Object PeerConnectionWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
|
20
23
|
Napi::Function func = DefineClass(
|
|
21
24
|
env,
|
|
22
25
|
"PeerConnection",
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
{
|
|
27
|
+
InstanceMethod("close", &PeerConnectionWrapper::close),
|
|
28
|
+
InstanceMethod("setLocalDescription", &PeerConnectionWrapper::setLocalDescription),
|
|
29
|
+
InstanceMethod("setRemoteDescription", &PeerConnectionWrapper::setRemoteDescription),
|
|
30
|
+
InstanceMethod("localDescription", &PeerConnectionWrapper::localDescription),
|
|
31
|
+
InstanceMethod("addRemoteCandidate", &PeerConnectionWrapper::addRemoteCandidate),
|
|
32
|
+
InstanceMethod("createDataChannel", &PeerConnectionWrapper::createDataChannel),
|
|
33
|
+
InstanceMethod("addTrack", &PeerConnectionWrapper::addTrack),
|
|
34
|
+
InstanceMethod("hasMedia", &PeerConnectionWrapper::hasMedia),
|
|
35
|
+
InstanceMethod("onLocalDescription", &PeerConnectionWrapper::onLocalDescription),
|
|
36
|
+
InstanceMethod("onLocalCandidate", &PeerConnectionWrapper::onLocalCandidate),
|
|
37
|
+
InstanceMethod("onStateChange", &PeerConnectionWrapper::onStateChange),
|
|
38
|
+
InstanceMethod("onGatheringStateChange", &PeerConnectionWrapper::onGatheringStateChange),
|
|
39
|
+
InstanceMethod("onDataChannel", &PeerConnectionWrapper::onDataChannel),
|
|
40
|
+
InstanceMethod("onTrack", &PeerConnectionWrapper::onTrack),
|
|
41
|
+
InstanceMethod("bytesSent", &PeerConnectionWrapper::bytesSent),
|
|
42
|
+
InstanceMethod("bytesReceived", &PeerConnectionWrapper::bytesReceived),
|
|
43
|
+
InstanceMethod("rtt", &PeerConnectionWrapper::rtt),
|
|
44
|
+
InstanceMethod("getSelectedCandidatePair", &PeerConnectionWrapper::getSelectedCandidatePair),
|
|
45
|
+
});
|
|
36
46
|
|
|
37
47
|
constructor = Napi::Persistent(func);
|
|
38
48
|
constructor.SuppressDestruct();
|
|
@@ -175,9 +185,9 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
175
185
|
return;
|
|
176
186
|
}
|
|
177
187
|
std::string strPolicy = config.Get("iceTransportPolicy").As<Napi::String>().ToString();
|
|
178
|
-
if(strPolicy == "all")
|
|
188
|
+
if (strPolicy == "all")
|
|
179
189
|
rtcConfig.iceTransportPolicy = rtc::TransportPolicy::All;
|
|
180
|
-
else if(strPolicy == "relay")
|
|
190
|
+
else if (strPolicy == "relay")
|
|
181
191
|
rtcConfig.iceTransportPolicy = rtc::TransportPolicy::Relay;
|
|
182
192
|
else
|
|
183
193
|
{
|
|
@@ -218,6 +228,7 @@ void PeerConnectionWrapper::doClose()
|
|
|
218
228
|
mOnStateChangeCallback.reset();
|
|
219
229
|
mOnGatheringStateChangeCallback.reset();
|
|
220
230
|
mOnDataChannelCallback.reset();
|
|
231
|
+
mOnTrackCallback.reset();
|
|
221
232
|
|
|
222
233
|
mRtcPeerConnPtr->close();
|
|
223
234
|
mRtcPeerConnPtr.reset();
|
|
@@ -235,6 +246,42 @@ void PeerConnectionWrapper::close(const Napi::CallbackInfo &info)
|
|
|
235
246
|
doClose();
|
|
236
247
|
}
|
|
237
248
|
|
|
249
|
+
void PeerConnectionWrapper::setLocalDescription(const Napi::CallbackInfo &info)
|
|
250
|
+
{
|
|
251
|
+
Napi::Env env = info.Env();
|
|
252
|
+
if (!mRtcPeerConnPtr)
|
|
253
|
+
{
|
|
254
|
+
Napi::Error::New(info.Env(), "It seems peer-connection is closed").ThrowAsJavaScriptException();
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
int length = info.Length();
|
|
259
|
+
|
|
260
|
+
rtc::Description::Type type = rtc::Description::Type::Unspec;
|
|
261
|
+
|
|
262
|
+
// optional
|
|
263
|
+
if (length > 0)
|
|
264
|
+
{
|
|
265
|
+
if (!info[0].IsString())
|
|
266
|
+
{
|
|
267
|
+
Napi::TypeError::New(env, "type (String) expected").ThrowAsJavaScriptException();
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
std::string typeStr = info[0].As<Napi::String>().ToString();
|
|
271
|
+
|
|
272
|
+
if (typeStr == "Answer")
|
|
273
|
+
type = rtc::Description::Type::Answer;
|
|
274
|
+
if (typeStr == "Offer")
|
|
275
|
+
type = rtc::Description::Type::Offer;
|
|
276
|
+
if (typeStr == "Pranswer")
|
|
277
|
+
type = rtc::Description::Type::Pranswer;
|
|
278
|
+
if (typeStr == "Rollback")
|
|
279
|
+
type = rtc::Description::Type::Rollback;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
mRtcPeerConnPtr->setLocalDescription(type);
|
|
283
|
+
}
|
|
284
|
+
|
|
238
285
|
void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
|
|
239
286
|
{
|
|
240
287
|
Napi::Env env = info.Env();
|
|
@@ -266,6 +313,17 @@ void PeerConnectionWrapper::setRemoteDescription(const Napi::CallbackInfo &info)
|
|
|
266
313
|
}
|
|
267
314
|
}
|
|
268
315
|
|
|
316
|
+
Napi::Value PeerConnectionWrapper::localDescription(const Napi::CallbackInfo &info)
|
|
317
|
+
{
|
|
318
|
+
Napi::Env env = info.Env();
|
|
319
|
+
std::optional<rtc::Description> desc = mRtcPeerConnPtr->localDescription();
|
|
320
|
+
|
|
321
|
+
Napi::Object obj = Napi::Object::New(env);
|
|
322
|
+
obj.Set("type", desc->typeString());
|
|
323
|
+
obj.Set("sdp", desc.value());
|
|
324
|
+
return obj;
|
|
325
|
+
}
|
|
326
|
+
|
|
269
327
|
void PeerConnectionWrapper::addRemoteCandidate(const Napi::CallbackInfo &info)
|
|
270
328
|
{
|
|
271
329
|
Napi::Env env = info.Env();
|
|
@@ -428,7 +486,7 @@ Napi::Value PeerConnectionWrapper::createDataChannel(const Napi::CallbackInfo &i
|
|
|
428
486
|
init.reliability.unordered = !initConfig.Get("ordered").As<Napi::Boolean>();
|
|
429
487
|
}
|
|
430
488
|
|
|
431
|
-
if(initConfig.Get("maxPacketLifeTime").IsNumber() && initConfig.Get("maxRetransmits").IsNumber())
|
|
489
|
+
if (initConfig.Get("maxPacketLifeTime").IsNumber() && initConfig.Get("maxRetransmits").IsNumber())
|
|
432
490
|
{
|
|
433
491
|
Napi::TypeError::New(env, "Wrong DataChannel Init Config, maxPacketLifeTime and maxRetransmits are exclusive").ThrowAsJavaScriptException();
|
|
434
492
|
return info.Env().Null();
|
|
@@ -478,7 +536,8 @@ void PeerConnectionWrapper::onLocalDescription(const Napi::CallbackInfo &info)
|
|
|
478
536
|
// Callback
|
|
479
537
|
mOnLocalDescriptionCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
480
538
|
|
|
481
|
-
mRtcPeerConnPtr->onLocalDescription([&](const rtc::Description &sdp)
|
|
539
|
+
mRtcPeerConnPtr->onLocalDescription([&](const rtc::Description &sdp)
|
|
540
|
+
{
|
|
482
541
|
if (mOnLocalDescriptionCallback)
|
|
483
542
|
mOnLocalDescriptionCallback->call([this, sdp](Napi::Env env, std::vector<napi_value> &args) {
|
|
484
543
|
// Check the peer connection is not closed
|
|
@@ -490,8 +549,7 @@ void PeerConnectionWrapper::onLocalDescription(const Napi::CallbackInfo &info)
|
|
|
490
549
|
args = {
|
|
491
550
|
Napi::String::New(env, std::string(sdp)),
|
|
492
551
|
Napi::String::New(env, sdp.typeString())};
|
|
493
|
-
});
|
|
494
|
-
});
|
|
552
|
+
}); });
|
|
495
553
|
}
|
|
496
554
|
|
|
497
555
|
void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
@@ -508,7 +566,8 @@ void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
|
508
566
|
// Callback
|
|
509
567
|
mOnLocalCandidateCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
510
568
|
|
|
511
|
-
mRtcPeerConnPtr->onLocalCandidate([&](const rtc::Candidate &candidate)
|
|
569
|
+
mRtcPeerConnPtr->onLocalCandidate([&](const rtc::Candidate &candidate)
|
|
570
|
+
{
|
|
512
571
|
if (mOnLocalCandidateCallback)
|
|
513
572
|
mOnLocalCandidateCallback->call([this, candidate](Napi::Env env, std::vector<napi_value> &args) {
|
|
514
573
|
// Check the peer connection is not closed
|
|
@@ -520,8 +579,7 @@ void PeerConnectionWrapper::onLocalCandidate(const Napi::CallbackInfo &info)
|
|
|
520
579
|
args = {
|
|
521
580
|
Napi::String::New(env, std::string(candidate)),
|
|
522
581
|
Napi::String::New(env, candidate.mid())};
|
|
523
|
-
});
|
|
524
|
-
});
|
|
582
|
+
}); });
|
|
525
583
|
}
|
|
526
584
|
|
|
527
585
|
void PeerConnectionWrapper::onStateChange(const Napi::CallbackInfo &info)
|
|
@@ -538,7 +596,8 @@ void PeerConnectionWrapper::onStateChange(const Napi::CallbackInfo &info)
|
|
|
538
596
|
// Callback
|
|
539
597
|
mOnStateChangeCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
540
598
|
|
|
541
|
-
mRtcPeerConnPtr->onStateChange([&](rtc::PeerConnection::State state)
|
|
599
|
+
mRtcPeerConnPtr->onStateChange([&](rtc::PeerConnection::State state)
|
|
600
|
+
{
|
|
542
601
|
if (mOnStateChangeCallback)
|
|
543
602
|
mOnStateChangeCallback->call([this, state](Napi::Env env, std::vector<napi_value> &args) {
|
|
544
603
|
// Check the peer connection is not closed
|
|
@@ -550,8 +609,7 @@ void PeerConnectionWrapper::onStateChange(const Napi::CallbackInfo &info)
|
|
|
550
609
|
std::ostringstream stream;
|
|
551
610
|
stream << state;
|
|
552
611
|
args = {Napi::String::New(env, stream.str())};
|
|
553
|
-
});
|
|
554
|
-
});
|
|
612
|
+
}); });
|
|
555
613
|
}
|
|
556
614
|
|
|
557
615
|
void PeerConnectionWrapper::onGatheringStateChange(const Napi::CallbackInfo &info)
|
|
@@ -568,7 +626,8 @@ void PeerConnectionWrapper::onGatheringStateChange(const Napi::CallbackInfo &inf
|
|
|
568
626
|
// Callback
|
|
569
627
|
mOnGatheringStateChangeCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
570
628
|
|
|
571
|
-
mRtcPeerConnPtr->onGatheringStateChange([&](rtc::PeerConnection::GatheringState state)
|
|
629
|
+
mRtcPeerConnPtr->onGatheringStateChange([&](rtc::PeerConnection::GatheringState state)
|
|
630
|
+
{
|
|
572
631
|
if (mOnGatheringStateChangeCallback)
|
|
573
632
|
mOnGatheringStateChangeCallback->call([this, state](Napi::Env env, std::vector<napi_value> &args) {
|
|
574
633
|
// Check the peer connection is not closed
|
|
@@ -580,8 +639,7 @@ void PeerConnectionWrapper::onGatheringStateChange(const Napi::CallbackInfo &inf
|
|
|
580
639
|
std::ostringstream stream;
|
|
581
640
|
stream << state;
|
|
582
641
|
args = {Napi::String::New(env, stream.str())};
|
|
583
|
-
});
|
|
584
|
-
});
|
|
642
|
+
}); });
|
|
585
643
|
}
|
|
586
644
|
|
|
587
645
|
void PeerConnectionWrapper::onDataChannel(const Napi::CallbackInfo &info)
|
|
@@ -598,7 +656,8 @@ void PeerConnectionWrapper::onDataChannel(const Napi::CallbackInfo &info)
|
|
|
598
656
|
// Callback
|
|
599
657
|
mOnDataChannelCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
600
658
|
|
|
601
|
-
mRtcPeerConnPtr->onDataChannel([&](std::shared_ptr<rtc::DataChannel> dc)
|
|
659
|
+
mRtcPeerConnPtr->onDataChannel([&](std::shared_ptr<rtc::DataChannel> dc)
|
|
660
|
+
{
|
|
602
661
|
if (mOnDataChannelCallback)
|
|
603
662
|
mOnDataChannelCallback->call([this, dc](Napi::Env env, std::vector<napi_value> &args) {
|
|
604
663
|
// Check the peer connection is not closed
|
|
@@ -610,8 +669,7 @@ void PeerConnectionWrapper::onDataChannel(const Napi::CallbackInfo &info)
|
|
|
610
669
|
std::shared_ptr<rtc::DataChannel> dataChannel = dc;
|
|
611
670
|
auto instance = DataChannelWrapper::constructor.New({Napi::External<std::shared_ptr<rtc::DataChannel>>::New(env, &dataChannel)});
|
|
612
671
|
args = {instance};
|
|
613
|
-
});
|
|
614
|
-
});
|
|
672
|
+
}); });
|
|
615
673
|
}
|
|
616
674
|
|
|
617
675
|
Napi::Value PeerConnectionWrapper::bytesSent(const Napi::CallbackInfo &info)
|
|
@@ -746,3 +804,85 @@ std::string PeerConnectionWrapper::candidateTransportTypeToString(const rtc::Can
|
|
|
746
804
|
return "unknown";
|
|
747
805
|
}
|
|
748
806
|
}
|
|
807
|
+
|
|
808
|
+
Napi::Value PeerConnectionWrapper::addTrack(const Napi::CallbackInfo &info)
|
|
809
|
+
{
|
|
810
|
+
Napi::Env env = info.Env();
|
|
811
|
+
int length = info.Length();
|
|
812
|
+
|
|
813
|
+
if (!mRtcPeerConnPtr)
|
|
814
|
+
{
|
|
815
|
+
Napi::Error::New(info.Env(), "It seems peer-connection is closed").ThrowAsJavaScriptException();
|
|
816
|
+
return env.Null();
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
if (length < 1 || !info[0].IsObject())
|
|
820
|
+
{
|
|
821
|
+
Napi::TypeError::New(env, "Media class instance expected").ThrowAsJavaScriptException();
|
|
822
|
+
return env.Null();
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
try
|
|
826
|
+
{
|
|
827
|
+
Napi::Object obj = info[0].As<Napi::Object>();
|
|
828
|
+
if (obj.Get("media-type-video").IsBoolean())
|
|
829
|
+
{
|
|
830
|
+
VideoWrapper *videoPtr = Napi::ObjectWrap<VideoWrapper>::Unwrap(obj);
|
|
831
|
+
std::shared_ptr<rtc::Track> track = mRtcPeerConnPtr->addTrack(videoPtr->getVideoInstance());
|
|
832
|
+
auto instance = TrackWrapper::constructor.New({Napi::External<std::shared_ptr<rtc::Track>>::New(info.Env(), &track)});
|
|
833
|
+
return instance;
|
|
834
|
+
}
|
|
835
|
+
|
|
836
|
+
if (obj.Get("media-type-audio").IsBoolean())
|
|
837
|
+
{
|
|
838
|
+
AudioWrapper *audioPtr = Napi::ObjectWrap<AudioWrapper>::Unwrap(obj);
|
|
839
|
+
std::shared_ptr<rtc::Track> track = mRtcPeerConnPtr->addTrack(audioPtr->getAudioInstance());
|
|
840
|
+
auto instance = TrackWrapper::constructor.New({Napi::External<std::shared_ptr<rtc::Track>>::New(info.Env(), &track)});
|
|
841
|
+
return instance;
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
Napi::Error::New(env, std::string("Unknown media type")).ThrowAsJavaScriptException();
|
|
845
|
+
return env.Null();
|
|
846
|
+
}
|
|
847
|
+
catch (std::exception &ex)
|
|
848
|
+
{
|
|
849
|
+
Napi::Error::New(env, std::string("libdatachannel error# ") + ex.what()).ThrowAsJavaScriptException();
|
|
850
|
+
return env.Null();
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
void PeerConnectionWrapper::onTrack(const Napi::CallbackInfo &info)
|
|
855
|
+
{
|
|
856
|
+
Napi::Env env = info.Env();
|
|
857
|
+
int length = info.Length();
|
|
858
|
+
|
|
859
|
+
if (length < 1 || !info[0].IsFunction())
|
|
860
|
+
{
|
|
861
|
+
Napi::TypeError::New(env, "Function expected").ThrowAsJavaScriptException();
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
// Callback
|
|
866
|
+
mOnTrackCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
867
|
+
|
|
868
|
+
mRtcPeerConnPtr->onTrack([&](std::shared_ptr<rtc::Track> track)
|
|
869
|
+
{
|
|
870
|
+
if (mOnTrackCallback)
|
|
871
|
+
mOnTrackCallback->call([this, track](Napi::Env env, std::vector<napi_value> &args) {
|
|
872
|
+
// Check the peer connection is not closed
|
|
873
|
+
if(instances.find(this) == instances.end())
|
|
874
|
+
throw ThreadSafeCallback::CancelException();
|
|
875
|
+
|
|
876
|
+
// This will run in main thread and needs to construct the
|
|
877
|
+
// arguments for the call
|
|
878
|
+
std::shared_ptr<rtc::Track> newTrack = track;
|
|
879
|
+
auto instance = TrackWrapper::constructor.New({Napi::External<std::shared_ptr<rtc::Track>>::New(env, &newTrack)});
|
|
880
|
+
args = {instance};
|
|
881
|
+
}); });
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
Napi::Value PeerConnectionWrapper::hasMedia(const Napi::CallbackInfo &info)
|
|
885
|
+
{
|
|
886
|
+
Napi::Env env = info.Env();
|
|
887
|
+
return Napi::Boolean::New(env, mRtcPeerConnPtr->hasMedia());
|
|
888
|
+
}
|
|
@@ -21,9 +21,13 @@ public:
|
|
|
21
21
|
|
|
22
22
|
// Functions
|
|
23
23
|
void close(const Napi::CallbackInfo &info);
|
|
24
|
+
void setLocalDescription(const Napi::CallbackInfo &info);
|
|
24
25
|
void setRemoteDescription(const Napi::CallbackInfo &info);
|
|
26
|
+
Napi::Value localDescription(const Napi::CallbackInfo &info);
|
|
25
27
|
void addRemoteCandidate(const Napi::CallbackInfo &info);
|
|
26
28
|
Napi::Value createDataChannel(const Napi::CallbackInfo &info);
|
|
29
|
+
Napi::Value addTrack(const Napi::CallbackInfo &info);
|
|
30
|
+
Napi::Value hasMedia(const Napi::CallbackInfo &info);
|
|
27
31
|
|
|
28
32
|
// Callbacks
|
|
29
33
|
void onLocalDescription(const Napi::CallbackInfo &info);
|
|
@@ -31,6 +35,7 @@ public:
|
|
|
31
35
|
void onStateChange(const Napi::CallbackInfo &info);
|
|
32
36
|
void onGatheringStateChange(const Napi::CallbackInfo &info);
|
|
33
37
|
void onDataChannel(const Napi::CallbackInfo &info);
|
|
38
|
+
void onTrack(const Napi::CallbackInfo &info);
|
|
34
39
|
|
|
35
40
|
// Stats
|
|
36
41
|
Napi::Value bytesSent(const Napi::CallbackInfo &info);
|
|
@@ -43,7 +48,7 @@ public:
|
|
|
43
48
|
|
|
44
49
|
private:
|
|
45
50
|
static Napi::FunctionReference constructor;
|
|
46
|
-
static std::unordered_set<PeerConnectionWrapper*> instances;
|
|
51
|
+
static std::unordered_set<PeerConnectionWrapper *> instances;
|
|
47
52
|
|
|
48
53
|
void doClose();
|
|
49
54
|
|
|
@@ -56,6 +61,7 @@ private:
|
|
|
56
61
|
std::unique_ptr<ThreadSafeCallback> mOnStateChangeCallback = nullptr;
|
|
57
62
|
std::unique_ptr<ThreadSafeCallback> mOnGatheringStateChangeCallback = nullptr;
|
|
58
63
|
std::unique_ptr<ThreadSafeCallback> mOnDataChannelCallback = nullptr;
|
|
64
|
+
std::unique_ptr<ThreadSafeCallback> mOnTrackCallback = nullptr;
|
|
59
65
|
|
|
60
66
|
// Helpers
|
|
61
67
|
std::string candidateTypeToString(const rtc::Candidate::Type &type);
|
package/src/rtc-wrapper.cpp
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#include "rtc-wrapper.h"
|
|
2
2
|
#include "peer-connection-wrapper.h"
|
|
3
3
|
#include "data-channel-wrapper.h"
|
|
4
|
+
#include "media-track-wrapper.h"
|
|
4
5
|
|
|
5
6
|
#include <chrono>
|
|
6
7
|
#include <future>
|
|
@@ -76,6 +77,7 @@ void RtcWrapper::cleanup(const Napi::CallbackInfo &info)
|
|
|
76
77
|
{
|
|
77
78
|
PeerConnectionWrapper::CloseAll();
|
|
78
79
|
DataChannelWrapper::CloseAll();
|
|
80
|
+
TrackWrapper::CloseAll();
|
|
79
81
|
|
|
80
82
|
const auto timeout = std::chrono::seconds(10);
|
|
81
83
|
if(rtc::Cleanup().wait_for(std::chrono::seconds(timeout)) == std::future_status::timeout)
|