node-datachannel 0.30.0 → 0.32.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 (43) hide show
  1. package/CMakeLists.txt +13 -2
  2. package/dist/cjs/lib/index.cjs +24 -0
  3. package/dist/cjs/lib/index.cjs.map +1 -1
  4. package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -1
  5. package/dist/esm/lib/index.mjs +17 -1
  6. package/dist/esm/lib/index.mjs.map +1 -1
  7. package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -1
  8. package/dist/types/lib/index.d.ts +64 -4
  9. package/dist/types/lib/types.d.ts +3 -1
  10. package/dist/types/polyfill/RTCPeerConnection.d.ts +2 -1
  11. package/package.json +1 -1
  12. package/rollup.config.mjs +1 -1
  13. package/src/cpp/main.cpp +16 -0
  14. package/src/cpp/media-av1packetization.cpp +24 -0
  15. package/src/cpp/media-av1packetization.h +11 -0
  16. package/src/cpp/media-av1rtppacketizer-wrapper.cpp +126 -0
  17. package/src/cpp/media-av1rtppacketizer-wrapper.h +29 -0
  18. package/src/cpp/media-h264rtppacketizer-wrapper.cpp +126 -0
  19. package/src/cpp/media-h264rtppacketizer-wrapper.h +30 -0
  20. package/src/cpp/media-h265rtppacketizer-wrapper.cpp +126 -0
  21. package/src/cpp/media-h265rtppacketizer-wrapper.h +30 -0
  22. package/src/cpp/media-h26xseparator.cpp +32 -0
  23. package/src/cpp/media-h26xseparator.h +11 -0
  24. package/src/cpp/media-mediahandler-helper.cpp +31 -0
  25. package/src/cpp/media-mediahandler-helper.h +11 -0
  26. package/src/cpp/media-pacinghandler-wrapper.cpp +79 -0
  27. package/src/cpp/media-pacinghandler-wrapper.h +28 -0
  28. package/src/cpp/media-rtcpnackresponder-wrapper.cpp +68 -0
  29. package/src/cpp/media-rtcpnackresponder-wrapper.h +28 -0
  30. package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +23 -6
  31. package/src/cpp/media-rtcpreceivingsession-wrapper.h +1 -1
  32. package/src/cpp/media-rtcpsrreporter-wrapper.cpp +93 -0
  33. package/src/cpp/media-rtcpsrreporter-wrapper.h +30 -0
  34. package/src/cpp/media-rtppacketizationconfig-wrapper.cpp +167 -0
  35. package/src/cpp/media-rtppacketizationconfig-wrapper.h +35 -0
  36. package/src/cpp/media-rtppacketizer-wrapper.cpp +95 -0
  37. package/src/cpp/media-rtppacketizer-wrapper.h +30 -0
  38. package/src/cpp/media-track-wrapper.cpp +9 -4
  39. package/src/cpp/media-video-wrapper.cpp +36 -1
  40. package/src/cpp/media-video-wrapper.h +2 -0
  41. package/src/lib/index.ts +76 -2
  42. package/src/lib/types.ts +6 -0
  43. package/src/polyfill/RTCPeerConnection.ts +1 -1
@@ -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
@@ -1,6 +1,6 @@
1
1
  #include "media-track-wrapper.h"
2
2
  #include "media-direction.h"
3
- #include "media-rtcpreceivingsession-wrapper.h"
3
+ #include "media-mediahandler-helper.h"
4
4
 
5
5
  #include "plog/Log.h"
6
6
 
@@ -292,9 +292,14 @@ void TrackWrapper::setMediaHandler(const Napi::CallbackInfo &info)
292
292
  return;
293
293
  }
294
294
 
295
- RtcpReceivingSessionWrapper *handler =
296
- Napi::ObjectWrap<RtcpReceivingSessionWrapper>::Unwrap(info[0].As<Napi::Object>());
297
- mTrackPtr->setMediaHandler(handler->getSessionInstance());
295
+ std::shared_ptr<rtc::MediaHandler> handler = asMediaHandler(info[0].As<Napi::Object>());
296
+ if (!handler)
297
+ {
298
+ Napi::TypeError::New(env, "MediaHandler class instance expected. If this error is unexpected, please report a bug!")
299
+ .ThrowAsJavaScriptException();
300
+ return;
301
+ }
302
+ mTrackPtr->setMediaHandler(handler);
298
303
  }
299
304
 
300
305
  void TrackWrapper::onOpen(const Napi::CallbackInfo &info)
@@ -12,10 +12,12 @@ Napi::Object VideoWrapper::Init(Napi::Env env, Napi::Object exports)
12
12
  Napi::ObjectWrap<VideoWrapper>::DefineClass(env, "Video",
13
13
  {
14
14
  InstanceValue("media-type-video", Napi::Boolean::New(env, true)),
15
- InstanceMethod("addH264Codec", &VideoWrapper::addH264Codec),
16
15
  InstanceMethod("addVideoCodec", &VideoWrapper::addVideoCodec),
16
+ InstanceMethod("addH264Codec", &VideoWrapper::addH264Codec),
17
+ InstanceMethod("addH265Codec", &VideoWrapper::addH265Codec),
17
18
  InstanceMethod("addVP8Codec", &VideoWrapper::addVP8Codec),
18
19
  InstanceMethod("addVP9Codec", &VideoWrapper::addVP9Codec),
20
+ InstanceMethod("addAV1Codec", &VideoWrapper::addAV1Codec),
19
21
  InstanceMethod("direction", &VideoWrapper::direction),
20
22
  InstanceMethod("generateSdp", &VideoWrapper::generateSdp),
21
23
  InstanceMethod("mid", &VideoWrapper::mid),
@@ -147,6 +149,22 @@ void VideoWrapper::addH264Codec(const Napi::CallbackInfo &info)
147
149
  mVideoPtr->addH264Codec(payloadType, profile);
148
150
  }
149
151
 
152
+ void VideoWrapper::addH265Codec(const Napi::CallbackInfo &info)
153
+ {
154
+ Napi::Env env = info.Env();
155
+ int length = info.Length();
156
+
157
+ if (length < 1 || !info[0].IsNumber())
158
+ {
159
+ Napi::TypeError::New(env, "We expect (Number) as param").ThrowAsJavaScriptException();
160
+ return;
161
+ }
162
+
163
+ int payloadType = info[0].As<Napi::Number>().ToNumber();
164
+
165
+ mVideoPtr->addH265Codec(payloadType);
166
+ }
167
+
150
168
  void VideoWrapper::addVP8Codec(const Napi::CallbackInfo &info)
151
169
  {
152
170
  Napi::Env env = info.Env();
@@ -179,6 +197,23 @@ void VideoWrapper::addVP9Codec(const Napi::CallbackInfo &info)
179
197
  mVideoPtr->addVP9Codec(payloadType);
180
198
  }
181
199
 
200
+ void VideoWrapper::addAV1Codec(const Napi::CallbackInfo &info)
201
+ {
202
+ Napi::Env env = info.Env();
203
+ int length = info.Length();
204
+
205
+ if (length < 1 || !info[0].IsNumber())
206
+ {
207
+ Napi::TypeError::New(env, "We expect (Number) as param").ThrowAsJavaScriptException();
208
+ return;
209
+ }
210
+
211
+ int payloadType = info[0].As<Napi::Number>().ToNumber();
212
+
213
+ mVideoPtr->addAV1Codec(payloadType);
214
+ }
215
+
216
+
182
217
  Napi::Value VideoWrapper::direction(const Napi::CallbackInfo &info)
183
218
  {
184
219
  Napi::Env env = info.Env();
@@ -19,8 +19,10 @@ public:
19
19
  // Functions
20
20
  void addVideoCodec(const Napi::CallbackInfo &info);
21
21
  void addH264Codec(const Napi::CallbackInfo &info);
22
+ void addH265Codec(const Napi::CallbackInfo &info);
22
23
  void addVP8Codec(const Napi::CallbackInfo &info);
23
24
  void addVP9Codec(const Napi::CallbackInfo &info);
25
+ void addAV1Codec(const Napi::CallbackInfo &info);
24
26
 
25
27
  // class Entry
26
28
  Napi::Value direction(const Napi::CallbackInfo &info);
package/src/lib/index.ts CHANGED
@@ -7,6 +7,8 @@ import {
7
7
  DescriptionType,
8
8
  Direction,
9
9
  LogLevel,
10
+ NalUnitSeparator,
11
+ ObuPacketization,
10
12
  RtcConfig,
11
13
  RTCIceConnectionState,
12
14
  RTCIceGatheringState,
@@ -63,8 +65,10 @@ export const Audio: {
63
65
  export interface Video {
64
66
  addVideoCodec(payloadType: number, codec: string, profile?: string): void;
65
67
  addH264Codec(payloadType: number, profile?: string): void;
68
+ addH265Codec(payloadType: number): void;
66
69
  addVP8Codec(payloadType: number): void;
67
70
  addVP9Codec(payloadType: number): void;
71
+ addAV1Codec(payloadType: number): void;
68
72
  direction(): Direction;
69
73
  generateSdp(eol: string, addr: string, port: number): string;
70
74
  mid(): string;
@@ -102,7 +106,7 @@ export interface Track {
102
106
  requestBitrate(bitRate: number): boolean;
103
107
  setBufferedAmountLowThreshold(newSize: number): void;
104
108
  requestKeyframe(): boolean;
105
- setMediaHandler(handler: RtcpReceivingSession): void;
109
+ setMediaHandler(handler: MediaHandler): void;
106
110
  onOpen(cb: () => void): void;
107
111
  onClosed(cb: () => void): void;
108
112
  onError(cb: (err: string) => void): void;
@@ -182,12 +186,74 @@ export const IceUdpMuxListener: {
182
186
  new (port: number, address?: string): IceUdpMuxListener;
183
187
  } = nodeDataChannel.IceUdpMuxListener;
184
188
 
185
- export interface RtcpReceivingSession {}
189
+ export interface RtpPacketizationConfig {
190
+ playoutDelayId: number,
191
+ playoutDelayMin: number,
192
+ playoutDelayMax: number,
193
+ timestamp: number,
194
+ get clockRate(): number
195
+ }
196
+
197
+ export const RtpPacketizationConfig: {
198
+ new(ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number): RtpPacketizationConfig
199
+ } = nodeDataChannel.RtpPacketizationConfig
200
+
201
+ export interface MediaHandler {
202
+ addToChain(handler: MediaHandler): void
203
+ }
204
+
205
+ export interface PacingHandler extends MediaHandler {}
206
+
207
+ export const PacingHandler: {
208
+ new (bitsPerSecond: number, sendInterval: number): PacingHandler;
209
+ } = nodeDataChannel.PacingHandler;
210
+
211
+ export interface RtcpReceivingSession extends MediaHandler {}
186
212
 
187
213
  export const RtcpReceivingSession: {
188
214
  new (): RtcpReceivingSession;
189
215
  } = nodeDataChannel.RtcpReceivingSession;
190
216
 
217
+ export interface RtcpNackResponder extends MediaHandler {}
218
+
219
+ export const RtcpNackResponder: {
220
+ new (maxSize?: number): RtcpNackResponder
221
+ } = nodeDataChannel.RtcpNackResponder;
222
+
223
+ export interface RtcpSrReporter extends MediaHandler {
224
+ get rtpConfig(): RtpPacketizationConfig
225
+ }
226
+
227
+ export const RtcpSrReporter: {
228
+ new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter
229
+ } = nodeDataChannel.RtcpSrReporter;
230
+
231
+ export interface RtpPacketizer extends MediaHandler {
232
+ get rtpConfig(): RtpPacketizationConfig
233
+ }
234
+
235
+ export const RtpPacketizer: {
236
+ new (rtpConfig: RtpPacketizationConfig): RtpPacketizer
237
+ } = nodeDataChannel.RtpPacketizer;
238
+
239
+ export interface H264RtpPacketizer extends RtpPacketizer {}
240
+
241
+ export const H264RtpPacketizer: {
242
+ new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer
243
+ } = nodeDataChannel.H264RtpPacketizer
244
+
245
+ export interface H265RtpPacketizer extends RtpPacketizer {}
246
+
247
+ export const H265RtpPacketizer: {
248
+ new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer
249
+ } = nodeDataChannel.H265RtpPacketizer
250
+
251
+ export interface AV1RtpPacketizer extends RtpPacketizer {}
252
+
253
+ export const AV1RtpPacketizer: {
254
+ new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer
255
+ } = nodeDataChannel.AV1RtpPacketizer
256
+
191
257
  export { WebSocketServer } from './websocket-server';
192
258
  export { WebSocket } from './websocket';
193
259
 
@@ -199,7 +265,15 @@ export default {
199
265
  preload,
200
266
  setSctpSettings,
201
267
  getLibraryVersion,
268
+ PacingHandler,
202
269
  RtcpReceivingSession,
270
+ RtcpNackResponder,
271
+ RtcpSrReporter,
272
+ RtpPacketizationConfig,
273
+ RtpPacketizer,
274
+ H264RtpPacketizer,
275
+ H265RtpPacketizer,
276
+ AV1RtpPacketizer,
203
277
  Track,
204
278
  Video,
205
279
  Audio,
package/src/lib/types.ts CHANGED
@@ -160,3 +160,9 @@ export interface IceUdpMuxRequest {
160
160
  host: string;
161
161
  port: number;
162
162
  }
163
+
164
+ // Same as rtc::NalUnit::Separator
165
+ export type NalUnitSeparator = 'Length' | 'ShortStartSequence' | 'LongStartSequence' | 'StartSequence';
166
+
167
+ // Same as rtc::AV1RtpPacketizer::Packetization
168
+ export type ObuPacketization = 'Obu' | 'TemporalUnit';
@@ -36,7 +36,7 @@ export default class RTCPeerConnection extends EventTarget implements globalThis
36
36
  // events
37
37
  onconnectionstatechange: globalThis.RTCPeerConnection['onconnectionstatechange'] = null;
38
38
  // For ondatachannel we need to define type manually
39
- ondatachannel: ((this: globalThis.RTCPeerConnection, ev: globalThis.RTCDataChannelEvent) => any) | null;
39
+ ondatachannel: ((this: globalThis.RTCPeerConnection, ev: RTCDataChannelEvent) => any) | null;
40
40
  onicecandidate: globalThis.RTCPeerConnection['onicecandidate'] = null;
41
41
  onicecandidateerror: globalThis.RTCPeerConnection['onicecandidateerror'] = null;
42
42
  oniceconnectionstatechange: globalThis.RTCPeerConnection['oniceconnectionstatechange'] = null;