node-datachannel 0.29.0 → 0.31.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.
Files changed (61) hide show
  1. package/.clang-format +17 -0
  2. package/CMakeLists.txt +16 -2
  3. package/dist/cjs/lib/index.cjs +21 -0
  4. package/dist/cjs/lib/index.cjs.map +1 -1
  5. package/dist/cjs/polyfill/RTCPeerConnection.cjs +6 -1
  6. package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -1
  7. package/dist/esm/lib/index.mjs +15 -1
  8. package/dist/esm/lib/index.mjs.map +1 -1
  9. package/dist/esm/polyfill/RTCPeerConnection.mjs +6 -1
  10. package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -1
  11. package/dist/types/lib/index.d.ts +58 -4
  12. package/dist/types/lib/types.d.ts +3 -1
  13. package/package.json +3 -2
  14. package/rollup.config.mjs +1 -1
  15. package/src/cpp/data-channel-wrapper.cpp +432 -411
  16. package/src/cpp/data-channel-wrapper.h +0 -2
  17. package/src/cpp/ice-udp-mux-listener-wrapper.cpp +104 -97
  18. package/src/cpp/main.cpp +25 -11
  19. package/src/cpp/media-audio-wrapper.cpp +291 -294
  20. package/src/cpp/media-audio-wrapper.h +1 -3
  21. package/src/cpp/media-av1packetization.cpp +24 -0
  22. package/src/cpp/media-av1packetization.h +11 -0
  23. package/src/cpp/media-av1rtppacketizer-wrapper.cpp +126 -0
  24. package/src/cpp/media-av1rtppacketizer-wrapper.h +29 -0
  25. package/src/cpp/media-direction.cpp +32 -32
  26. package/src/cpp/media-direction.h +1 -1
  27. package/src/cpp/media-h264rtppacketizer-wrapper.cpp +126 -0
  28. package/src/cpp/media-h264rtppacketizer-wrapper.h +30 -0
  29. package/src/cpp/media-h265rtppacketizer-wrapper.cpp +126 -0
  30. package/src/cpp/media-h265rtppacketizer-wrapper.h +30 -0
  31. package/src/cpp/media-h26xseparator.cpp +32 -0
  32. package/src/cpp/media-h26xseparator.h +11 -0
  33. package/src/cpp/media-mediahandler-helper.cpp +28 -0
  34. package/src/cpp/media-mediahandler-helper.h +11 -0
  35. package/src/cpp/media-rtcpnackresponder-wrapper.cpp +68 -0
  36. package/src/cpp/media-rtcpnackresponder-wrapper.h +28 -0
  37. package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +38 -25
  38. package/src/cpp/media-rtcpreceivingsession-wrapper.h +1 -6
  39. package/src/cpp/media-rtcpsrreporter-wrapper.cpp +93 -0
  40. package/src/cpp/media-rtcpsrreporter-wrapper.h +30 -0
  41. package/src/cpp/media-rtppacketizationconfig-wrapper.cpp +167 -0
  42. package/src/cpp/media-rtppacketizationconfig-wrapper.h +35 -0
  43. package/src/cpp/media-rtppacketizer-wrapper.cpp +95 -0
  44. package/src/cpp/media-rtppacketizer-wrapper.h +30 -0
  45. package/src/cpp/media-track-wrapper.cpp +356 -340
  46. package/src/cpp/media-track-wrapper.h +0 -3
  47. package/src/cpp/media-video-wrapper.cpp +347 -313
  48. package/src/cpp/media-video-wrapper.h +3 -3
  49. package/src/cpp/peer-connection-wrapper.cpp +1094 -1047
  50. package/src/cpp/peer-connection-wrapper.h +0 -2
  51. package/src/cpp/rtc-wrapper.cpp +142 -138
  52. package/src/cpp/rtc-wrapper.h +8 -10
  53. package/src/cpp/thread-safe-callback.cpp +39 -50
  54. package/src/cpp/thread-safe-callback.h +26 -28
  55. package/src/cpp/web-socket-server-wrapper.cpp +205 -199
  56. package/src/cpp/web-socket-server-wrapper.h +0 -4
  57. package/src/cpp/web-socket-wrapper.cpp +625 -598
  58. package/src/cpp/web-socket-wrapper.h +0 -3
  59. package/src/lib/index.ts +69 -2
  60. package/src/lib/types.ts +6 -0
  61. package/src/polyfill/RTCPeerConnection.ts +8 -2
@@ -0,0 +1,11 @@
1
+ #ifndef MEDIA_MEDIAHANDLER_HELPER_H
2
+ #define MEDIA_MEDIAHANDLER_HELPER_H
3
+
4
+ #include <memory>
5
+
6
+ #include <napi.h>
7
+ #include <rtc/rtc.hpp>
8
+
9
+ std::shared_ptr<rtc::MediaHandler> asMediaHandler(const Napi::Object &obj);
10
+
11
+ #endif // MEDIA_MEDIAHANDLER_HELPER_H
@@ -0,0 +1,68 @@
1
+ #include "media-rtcpnackresponder-wrapper.h"
2
+ #include "media-mediahandler-helper.h"
3
+
4
+ Napi::FunctionReference RtcpNackResponderWrapper::constructor = Napi::FunctionReference();
5
+
6
+ Napi::Object RtcpNackResponderWrapper::Init(Napi::Env env, Napi::Object exports)
7
+ {
8
+ Napi::HandleScope scope(env);
9
+
10
+ Napi::Function func = Napi::ObjectWrap<RtcpNackResponderWrapper>::DefineClass(env, "RtcpNackResponder",
11
+ {
12
+ // Instance Methods
13
+ InstanceMethod("addToChain", &RtcpNackResponderWrapper::addToChain),
14
+ });
15
+
16
+ // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
17
+ if (constructor.IsEmpty())
18
+ {
19
+ constructor = Napi::Persistent(func);
20
+ constructor.SuppressDestruct();
21
+ }
22
+
23
+ exports.Set("RtcpNackResponder", func);
24
+ return exports;
25
+ }
26
+
27
+ RtcpNackResponderWrapper::RtcpNackResponderWrapper(const Napi::CallbackInfo &info)
28
+ : Napi::ObjectWrap<RtcpNackResponderWrapper>(info)
29
+ {
30
+ Napi::Env env = info.Env();
31
+
32
+ size_t maxSize = rtc::RtcpNackResponder::DefaultMaxSize;
33
+ if (info.Length() >= 1)
34
+ {
35
+ if (!info[0].IsNumber())
36
+ {
37
+ Napi::TypeError::New(env, "maxSize must be a number").ThrowAsJavaScriptException();
38
+ return;
39
+ }
40
+ maxSize = info[0].As<Napi::Number>().Int64Value();
41
+ }
42
+ mResponderPtr = std::make_unique<rtc::RtcpNackResponder>(maxSize);
43
+ }
44
+
45
+ RtcpNackResponderWrapper::~RtcpNackResponderWrapper()
46
+ {
47
+ mResponderPtr.reset();
48
+ }
49
+
50
+ std::shared_ptr<rtc::RtcpNackResponder> RtcpNackResponderWrapper::getResponderInstance() { return mResponderPtr; }
51
+
52
+ void RtcpNackResponderWrapper::addToChain(const Napi::CallbackInfo &info)
53
+ {
54
+ auto env = info.Env();
55
+ if (info.Length() < 1 || !info[0].IsObject())
56
+ {
57
+ Napi::TypeError::New(env, "Expected a MediaHandler instance").ThrowAsJavaScriptException();
58
+ return;
59
+ }
60
+ auto mediaHandler = asMediaHandler(info[0].As<Napi::Object>());
61
+ if (!mediaHandler)
62
+ {
63
+ Napi::TypeError::New(env, "Expected a MediaHandler instance. If this error is unexpected, please report a bug!")
64
+ .ThrowAsJavaScriptException();
65
+ return;
66
+ }
67
+ mResponderPtr->addToChain(mediaHandler);
68
+ }
@@ -0,0 +1,28 @@
1
+ #ifndef MEDIA_RTCPNACKRESPONDER_WRAPPER_H
2
+ #define MEDIA_RTCPNACKRESPONDER_WRAPPER_H
3
+
4
+ #include <memory>
5
+ #include <unordered_set>
6
+
7
+ #include <napi.h>
8
+ #include <rtc/rtc.hpp>
9
+
10
+ class RtcpNackResponderWrapper : public Napi::ObjectWrap<RtcpNackResponderWrapper>
11
+ {
12
+ public:
13
+ static Napi::FunctionReference constructor;
14
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
15
+ RtcpNackResponderWrapper(const Napi::CallbackInfo &info);
16
+ ~RtcpNackResponderWrapper();
17
+ std::shared_ptr<rtc::RtcpNackResponder> getResponderInstance();
18
+
19
+ // Functions
20
+ void addToChain(const Napi::CallbackInfo &info);
21
+
22
+ // Callbacks
23
+
24
+ private:
25
+ std::shared_ptr<rtc::RtcpNackResponder> mResponderPtr = nullptr;
26
+ };
27
+
28
+ #endif // MEDIA_RTCPNACKRESPONDER_WRAPPER_H
@@ -1,44 +1,57 @@
1
1
  #include "media-rtcpreceivingsession-wrapper.h"
2
+ #include "media-mediahandler-helper.h"
2
3
 
3
4
  Napi::FunctionReference RtcpReceivingSessionWrapper::constructor = Napi::FunctionReference();
4
- std::unordered_set<RtcpReceivingSessionWrapper *> RtcpReceivingSessionWrapper::instances;
5
5
 
6
6
  Napi::Object RtcpReceivingSessionWrapper::Init(Napi::Env env, Napi::Object exports)
7
7
  {
8
- Napi::HandleScope scope(env);
8
+ Napi::HandleScope scope(env);
9
9
 
10
- Napi::Function func = Napi::ObjectWrap<RtcpReceivingSessionWrapper>::DefineClass(
11
- env,
12
- "RtcpReceivingSession",
13
- {
14
- // Instance Methods
15
- });
16
-
17
- // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
18
- if(constructor.IsEmpty())
10
+ Napi::Function func = Napi::ObjectWrap<RtcpReceivingSessionWrapper>::DefineClass(env, "RtcpReceivingSession",
19
11
  {
20
- constructor = Napi::Persistent(func);
21
- constructor.SuppressDestruct();
22
- }
23
-
24
- exports.Set("RtcpReceivingSession", func);
25
- return exports;
12
+ // Instance Methods
13
+ InstanceMethod("addToChain", &RtcpReceivingSessionWrapper::addToChain),
14
+ });
15
+
16
+ // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
17
+ if (constructor.IsEmpty())
18
+ {
19
+ constructor = Napi::Persistent(func);
20
+ constructor.SuppressDestruct();
21
+ }
22
+
23
+ exports.Set("RtcpReceivingSession", func);
24
+ return exports;
26
25
  }
27
26
 
28
- RtcpReceivingSessionWrapper::RtcpReceivingSessionWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<RtcpReceivingSessionWrapper>(info)
27
+ RtcpReceivingSessionWrapper::RtcpReceivingSessionWrapper(const Napi::CallbackInfo &info)
28
+ : Napi::ObjectWrap<RtcpReceivingSessionWrapper>(info)
29
29
  {
30
- Napi::Env env = info.Env();
31
- mSessionPtr = std::make_unique<rtc::RtcpReceivingSession>();
32
- instances.insert(this);
30
+ Napi::Env env = info.Env();
31
+ mSessionPtr = std::make_unique<rtc::RtcpReceivingSession>();
33
32
  }
34
33
 
35
34
  RtcpReceivingSessionWrapper::~RtcpReceivingSessionWrapper()
36
35
  {
37
- mSessionPtr.reset();
38
- instances.erase(this);
36
+ mSessionPtr.reset();
39
37
  }
40
38
 
41
- std::shared_ptr<rtc::RtcpReceivingSession> RtcpReceivingSessionWrapper::getSessionInstance()
39
+ std::shared_ptr<rtc::RtcpReceivingSession> RtcpReceivingSessionWrapper::getSessionInstance() { return mSessionPtr; }
40
+
41
+ void RtcpReceivingSessionWrapper::addToChain(const Napi::CallbackInfo &info)
42
42
  {
43
- return mSessionPtr;
43
+ auto env = info.Env();
44
+ if (info.Length() < 1 || !info[0].IsObject())
45
+ {
46
+ Napi::TypeError::New(env, "Expected a MediaHandler instance").ThrowAsJavaScriptException();
47
+ return;
48
+ }
49
+ auto mediaHandler = asMediaHandler(info[0].As<Napi::Object>());
50
+ if (!mediaHandler)
51
+ {
52
+ Napi::TypeError::New(env, "Expected a MediaHandler instance. If this error is unexpected, please report a bug!")
53
+ .ThrowAsJavaScriptException();
54
+ return;
55
+ }
56
+ mSessionPtr->addToChain(mediaHandler);
44
57
  }
@@ -1,17 +1,12 @@
1
1
  #ifndef MEDIA_RTCPRECEIVINGSESSION_WRAPPER_H
2
2
  #define MEDIA_RTCPRECEIVINGSESSION_WRAPPER_H
3
3
 
4
- #include <iostream>
5
- #include <string>
6
- #include <variant>
7
4
  #include <memory>
8
5
  #include <unordered_set>
9
6
 
10
7
  #include <napi.h>
11
8
  #include <rtc/rtc.hpp>
12
9
 
13
- #include "thread-safe-callback.h"
14
-
15
10
  class RtcpReceivingSessionWrapper : public Napi::ObjectWrap<RtcpReceivingSessionWrapper>
16
11
  {
17
12
  public:
@@ -22,11 +17,11 @@ public:
22
17
  std::shared_ptr<rtc::RtcpReceivingSession> getSessionInstance();
23
18
 
24
19
  // Functions
20
+ void addToChain(const Napi::CallbackInfo &info);
25
21
 
26
22
  // Callbacks
27
23
 
28
24
  private:
29
- static std::unordered_set<RtcpReceivingSessionWrapper *> instances;
30
25
  std::shared_ptr<rtc::RtcpReceivingSession> mSessionPtr = nullptr;
31
26
  };
32
27
 
@@ -0,0 +1,93 @@
1
+ #include "media-rtcpsrreporter-wrapper.h"
2
+ #include "media-rtppacketizationconfig-wrapper.h"
3
+ #include "media-mediahandler-helper.h"
4
+
5
+ Napi::FunctionReference RtcpSrReporterWrapper::constructor = Napi::FunctionReference();
6
+
7
+ Napi::Object RtcpSrReporterWrapper::Init(Napi::Env env, Napi::Object exports)
8
+ {
9
+ Napi::HandleScope scope(env);
10
+
11
+ Napi::Function func = Napi::ObjectWrap<RtcpSrReporterWrapper>::DefineClass(env, "RtcpSrReporter",
12
+ {
13
+ // Instance Methods
14
+ InstanceMethod("addToChain", &RtcpSrReporterWrapper::addToChain),
15
+ // Accessors
16
+ InstanceAccessor("rtpConfig", &RtcpSrReporterWrapper::getRtpPacketizationConfig, nullptr),
17
+ });
18
+
19
+ // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
20
+ if (constructor.IsEmpty())
21
+ {
22
+ constructor = Napi::Persistent(func);
23
+ constructor.SuppressDestruct();
24
+ }
25
+
26
+ exports.Set("RtcpSrReporter", func);
27
+ return exports;
28
+ }
29
+
30
+ RtcpSrReporterWrapper::RtcpSrReporterWrapper(const Napi::CallbackInfo &info)
31
+ : Napi::ObjectWrap<RtcpSrReporterWrapper>(info)
32
+ {
33
+ Napi::Env env = info.Env();
34
+
35
+ if (!info[0].IsObject())
36
+ {
37
+ Napi::TypeError::New(env, "Expected a RtpPacketizationConfig object").ThrowAsJavaScriptException();
38
+ return;
39
+ }
40
+
41
+ auto obj = info[0].As<Napi::Object>();
42
+ if (!obj.InstanceOf(RtpPacketizationConfigWrapper::constructor.Value()))
43
+ {
44
+ Napi::TypeError::New(env, "Expected a RtpPacketizationConfig object").ThrowAsJavaScriptException();
45
+ return;
46
+ }
47
+ // store original JS object so we can return it later
48
+ mRtpConfigObject = Napi::Persistent(obj);
49
+ mRtpConfigObject.SuppressDestruct();
50
+ auto config = RtpPacketizationConfigWrapper::Unwrap(obj);
51
+ mReporterPtr = std::make_unique<rtc::RtcpSrReporter>(config->getConfigInstance());
52
+ }
53
+
54
+ RtcpSrReporterWrapper::~RtcpSrReporterWrapper()
55
+ {
56
+ mReporterPtr.reset();
57
+ mRtpConfigObject.Reset();
58
+ }
59
+
60
+ std::shared_ptr<rtc::RtcpSrReporter> RtcpSrReporterWrapper::getReporterInstance() { return mReporterPtr; }
61
+
62
+ void RtcpSrReporterWrapper::addToChain(const Napi::CallbackInfo &info)
63
+ {
64
+ auto env = info.Env();
65
+ if (info.Length() < 1 || !info[0].IsObject())
66
+ {
67
+ Napi::TypeError::New(env, "Expected a MediaHandler instance").ThrowAsJavaScriptException();
68
+ return;
69
+ }
70
+ auto mediaHandler = asMediaHandler(info[0].As<Napi::Object>());
71
+ if (!mediaHandler)
72
+ {
73
+ Napi::TypeError::New(env, "Expected a MediaHandler instance. If this error is unexpected, please report a bug!")
74
+ .ThrowAsJavaScriptException();
75
+ return;
76
+ }
77
+ mReporterPtr->addToChain(mediaHandler);
78
+ }
79
+
80
+ Napi::Value RtcpSrReporterWrapper::getRtpPacketizationConfig(const Napi::CallbackInfo &info)
81
+ {
82
+ Napi::Env env = info.Env();
83
+ if (!mReporterPtr)
84
+ {
85
+ Napi::Error::New(env, "getRtpPacketizationConfig() called on destroyed reporter").ThrowAsJavaScriptException();
86
+ return env.Null();
87
+ }
88
+
89
+ if (mRtpConfigObject.IsEmpty())
90
+ return env.Null();
91
+
92
+ return mRtpConfigObject.Value();
93
+ }
@@ -0,0 +1,30 @@
1
+ #ifndef MEDIA_RTCPSRREPORTER_WRAPPER_H
2
+ #define MEDIA_RTCPSRREPORTER_WRAPPER_H
3
+
4
+ #include <memory>
5
+ #include <unordered_set>
6
+
7
+ #include <napi.h>
8
+ #include <rtc/rtc.hpp>
9
+
10
+ class RtcpSrReporterWrapper : public Napi::ObjectWrap<RtcpSrReporterWrapper>
11
+ {
12
+ public:
13
+ static Napi::FunctionReference constructor;
14
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
15
+ RtcpSrReporterWrapper(const Napi::CallbackInfo &info);
16
+ ~RtcpSrReporterWrapper();
17
+ std::shared_ptr<rtc::RtcpSrReporter> getReporterInstance();
18
+
19
+ // Functions
20
+ void addToChain(const Napi::CallbackInfo &info);
21
+ Napi::Value getRtpPacketizationConfig(const Napi::CallbackInfo &info);
22
+
23
+ // Callbacks
24
+
25
+ private:
26
+ std::shared_ptr<rtc::RtcpSrReporter> mReporterPtr = nullptr;
27
+ Napi::ObjectReference mRtpConfigObject;
28
+ };
29
+
30
+ #endif // MEDIA_RTCPSRREPORTER_WRAPPER_H
@@ -0,0 +1,167 @@
1
+ #include "media-rtppacketizationconfig-wrapper.h"
2
+
3
+ Napi::FunctionReference RtpPacketizationConfigWrapper::constructor = Napi::FunctionReference();
4
+
5
+ Napi::Object RtpPacketizationConfigWrapper::Init(Napi::Env env, Napi::Object exports)
6
+ {
7
+ Napi::HandleScope scope(env);
8
+
9
+ Napi::Function func = Napi::ObjectWrap<RtpPacketizationConfigWrapper>::DefineClass(env, "RtpPacketizationConfig",
10
+ {
11
+ // Instance Methods
12
+ InstanceAccessor("playoutDelayId",
13
+ &RtpPacketizationConfigWrapper::getPlayoutDelayId,
14
+ &RtpPacketizationConfigWrapper::setPlayoutDelayId
15
+ ),
16
+ InstanceAccessor("playoutDelayMin",
17
+ &RtpPacketizationConfigWrapper::getPlayoutDelayMin,
18
+ &RtpPacketizationConfigWrapper::setPlayoutDelayMin
19
+ ),
20
+ InstanceAccessor("playoutDelayMax",
21
+ &RtpPacketizationConfigWrapper::getPlayoutDelayMax,
22
+ &RtpPacketizationConfigWrapper::setPlayoutDelayMax
23
+ ),
24
+ InstanceAccessor("timestamp",
25
+ &RtpPacketizationConfigWrapper::getTimestamp,
26
+ &RtpPacketizationConfigWrapper::setTimestamp
27
+ ),
28
+ InstanceAccessor("clockRate",
29
+ &RtpPacketizationConfigWrapper::getClockRate,
30
+ nullptr
31
+ ),
32
+ });
33
+
34
+ // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
35
+ if (constructor.IsEmpty())
36
+ {
37
+ constructor = Napi::Persistent(func);
38
+ constructor.SuppressDestruct();
39
+ }
40
+
41
+ exports.Set("RtpPacketizationConfig", func);
42
+ return exports;
43
+ }
44
+
45
+ RtpPacketizationConfigWrapper::RtpPacketizationConfigWrapper(const Napi::CallbackInfo &info)
46
+ : Napi::ObjectWrap<RtpPacketizationConfigWrapper>(info)
47
+ {
48
+ Napi::Env env = info.Env();
49
+
50
+ if (info.Length() < 4)
51
+ {
52
+ Napi::Error::New(env, "RtpPacketizationConfig constructor requires 4 or 5 parameters").ThrowAsJavaScriptException();
53
+ return;
54
+ }
55
+
56
+ rtc::SSRC ssrc;
57
+ if (!info[0].IsNumber())
58
+ {
59
+ Napi::TypeError::New(env, "ssrc must be a number").ThrowAsJavaScriptException();
60
+ return;
61
+ }
62
+ ssrc = info[0].As<Napi::Number>().Uint32Value();
63
+
64
+ std::string cname;
65
+ if (!info[1].IsString())
66
+ {
67
+ Napi::TypeError::New(env, "cname must be a string").ThrowAsJavaScriptException();
68
+ return;
69
+ }
70
+ cname = info[1].As<Napi::String>().Utf8Value();
71
+
72
+ uint8_t payloadType;
73
+ if (!info[2].IsNumber())
74
+ {
75
+ Napi::TypeError::New(env, "payloadType must be a number").ThrowAsJavaScriptException();
76
+ return;
77
+ }
78
+ payloadType = info[2].As<Napi::Number>().Uint32Value();
79
+
80
+ uint32_t clockRate;
81
+ if (!info[3].IsNumber())
82
+ {
83
+ Napi::TypeError::New(env, "clockRate must be a number").ThrowAsJavaScriptException();
84
+ return;
85
+ }
86
+ clockRate = info[3].As<Napi::Number>().Uint32Value();
87
+
88
+ uint8_t videoOrientationId = 0;
89
+ if (info.Length() >= 5)
90
+ {
91
+ if (!info[4].IsNumber())
92
+ {
93
+ Napi::TypeError::New(env, "videoOrientationId must be a number").ThrowAsJavaScriptException();
94
+ return;
95
+ }
96
+ videoOrientationId = info[4].As<Napi::Number>().Uint32Value();
97
+ }
98
+ mConfigPtr = std::make_unique<rtc::RtpPacketizationConfig>(ssrc, cname, payloadType, clockRate, videoOrientationId);
99
+ }
100
+
101
+ RtpPacketizationConfigWrapper::~RtpPacketizationConfigWrapper()
102
+ {
103
+ mConfigPtr.reset();
104
+ }
105
+
106
+ std::shared_ptr<rtc::RtpPacketizationConfig> RtpPacketizationConfigWrapper::getConfigInstance() { return mConfigPtr; }
107
+
108
+ Napi::Value RtpPacketizationConfigWrapper::getPlayoutDelayId(const Napi::CallbackInfo &info)
109
+ {
110
+ return Napi::Number::New(info.Env(), mConfigPtr->playoutDelayId);
111
+ }
112
+ void RtpPacketizationConfigWrapper::setPlayoutDelayId(const Napi::CallbackInfo &info, const Napi::Value &val)
113
+ {
114
+ auto env = info.Env();
115
+ if (!val.IsNumber())
116
+ {
117
+ Napi::TypeError::New(env, "Expected a number").ThrowAsJavaScriptException();
118
+ return;
119
+ }
120
+ mConfigPtr->playoutDelayId = val.As<Napi::Number>().Uint32Value();
121
+ }
122
+ Napi::Value RtpPacketizationConfigWrapper::getPlayoutDelayMin(const Napi::CallbackInfo &info)
123
+ {
124
+ return Napi::Number::New(info.Env(), mConfigPtr->playoutDelayMin);
125
+ }
126
+ void RtpPacketizationConfigWrapper::setPlayoutDelayMin(const Napi::CallbackInfo &info, const Napi::Value &val)
127
+ {
128
+ auto env = info.Env();
129
+ if (!val.IsNumber())
130
+ {
131
+ Napi::TypeError::New(env, "Expected a number").ThrowAsJavaScriptException();
132
+ return;
133
+ }
134
+ mConfigPtr->playoutDelayMin = val.As<Napi::Number>().Uint32Value();
135
+ }
136
+ Napi::Value RtpPacketizationConfigWrapper::getPlayoutDelayMax(const Napi::CallbackInfo &info)
137
+ {
138
+ return Napi::Number::New(info.Env(), mConfigPtr->playoutDelayMax);
139
+ }
140
+ void RtpPacketizationConfigWrapper::setPlayoutDelayMax(const Napi::CallbackInfo &info, const Napi::Value &val)
141
+ {
142
+ auto env = info.Env();
143
+ if (!val.IsNumber())
144
+ {
145
+ Napi::TypeError::New(env, "Expected a number").ThrowAsJavaScriptException();
146
+ return;
147
+ }
148
+ mConfigPtr->playoutDelayMax = val.As<Napi::Number>().Uint32Value();
149
+ }
150
+ Napi::Value RtpPacketizationConfigWrapper::getTimestamp(const Napi::CallbackInfo &info)
151
+ {
152
+ return Napi::Number::New(info.Env(), mConfigPtr->timestamp);
153
+ }
154
+ void RtpPacketizationConfigWrapper::setTimestamp(const Napi::CallbackInfo &info, const Napi::Value &val)
155
+ {
156
+ auto env = info.Env();
157
+ if (!val.IsNumber())
158
+ {
159
+ Napi::TypeError::New(env, "Expected a number").ThrowAsJavaScriptException();
160
+ return;
161
+ }
162
+ mConfigPtr->timestamp = val.As<Napi::Number>().Uint32Value();
163
+ }
164
+ Napi::Value RtpPacketizationConfigWrapper::getClockRate(const Napi::CallbackInfo &info)
165
+ {
166
+ return Napi::Number::New(info.Env(), mConfigPtr->clockRate);
167
+ }
@@ -0,0 +1,35 @@
1
+ #ifndef MEDIA_RTPPACKETIZATIONCONFIG_WRAPPER_H
2
+ #define MEDIA_RTPPACKETIZATIONCONFIG_WRAPPER_H
3
+
4
+ #include <memory>
5
+ #include <unordered_set>
6
+
7
+ #include <napi.h>
8
+ #include <rtc/rtc.hpp>
9
+
10
+ class RtpPacketizationConfigWrapper : public Napi::ObjectWrap<RtpPacketizationConfigWrapper>
11
+ {
12
+ public:
13
+ static Napi::FunctionReference constructor;
14
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
15
+ RtpPacketizationConfigWrapper(const Napi::CallbackInfo &info);
16
+ ~RtpPacketizationConfigWrapper();
17
+ std::shared_ptr<rtc::RtpPacketizationConfig> getConfigInstance();
18
+
19
+ // Functions
20
+ Napi::Value getPlayoutDelayId(const Napi::CallbackInfo& info);
21
+ void setPlayoutDelayId(const Napi::CallbackInfo& info, const Napi::Value &val);
22
+ Napi::Value getPlayoutDelayMin(const Napi::CallbackInfo& info);
23
+ void setPlayoutDelayMin(const Napi::CallbackInfo& info, const Napi::Value &val);
24
+ Napi::Value getPlayoutDelayMax(const Napi::CallbackInfo& info);
25
+ void setPlayoutDelayMax(const Napi::CallbackInfo& info, const Napi::Value &val);
26
+ Napi::Value getTimestamp(const Napi::CallbackInfo& info);
27
+ void setTimestamp(const Napi::CallbackInfo& info, const Napi::Value &val);
28
+ Napi::Value getClockRate(const Napi::CallbackInfo& info);
29
+ // Callbacks
30
+
31
+ private:
32
+ std::shared_ptr<rtc::RtpPacketizationConfig> mConfigPtr = nullptr;
33
+ };
34
+
35
+ #endif // MEDIA_RTPPACKETIZATIONCONFIG_WRAPPER_H
@@ -0,0 +1,95 @@
1
+ #include "media-rtppacketizer-wrapper.h"
2
+ #include "media-rtppacketizationconfig-wrapper.h"
3
+ #include "media-mediahandler-helper.h"
4
+
5
+ Napi::FunctionReference RtpPacketizerWrapper::constructor = Napi::FunctionReference();
6
+
7
+ Napi::Object RtpPacketizerWrapper::Init(Napi::Env env, Napi::Object exports)
8
+ {
9
+ Napi::HandleScope scope(env);
10
+
11
+ Napi::Function func = Napi::ObjectWrap<RtpPacketizerWrapper>::DefineClass(env, "RtpPacketizer",
12
+ {
13
+ // Instance Methods
14
+ InstanceMethod("addToChain", &RtpPacketizerWrapper::addToChain),
15
+ // Accessors
16
+ InstanceAccessor("rtpConfig", &RtpPacketizerWrapper::getRtpPacketizationConfig, nullptr),
17
+ });
18
+
19
+ // If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
20
+ if (constructor.IsEmpty())
21
+ {
22
+ constructor = Napi::Persistent(func);
23
+ constructor.SuppressDestruct();
24
+ }
25
+
26
+ exports.Set("RtpPacketizer", func);
27
+ return exports;
28
+ }
29
+
30
+ RtpPacketizerWrapper::RtpPacketizerWrapper(const Napi::CallbackInfo &info)
31
+ : Napi::ObjectWrap<RtpPacketizerWrapper>(info)
32
+ {
33
+ Napi::Env env = info.Env();
34
+
35
+ if (!info[0].IsObject())
36
+ {
37
+ Napi::TypeError::New(env, "rtpConfig must be a RtpPacketizationConfig instance").ThrowAsJavaScriptException();
38
+ return;
39
+ }
40
+ auto obj = info[0].As<Napi::Object>();
41
+ if (!obj.InstanceOf(RtpPacketizationConfigWrapper::constructor.Value()))
42
+ {
43
+ Napi::TypeError::New(env, "rtpConfig must be a RtpPacketizationConfig instance").ThrowAsJavaScriptException();
44
+ return;
45
+ }
46
+ // store original JS object so we can return it later
47
+ mRtpConfigObject = Napi::Persistent(obj);
48
+ mRtpConfigObject.SuppressDestruct();
49
+ auto rtpConfig = RtpPacketizationConfigWrapper::Unwrap(obj)->getConfigInstance();
50
+
51
+ mPacketizerPtr = std::make_unique<rtc::RtpPacketizer>(rtpConfig);
52
+
53
+ auto asMediaHandler = new std::shared_ptr<rtc::MediaHandler>(mPacketizerPtr);
54
+ }
55
+
56
+ RtpPacketizerWrapper::~RtpPacketizerWrapper()
57
+ {
58
+ mPacketizerPtr.reset();
59
+ mRtpConfigObject.Reset();
60
+ }
61
+
62
+ std::shared_ptr<rtc::RtpPacketizer> RtpPacketizerWrapper::getPacketizerInstance() { return mPacketizerPtr; }
63
+
64
+ void RtpPacketizerWrapper::addToChain(const Napi::CallbackInfo &info)
65
+ {
66
+ auto env = info.Env();
67
+ if (info.Length() < 1 || !info[0].IsObject())
68
+ {
69
+ Napi::TypeError::New(env, "Expected a MediaHandler instance").ThrowAsJavaScriptException();
70
+ return;
71
+ }
72
+ auto mediaHandler = asMediaHandler(info[0].As<Napi::Object>());
73
+ if (!mediaHandler)
74
+ {
75
+ Napi::TypeError::New(env, "Expected a MediaHandler instance. If this error is unexpected, please report a bug!")
76
+ .ThrowAsJavaScriptException();
77
+ return;
78
+ }
79
+ mPacketizerPtr->addToChain(mediaHandler);
80
+ }
81
+
82
+ Napi::Value RtpPacketizerWrapper::getRtpPacketizationConfig(const Napi::CallbackInfo &info)
83
+ {
84
+ Napi::Env env = info.Env();
85
+ if (!mPacketizerPtr)
86
+ {
87
+ Napi::Error::New(env, "getRtpPacketizationConfig() called on destroyed packetizer").ThrowAsJavaScriptException();
88
+ return env.Null();
89
+ }
90
+
91
+ if (mRtpConfigObject.IsEmpty())
92
+ return env.Null();
93
+
94
+ return mRtpConfigObject.Value();
95
+ }
@@ -0,0 +1,30 @@
1
+ #ifndef MEDIA_RTPPACKETIZER_WRAPPER_H
2
+ #define MEDIA_RTPPACKETIZER_WRAPPER_H
3
+
4
+ #include <memory>
5
+ #include <unordered_set>
6
+
7
+ #include <napi.h>
8
+ #include <rtc/rtc.hpp>
9
+
10
+ class RtpPacketizerWrapper : public Napi::ObjectWrap<RtpPacketizerWrapper>
11
+ {
12
+ public:
13
+ static Napi::FunctionReference constructor;
14
+ static Napi::Object Init(Napi::Env env, Napi::Object exports);
15
+ RtpPacketizerWrapper(const Napi::CallbackInfo &info);
16
+ ~RtpPacketizerWrapper();
17
+ std::shared_ptr<rtc::RtpPacketizer> getPacketizerInstance();
18
+
19
+ // Functions
20
+ void addToChain(const Napi::CallbackInfo &info);
21
+ Napi::Value getRtpPacketizationConfig(const Napi::CallbackInfo &info);
22
+
23
+ // Callbacks
24
+
25
+ private:
26
+ std::shared_ptr<rtc::RtpPacketizer> mPacketizerPtr = nullptr;
27
+ Napi::ObjectReference mRtpConfigObject;
28
+ };
29
+
30
+ #endif // MEDIA_RTPPACKETIZER_WRAPPER_H