node-datachannel 0.30.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 (41) hide show
  1. package/CMakeLists.txt +12 -2
  2. package/dist/cjs/lib/index.cjs +21 -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 +15 -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 +58 -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 +14 -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 +28 -0
  25. package/src/cpp/media-mediahandler-helper.h +11 -0
  26. package/src/cpp/media-rtcpnackresponder-wrapper.cpp +68 -0
  27. package/src/cpp/media-rtcpnackresponder-wrapper.h +28 -0
  28. package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +23 -6
  29. package/src/cpp/media-rtcpreceivingsession-wrapper.h +1 -1
  30. package/src/cpp/media-rtcpsrreporter-wrapper.cpp +93 -0
  31. package/src/cpp/media-rtcpsrreporter-wrapper.h +30 -0
  32. package/src/cpp/media-rtppacketizationconfig-wrapper.cpp +167 -0
  33. package/src/cpp/media-rtppacketizationconfig-wrapper.h +35 -0
  34. package/src/cpp/media-rtppacketizer-wrapper.cpp +95 -0
  35. package/src/cpp/media-rtppacketizer-wrapper.h +30 -0
  36. package/src/cpp/media-track-wrapper.cpp +9 -4
  37. package/src/cpp/media-video-wrapper.cpp +36 -1
  38. package/src/cpp/media-video-wrapper.h +2 -0
  39. package/src/lib/index.ts +69 -2
  40. package/src/lib/types.ts +6 -0
  41. package/src/polyfill/RTCPeerConnection.ts +1 -1
@@ -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,68 @@ 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 RtcpReceivingSession extends MediaHandler {}
186
206
 
187
207
  export const RtcpReceivingSession: {
188
208
  new (): RtcpReceivingSession;
189
209
  } = nodeDataChannel.RtcpReceivingSession;
190
210
 
211
+ export interface RtcpNackResponder extends MediaHandler {}
212
+
213
+ export const RtcpNackResponder: {
214
+ new (maxSize?: number): RtcpNackResponder
215
+ } = nodeDataChannel.RtcpNackResponder;
216
+
217
+ export interface RtcpSrReporter extends MediaHandler {
218
+ get rtpConfig(): RtpPacketizationConfig
219
+ }
220
+
221
+ export const RtcpSrReporter: {
222
+ new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter
223
+ } = nodeDataChannel.RtcpSrReporter;
224
+
225
+ export interface RtpPacketizer extends MediaHandler {
226
+ get rtpConfig(): RtpPacketizationConfig
227
+ }
228
+
229
+ export const RtpPacketizer: {
230
+ new (rtpConfig: RtpPacketizationConfig): RtpPacketizer
231
+ } = nodeDataChannel.RtpPacketizer;
232
+
233
+ export interface H264RtpPacketizer extends RtpPacketizer {}
234
+
235
+ export const H264RtpPacketizer: {
236
+ new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer
237
+ } = nodeDataChannel.H264RtpPacketizer
238
+
239
+ export interface H265RtpPacketizer extends RtpPacketizer {}
240
+
241
+ export const H265RtpPacketizer: {
242
+ new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer
243
+ } = nodeDataChannel.H265RtpPacketizer
244
+
245
+ export interface AV1RtpPacketizer extends RtpPacketizer {}
246
+
247
+ export const AV1RtpPacketizer: {
248
+ new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer
249
+ } = nodeDataChannel.AV1RtpPacketizer
250
+
191
251
  export { WebSocketServer } from './websocket-server';
192
252
  export { WebSocket } from './websocket';
193
253
 
@@ -200,6 +260,13 @@ export default {
200
260
  setSctpSettings,
201
261
  getLibraryVersion,
202
262
  RtcpReceivingSession,
263
+ RtcpNackResponder,
264
+ RtcpSrReporter,
265
+ RtpPacketizationConfig,
266
+ RtpPacketizer,
267
+ H264RtpPacketizer,
268
+ H265RtpPacketizer,
269
+ AV1RtpPacketizer,
203
270
  Track,
204
271
  Video,
205
272
  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;