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.
- package/CMakeLists.txt +12 -2
- package/dist/cjs/lib/index.cjs +21 -0
- package/dist/cjs/lib/index.cjs.map +1 -1
- package/dist/cjs/polyfill/RTCPeerConnection.cjs.map +1 -1
- package/dist/esm/lib/index.mjs +15 -1
- package/dist/esm/lib/index.mjs.map +1 -1
- package/dist/esm/polyfill/RTCPeerConnection.mjs.map +1 -1
- package/dist/types/lib/index.d.ts +58 -4
- package/dist/types/lib/types.d.ts +3 -1
- package/dist/types/polyfill/RTCPeerConnection.d.ts +2 -1
- package/package.json +1 -1
- package/rollup.config.mjs +1 -1
- package/src/cpp/main.cpp +14 -0
- package/src/cpp/media-av1packetization.cpp +24 -0
- package/src/cpp/media-av1packetization.h +11 -0
- package/src/cpp/media-av1rtppacketizer-wrapper.cpp +126 -0
- package/src/cpp/media-av1rtppacketizer-wrapper.h +29 -0
- package/src/cpp/media-h264rtppacketizer-wrapper.cpp +126 -0
- package/src/cpp/media-h264rtppacketizer-wrapper.h +30 -0
- package/src/cpp/media-h265rtppacketizer-wrapper.cpp +126 -0
- package/src/cpp/media-h265rtppacketizer-wrapper.h +30 -0
- package/src/cpp/media-h26xseparator.cpp +32 -0
- package/src/cpp/media-h26xseparator.h +11 -0
- package/src/cpp/media-mediahandler-helper.cpp +28 -0
- package/src/cpp/media-mediahandler-helper.h +11 -0
- package/src/cpp/media-rtcpnackresponder-wrapper.cpp +68 -0
- package/src/cpp/media-rtcpnackresponder-wrapper.h +28 -0
- package/src/cpp/media-rtcpreceivingsession-wrapper.cpp +23 -6
- package/src/cpp/media-rtcpreceivingsession-wrapper.h +1 -1
- package/src/cpp/media-rtcpsrreporter-wrapper.cpp +93 -0
- package/src/cpp/media-rtcpsrreporter-wrapper.h +30 -0
- package/src/cpp/media-rtppacketizationconfig-wrapper.cpp +167 -0
- package/src/cpp/media-rtppacketizationconfig-wrapper.h +35 -0
- package/src/cpp/media-rtppacketizer-wrapper.cpp +95 -0
- package/src/cpp/media-rtppacketizer-wrapper.h +30 -0
- package/src/cpp/media-track-wrapper.cpp +9 -4
- package/src/cpp/media-video-wrapper.cpp +36 -1
- package/src/cpp/media-video-wrapper.h +2 -0
- package/src/lib/index.ts +69 -2
- package/src/lib/types.ts +6 -0
- package/src/polyfill/RTCPeerConnection.ts +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LogLevel, SctpSettings, Direction, Channel, DescriptionType, LocalDescriptionInit, CertificateFingerprint, DataChannelInitConfig, RTCPeerConnectionState, RTCIceConnectionState, RTCSignalingState, RTCIceGatheringState, SelectedCandidateInfo, RtcConfig, IceUdpMuxRequest, WebSocketServerConfiguration } from './types.js';
|
|
1
|
+
import { LogLevel, SctpSettings, Direction, Channel, DescriptionType, LocalDescriptionInit, CertificateFingerprint, DataChannelInitConfig, RTCPeerConnectionState, RTCIceConnectionState, RTCSignalingState, RTCIceGatheringState, SelectedCandidateInfo, RtcConfig, IceUdpMuxRequest, NalUnitSeparator, ObuPacketization, WebSocketServerConfiguration } from './types.js';
|
|
2
2
|
export { IceServer, ProxyServer, ProxyServerType, RTCIceGathererState, RTCIceTransportState, RTCSdpType, RelayType, TransportPolicy } from './types.js';
|
|
3
3
|
import DataChannelStream$1 from './datachannel-stream.js';
|
|
4
4
|
import { WebSocketServer } from './websocket-server.js';
|
|
@@ -37,8 +37,10 @@ declare const Audio: {
|
|
|
37
37
|
interface Video {
|
|
38
38
|
addVideoCodec(payloadType: number, codec: string, profile?: string): void;
|
|
39
39
|
addH264Codec(payloadType: number, profile?: string): void;
|
|
40
|
+
addH265Codec(payloadType: number): void;
|
|
40
41
|
addVP8Codec(payloadType: number): void;
|
|
41
42
|
addVP9Codec(payloadType: number): void;
|
|
43
|
+
addAV1Codec(payloadType: number): void;
|
|
42
44
|
direction(): Direction;
|
|
43
45
|
generateSdp(eol: string, addr: string, port: number): string;
|
|
44
46
|
mid(): string;
|
|
@@ -75,7 +77,7 @@ interface Track {
|
|
|
75
77
|
requestBitrate(bitRate: number): boolean;
|
|
76
78
|
setBufferedAmountLowThreshold(newSize: number): void;
|
|
77
79
|
requestKeyframe(): boolean;
|
|
78
|
-
setMediaHandler(handler:
|
|
80
|
+
setMediaHandler(handler: MediaHandler): void;
|
|
79
81
|
onOpen(cb: () => void): void;
|
|
80
82
|
onClosed(cb: () => void): void;
|
|
81
83
|
onError(cb: (err: string) => void): void;
|
|
@@ -153,11 +155,56 @@ interface IceUdpMuxListener {
|
|
|
153
155
|
declare const IceUdpMuxListener: {
|
|
154
156
|
new (port: number, address?: string): IceUdpMuxListener;
|
|
155
157
|
};
|
|
156
|
-
interface
|
|
158
|
+
interface RtpPacketizationConfig {
|
|
159
|
+
playoutDelayId: number;
|
|
160
|
+
playoutDelayMin: number;
|
|
161
|
+
playoutDelayMax: number;
|
|
162
|
+
timestamp: number;
|
|
163
|
+
get clockRate(): number;
|
|
164
|
+
}
|
|
165
|
+
declare const RtpPacketizationConfig: {
|
|
166
|
+
new (ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number): RtpPacketizationConfig;
|
|
167
|
+
};
|
|
168
|
+
interface MediaHandler {
|
|
169
|
+
addToChain(handler: MediaHandler): void;
|
|
170
|
+
}
|
|
171
|
+
interface RtcpReceivingSession extends MediaHandler {
|
|
157
172
|
}
|
|
158
173
|
declare const RtcpReceivingSession: {
|
|
159
174
|
new (): RtcpReceivingSession;
|
|
160
175
|
};
|
|
176
|
+
interface RtcpNackResponder extends MediaHandler {
|
|
177
|
+
}
|
|
178
|
+
declare const RtcpNackResponder: {
|
|
179
|
+
new (maxSize?: number): RtcpNackResponder;
|
|
180
|
+
};
|
|
181
|
+
interface RtcpSrReporter extends MediaHandler {
|
|
182
|
+
get rtpConfig(): RtpPacketizationConfig;
|
|
183
|
+
}
|
|
184
|
+
declare const RtcpSrReporter: {
|
|
185
|
+
new (rtpConfig: RtpPacketizationConfig): RtcpSrReporter;
|
|
186
|
+
};
|
|
187
|
+
interface RtpPacketizer extends MediaHandler {
|
|
188
|
+
get rtpConfig(): RtpPacketizationConfig;
|
|
189
|
+
}
|
|
190
|
+
declare const RtpPacketizer: {
|
|
191
|
+
new (rtpConfig: RtpPacketizationConfig): RtpPacketizer;
|
|
192
|
+
};
|
|
193
|
+
interface H264RtpPacketizer extends RtpPacketizer {
|
|
194
|
+
}
|
|
195
|
+
declare const H264RtpPacketizer: {
|
|
196
|
+
new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H264RtpPacketizer;
|
|
197
|
+
};
|
|
198
|
+
interface H265RtpPacketizer extends RtpPacketizer {
|
|
199
|
+
}
|
|
200
|
+
declare const H265RtpPacketizer: {
|
|
201
|
+
new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): H265RtpPacketizer;
|
|
202
|
+
};
|
|
203
|
+
interface AV1RtpPacketizer extends RtpPacketizer {
|
|
204
|
+
}
|
|
205
|
+
declare const AV1RtpPacketizer: {
|
|
206
|
+
new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number): AV1RtpPacketizer;
|
|
207
|
+
};
|
|
161
208
|
|
|
162
209
|
declare const DataChannelStream: typeof DataChannelStream$1;
|
|
163
210
|
declare const _default: {
|
|
@@ -167,6 +214,13 @@ declare const _default: {
|
|
|
167
214
|
setSctpSettings: typeof setSctpSettings;
|
|
168
215
|
getLibraryVersion: typeof getLibraryVersion;
|
|
169
216
|
RtcpReceivingSession: new () => RtcpReceivingSession;
|
|
217
|
+
RtcpNackResponder: new (maxSize?: number) => RtcpNackResponder;
|
|
218
|
+
RtcpSrReporter: new (rtpConfig: RtpPacketizationConfig) => RtcpSrReporter;
|
|
219
|
+
RtpPacketizationConfig: new (ssrc: number, cname: string, payloadType: number, clockRate: number, videoOrientationId?: number) => RtpPacketizationConfig;
|
|
220
|
+
RtpPacketizer: new (rtpConfig: RtpPacketizationConfig) => RtpPacketizer;
|
|
221
|
+
H264RtpPacketizer: new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number) => H264RtpPacketizer;
|
|
222
|
+
H265RtpPacketizer: new (separator: NalUnitSeparator, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number) => H265RtpPacketizer;
|
|
223
|
+
AV1RtpPacketizer: new (packetization: ObuPacketization, rtpConfig: RtpPacketizationConfig, maxFragmentSize?: number) => AV1RtpPacketizer;
|
|
170
224
|
Track: new () => Track;
|
|
171
225
|
Video: new (mid: string, dir: Direction) => Video;
|
|
172
226
|
Audio: new (mid: string, dir: Direction) => Audio;
|
|
@@ -178,4 +232,4 @@ declare const _default: {
|
|
|
178
232
|
IceUdpMuxListener: new (port: number, address?: string) => IceUdpMuxListener;
|
|
179
233
|
};
|
|
180
234
|
|
|
181
|
-
export { Audio, CertificateFingerprint, Channel, DataChannel, DataChannelInitConfig, DataChannelStream, DescriptionType, Direction, IceUdpMuxListener, IceUdpMuxRequest, LocalDescriptionInit, LogLevel, PeerConnection, RTCIceConnectionState, RTCIceGatheringState, RTCPeerConnectionState, RTCSignalingState, RtcConfig, RtcpReceivingSession, SctpSettings, SelectedCandidateInfo, Track, Video, WebSocket, WebSocketServer, WebSocketServerConfiguration, cleanup, _default as default, getLibraryVersion, initLogger, preload, setSctpSettings };
|
|
235
|
+
export { AV1RtpPacketizer, Audio, CertificateFingerprint, Channel, DataChannel, DataChannelInitConfig, DataChannelStream, DescriptionType, Direction, H264RtpPacketizer, H265RtpPacketizer, IceUdpMuxListener, IceUdpMuxRequest, LocalDescriptionInit, LogLevel, type MediaHandler, NalUnitSeparator, ObuPacketization, PeerConnection, RTCIceConnectionState, RTCIceGatheringState, RTCPeerConnectionState, RTCSignalingState, RtcConfig, RtcpNackResponder, RtcpReceivingSession, RtcpSrReporter, RtpPacketizationConfig, RtpPacketizer, SctpSettings, SelectedCandidateInfo, Track, Video, WebSocket, WebSocketServer, WebSocketServerConfiguration, cleanup, _default as default, getLibraryVersion, initLogger, preload, setSctpSettings };
|
|
@@ -112,5 +112,7 @@ interface IceUdpMuxRequest {
|
|
|
112
112
|
host: string;
|
|
113
113
|
port: number;
|
|
114
114
|
}
|
|
115
|
+
type NalUnitSeparator = 'Length' | 'ShortStartSequence' | 'LongStartSequence' | 'StartSequence';
|
|
116
|
+
type ObuPacketization = 'Obu' | 'TemporalUnit';
|
|
115
117
|
|
|
116
|
-
export type { CertificateFingerprint, Channel, DataChannelInitConfig, DescriptionType, Direction, IceServer, IceUdpMuxRequest, LocalDescriptionInit, LogLevel, ProxyServer, ProxyServerType, RTCIceConnectionState, RTCIceGathererState, RTCIceGatheringState, RTCIceTransportState, RTCPeerConnectionState, RTCSdpType, RTCSignalingState, RelayType, RtcConfig, SctpSettings, SelectedCandidateInfo, TransportPolicy, WebSocketServerConfiguration };
|
|
118
|
+
export type { CertificateFingerprint, Channel, DataChannelInitConfig, DescriptionType, Direction, IceServer, IceUdpMuxRequest, LocalDescriptionInit, LogLevel, NalUnitSeparator, ObuPacketization, ProxyServer, ProxyServerType, RTCIceConnectionState, RTCIceGathererState, RTCIceGatheringState, RTCIceTransportState, RTCPeerConnectionState, RTCSdpType, RTCSignalingState, RelayType, RtcConfig, SctpSettings, SelectedCandidateInfo, TransportPolicy, WebSocketServerConfiguration };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { SelectedCandidateInfo } from '../lib/types';
|
|
2
2
|
import { PeerConnection } from '../lib/index';
|
|
3
3
|
import RTCDataChannel from './RTCDataChannel.js';
|
|
4
|
+
import { RTCDataChannelEvent } from './Events.js';
|
|
4
5
|
import RTCCertificate from './RTCCertificate.js';
|
|
5
6
|
|
|
6
7
|
interface RTCConfiguration extends globalThis.RTCConfiguration {
|
|
@@ -11,7 +12,7 @@ declare class RTCPeerConnection extends EventTarget implements globalThis.RTCPee
|
|
|
11
12
|
#private;
|
|
12
13
|
static generateCertificate(): Promise<RTCCertificate>;
|
|
13
14
|
onconnectionstatechange: globalThis.RTCPeerConnection['onconnectionstatechange'];
|
|
14
|
-
ondatachannel: ((this: globalThis.RTCPeerConnection, ev:
|
|
15
|
+
ondatachannel: ((this: globalThis.RTCPeerConnection, ev: RTCDataChannelEvent) => any) | null;
|
|
15
16
|
onicecandidate: globalThis.RTCPeerConnection['onicecandidate'];
|
|
16
17
|
onicecandidateerror: globalThis.RTCPeerConnection['onicecandidateerror'];
|
|
17
18
|
oniceconnectionstatechange: globalThis.RTCPeerConnection['oniceconnectionstatechange'];
|
package/package.json
CHANGED
package/rollup.config.mjs
CHANGED
package/src/cpp/main.cpp
CHANGED
|
@@ -5,7 +5,14 @@
|
|
|
5
5
|
#include "ice-udp-mux-listener-wrapper.h"
|
|
6
6
|
|
|
7
7
|
#if RTC_ENABLE_MEDIA == 1
|
|
8
|
+
#include "media-av1rtppacketizer-wrapper.h"
|
|
9
|
+
#include "media-h264rtppacketizer-wrapper.h"
|
|
10
|
+
#include "media-h265rtppacketizer-wrapper.h"
|
|
11
|
+
#include "media-rtcpnackresponder-wrapper.h"
|
|
8
12
|
#include "media-rtcpreceivingsession-wrapper.h"
|
|
13
|
+
#include "media-rtcpsrreporter-wrapper.h"
|
|
14
|
+
#include "media-rtppacketizationconfig-wrapper.h"
|
|
15
|
+
#include "media-rtppacketizer-wrapper.h"
|
|
9
16
|
#include "media-track-wrapper.h"
|
|
10
17
|
#include "media-video-wrapper.h"
|
|
11
18
|
#include "media-audio-wrapper.h"
|
|
@@ -21,7 +28,14 @@ Napi::Object InitAll(Napi::Env env, Napi::Object exports)
|
|
|
21
28
|
RtcWrapper::Init(env, exports);
|
|
22
29
|
|
|
23
30
|
#if RTC_ENABLE_MEDIA == 1
|
|
31
|
+
AV1RtpPacketizerWrapper::Init(env, exports);
|
|
32
|
+
H264RtpPacketizerWrapper::Init(env, exports);
|
|
33
|
+
H265RtpPacketizerWrapper::Init(env, exports);
|
|
34
|
+
RtcpNackResponderWrapper::Init(env, exports);
|
|
24
35
|
RtcpReceivingSessionWrapper::Init(env, exports);
|
|
36
|
+
RtcpSrReporterWrapper::Init(env, exports);
|
|
37
|
+
RtpPacketizationConfigWrapper::Init(env, exports);
|
|
38
|
+
RtpPacketizerWrapper::Init(env, exports);
|
|
25
39
|
TrackWrapper::Init(env, exports);
|
|
26
40
|
VideoWrapper::Init(env, exports);
|
|
27
41
|
AudioWrapper::Init(env, exports);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#include "media-av1packetization.h"
|
|
2
|
+
|
|
3
|
+
using Packetization = rtc::AV1RtpPacketizer::Packetization;
|
|
4
|
+
|
|
5
|
+
std::optional<Packetization> strToPacketization(const std::string &packAsStr)
|
|
6
|
+
{
|
|
7
|
+
if (packAsStr == "Obu")
|
|
8
|
+
return Packetization::Obu;
|
|
9
|
+
if (packAsStr == "TemporalUnit")
|
|
10
|
+
return Packetization::TemporalUnit;
|
|
11
|
+
return {};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
std::string packetizationToStr(rtc::AV1RtpPacketizer::Packetization pack)
|
|
15
|
+
{
|
|
16
|
+
switch (pack)
|
|
17
|
+
{
|
|
18
|
+
case Packetization::Obu:
|
|
19
|
+
return "Obu";
|
|
20
|
+
case Packetization::TemporalUnit:
|
|
21
|
+
return "TemporalUnit";
|
|
22
|
+
}
|
|
23
|
+
return "Unknown";
|
|
24
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#ifndef MEDIA_AV1PACKETIZATION_H
|
|
2
|
+
#define MEDIA_AV1PACKETIZATION_H
|
|
3
|
+
|
|
4
|
+
#include <napi.h>
|
|
5
|
+
#include <rtc/rtc.hpp>
|
|
6
|
+
#include <optional>
|
|
7
|
+
|
|
8
|
+
std::optional<rtc::AV1RtpPacketizer::Packetization> strToPacketization(const std::string &pktAsStr);
|
|
9
|
+
std::string packetizationToStr(rtc::AV1RtpPacketizer::Packetization pkt);
|
|
10
|
+
|
|
11
|
+
#endif // MEDIA_AV1PACKETIZATION_H
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#include "media-av1rtppacketizer-wrapper.h"
|
|
2
|
+
#include "media-av1packetization.h"
|
|
3
|
+
#include "media-rtppacketizationconfig-wrapper.h"
|
|
4
|
+
#include "media-mediahandler-helper.h"
|
|
5
|
+
|
|
6
|
+
Napi::FunctionReference AV1RtpPacketizerWrapper::constructor = Napi::FunctionReference();
|
|
7
|
+
|
|
8
|
+
Napi::Object AV1RtpPacketizerWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
9
|
+
{
|
|
10
|
+
Napi::HandleScope scope(env);
|
|
11
|
+
|
|
12
|
+
Napi::Function func = Napi::ObjectWrap<AV1RtpPacketizerWrapper>::DefineClass(env, "AV1RtpPacketizer",
|
|
13
|
+
{
|
|
14
|
+
// Instance Methods
|
|
15
|
+
InstanceMethod("addToChain", &AV1RtpPacketizerWrapper::addToChain),
|
|
16
|
+
// Accessors
|
|
17
|
+
InstanceAccessor("rtpConfig", &AV1RtpPacketizerWrapper::getRtpPacketizationConfig, nullptr),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
|
|
21
|
+
if (constructor.IsEmpty())
|
|
22
|
+
{
|
|
23
|
+
constructor = Napi::Persistent(func);
|
|
24
|
+
constructor.SuppressDestruct();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
exports.Set("AV1RtpPacketizer", func);
|
|
28
|
+
return exports;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
AV1RtpPacketizerWrapper::AV1RtpPacketizerWrapper(const Napi::CallbackInfo &info)
|
|
32
|
+
: Napi::ObjectWrap<AV1RtpPacketizerWrapper>(info)
|
|
33
|
+
{
|
|
34
|
+
Napi::Env env = info.Env();
|
|
35
|
+
|
|
36
|
+
if (info.Length() < 2)
|
|
37
|
+
{
|
|
38
|
+
Napi::Error::New(env, "Expected 2 or 3 parameters").ThrowAsJavaScriptException();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!info[0].IsString())
|
|
43
|
+
{
|
|
44
|
+
Napi::TypeError::New(env, "packetization must be \"Obu\" or \"TemporalUnit\"")
|
|
45
|
+
.ThrowAsJavaScriptException();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
auto packetizationOpt = strToPacketization(info[0].As<Napi::String>().Utf8Value());
|
|
49
|
+
if (!packetizationOpt.has_value())
|
|
50
|
+
{
|
|
51
|
+
Napi::TypeError::New(env, "packetization must be \"Obu\" or \"TemporalUnit\"")
|
|
52
|
+
.ThrowAsJavaScriptException();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
auto packetization = packetizationOpt.value();
|
|
56
|
+
|
|
57
|
+
if (!info[1].IsObject())
|
|
58
|
+
{
|
|
59
|
+
Napi::TypeError::New(env, "rtpConfig must be a RtpPacketizationConfig instance").ThrowAsJavaScriptException();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
auto obj = info[1].As<Napi::Object>();
|
|
63
|
+
if (!obj.InstanceOf(RtpPacketizationConfigWrapper::constructor.Value()))
|
|
64
|
+
{
|
|
65
|
+
Napi::TypeError::New(env, "rtpConfig must be a RtpPacketizationConfig instance").ThrowAsJavaScriptException();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// store original JS object so we can return it later
|
|
69
|
+
mRtpConfigObject = Napi::Persistent(obj);
|
|
70
|
+
mRtpConfigObject.SuppressDestruct();
|
|
71
|
+
auto rtpConfig = RtpPacketizationConfigWrapper::Unwrap(obj)->getConfigInstance();
|
|
72
|
+
|
|
73
|
+
size_t maxFragmentSize = rtc::RtpPacketizer::DefaultMaxFragmentSize;
|
|
74
|
+
if (info.Length() >= 3)
|
|
75
|
+
{
|
|
76
|
+
if (!info[2].IsNumber())
|
|
77
|
+
{
|
|
78
|
+
Napi::TypeError::New(env, "maxFragmentSize must be a number").ThrowAsJavaScriptException();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
maxFragmentSize = info[2].As<Napi::Number>().Uint32Value();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
mPacketizerPtr = std::make_unique<rtc::AV1RtpPacketizer>(packetization, rtpConfig, maxFragmentSize);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
AV1RtpPacketizerWrapper::~AV1RtpPacketizerWrapper()
|
|
88
|
+
{
|
|
89
|
+
mPacketizerPtr.reset();
|
|
90
|
+
mRtpConfigObject.Reset();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
std::shared_ptr<rtc::AV1RtpPacketizer> AV1RtpPacketizerWrapper::getPacketizerInstance() { return mPacketizerPtr; }
|
|
94
|
+
|
|
95
|
+
void AV1RtpPacketizerWrapper::addToChain(const Napi::CallbackInfo &info)
|
|
96
|
+
{
|
|
97
|
+
auto env = info.Env();
|
|
98
|
+
if (info.Length() < 1 || !info[0].IsObject())
|
|
99
|
+
{
|
|
100
|
+
Napi::TypeError::New(env, "Expected a MediaHandler instance").ThrowAsJavaScriptException();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
auto mediaHandler = asMediaHandler(info[0].As<Napi::Object>());
|
|
104
|
+
if (!mediaHandler)
|
|
105
|
+
{
|
|
106
|
+
Napi::TypeError::New(env, "Expected a MediaHandler instance. If this error is unexpected, please report a bug!")
|
|
107
|
+
.ThrowAsJavaScriptException();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
mPacketizerPtr->addToChain(mediaHandler);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Napi::Value AV1RtpPacketizerWrapper::getRtpPacketizationConfig(const Napi::CallbackInfo &info)
|
|
114
|
+
{
|
|
115
|
+
Napi::Env env = info.Env();
|
|
116
|
+
if (!mPacketizerPtr)
|
|
117
|
+
{
|
|
118
|
+
Napi::Error::New(env, "getRtpPacketizationConfig() called on destroyed packetizer").ThrowAsJavaScriptException();
|
|
119
|
+
return env.Null();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (mRtpConfigObject.IsEmpty())
|
|
123
|
+
return env.Null();
|
|
124
|
+
|
|
125
|
+
return mRtpConfigObject.Value();
|
|
126
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#ifndef MEDIA_AV1RTPPACKETIZER_WRAPPER_H
|
|
2
|
+
#define MEDIA_AV1RTPPACKETIZER_WRAPPER_H
|
|
3
|
+
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <unordered_set>
|
|
6
|
+
|
|
7
|
+
#include <napi.h>
|
|
8
|
+
#include <rtc/rtc.hpp>
|
|
9
|
+
|
|
10
|
+
class AV1RtpPacketizerWrapper : public Napi::ObjectWrap<AV1RtpPacketizerWrapper>
|
|
11
|
+
{
|
|
12
|
+
public:
|
|
13
|
+
static Napi::FunctionReference constructor;
|
|
14
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
15
|
+
AV1RtpPacketizerWrapper(const Napi::CallbackInfo &info);
|
|
16
|
+
~AV1RtpPacketizerWrapper();
|
|
17
|
+
std::shared_ptr<rtc::AV1RtpPacketizer> getPacketizerInstance();
|
|
18
|
+
|
|
19
|
+
// Functions
|
|
20
|
+
Napi::Value getRtpPacketizationConfig(const Napi::CallbackInfo &info);
|
|
21
|
+
void addToChain(const Napi::CallbackInfo &info);
|
|
22
|
+
// Callbacks
|
|
23
|
+
|
|
24
|
+
private:
|
|
25
|
+
std::shared_ptr<rtc::AV1RtpPacketizer> mPacketizerPtr = nullptr;
|
|
26
|
+
Napi::ObjectReference mRtpConfigObject;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
#endif // MEDIA_AV1RTPPACKETIZER_WRAPPER_H
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#include "media-h264rtppacketizer-wrapper.h"
|
|
2
|
+
#include "media-h26xseparator.h"
|
|
3
|
+
#include "media-rtppacketizationconfig-wrapper.h"
|
|
4
|
+
#include "media-mediahandler-helper.h"
|
|
5
|
+
|
|
6
|
+
Napi::FunctionReference H264RtpPacketizerWrapper::constructor = Napi::FunctionReference();
|
|
7
|
+
|
|
8
|
+
Napi::Object H264RtpPacketizerWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
9
|
+
{
|
|
10
|
+
Napi::HandleScope scope(env);
|
|
11
|
+
|
|
12
|
+
Napi::Function func = Napi::ObjectWrap<H264RtpPacketizerWrapper>::DefineClass(env, "H264RtpPacketizer",
|
|
13
|
+
{
|
|
14
|
+
// Instance Methods
|
|
15
|
+
InstanceMethod("addToChain", &H264RtpPacketizerWrapper::addToChain),
|
|
16
|
+
// Accessors
|
|
17
|
+
InstanceAccessor("rtpConfig", &H264RtpPacketizerWrapper::getRtpPacketizationConfig, nullptr),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
|
|
21
|
+
if (constructor.IsEmpty())
|
|
22
|
+
{
|
|
23
|
+
constructor = Napi::Persistent(func);
|
|
24
|
+
constructor.SuppressDestruct();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
exports.Set("H264RtpPacketizer", func);
|
|
28
|
+
return exports;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
H264RtpPacketizerWrapper::H264RtpPacketizerWrapper(const Napi::CallbackInfo &info)
|
|
32
|
+
: Napi::ObjectWrap<H264RtpPacketizerWrapper>(info)
|
|
33
|
+
{
|
|
34
|
+
Napi::Env env = info.Env();
|
|
35
|
+
|
|
36
|
+
if (info.Length() < 2)
|
|
37
|
+
{
|
|
38
|
+
Napi::Error::New(env, "Expected 2 or 3 parameters").ThrowAsJavaScriptException();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!info[0].IsString())
|
|
43
|
+
{
|
|
44
|
+
Napi::TypeError::New(env, "separator must be \"Length\", \"ShortStartSequence\", \"LongStartSequence\" or \"StartSequence\"")
|
|
45
|
+
.ThrowAsJavaScriptException();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
auto separatorOpt = strToSeparator(info[0].As<Napi::String>().Utf8Value());
|
|
49
|
+
if (!separatorOpt.has_value())
|
|
50
|
+
{
|
|
51
|
+
Napi::TypeError::New(env, "separator must be \"Length\", \"ShortStartSequence\", \"LongStartSequence\" or \"StartSequence\"")
|
|
52
|
+
.ThrowAsJavaScriptException();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
auto separator = separatorOpt.value();
|
|
56
|
+
|
|
57
|
+
if (!info[1].IsObject())
|
|
58
|
+
{
|
|
59
|
+
Napi::TypeError::New(env, "rtpConfig must be a RtpPacketizationConfig instance").ThrowAsJavaScriptException();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
auto obj = info[1].As<Napi::Object>();
|
|
63
|
+
if (!obj.InstanceOf(RtpPacketizationConfigWrapper::constructor.Value()))
|
|
64
|
+
{
|
|
65
|
+
Napi::TypeError::New(env, "rtpConfig must be a RtpPacketizationConfig instance").ThrowAsJavaScriptException();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// store original JS object so we can return it later
|
|
69
|
+
mRtpConfigObject = Napi::Persistent(obj);
|
|
70
|
+
mRtpConfigObject.SuppressDestruct();
|
|
71
|
+
auto rtpConfig = RtpPacketizationConfigWrapper::Unwrap(obj)->getConfigInstance();
|
|
72
|
+
|
|
73
|
+
size_t maxFragmentSize = rtc::RtpPacketizer::DefaultMaxFragmentSize;
|
|
74
|
+
if (info.Length() >= 3)
|
|
75
|
+
{
|
|
76
|
+
if (!info[2].IsNumber())
|
|
77
|
+
{
|
|
78
|
+
Napi::TypeError::New(env, "maxFragmentSize must be a number").ThrowAsJavaScriptException();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
maxFragmentSize = info[2].As<Napi::Number>().Uint32Value();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
mPacketizerPtr = std::make_unique<rtc::H264RtpPacketizer>(separator, rtpConfig, maxFragmentSize);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
H264RtpPacketizerWrapper::~H264RtpPacketizerWrapper()
|
|
88
|
+
{
|
|
89
|
+
mPacketizerPtr.reset();
|
|
90
|
+
mRtpConfigObject.Reset();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
std::shared_ptr<rtc::H264RtpPacketizer> H264RtpPacketizerWrapper::getPacketizerInstance() { return mPacketizerPtr; }
|
|
94
|
+
|
|
95
|
+
void H264RtpPacketizerWrapper::addToChain(const Napi::CallbackInfo &info)
|
|
96
|
+
{
|
|
97
|
+
auto env = info.Env();
|
|
98
|
+
if (info.Length() < 1 || !info[0].IsObject())
|
|
99
|
+
{
|
|
100
|
+
Napi::TypeError::New(env, "Expected a MediaHandler instance").ThrowAsJavaScriptException();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
auto mediaHandler = asMediaHandler(info[0].As<Napi::Object>());
|
|
104
|
+
if (!mediaHandler)
|
|
105
|
+
{
|
|
106
|
+
Napi::TypeError::New(env, "Expected a MediaHandler instance. If this error is unexpected, please report a bug!")
|
|
107
|
+
.ThrowAsJavaScriptException();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
mPacketizerPtr->addToChain(mediaHandler);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Napi::Value H264RtpPacketizerWrapper::getRtpPacketizationConfig(const Napi::CallbackInfo &info)
|
|
114
|
+
{
|
|
115
|
+
Napi::Env env = info.Env();
|
|
116
|
+
if (!mPacketizerPtr)
|
|
117
|
+
{
|
|
118
|
+
Napi::Error::New(env, "getRtpPacketizationConfig() called on destroyed packetizer").ThrowAsJavaScriptException();
|
|
119
|
+
return env.Null();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (mRtpConfigObject.IsEmpty())
|
|
123
|
+
return env.Null();
|
|
124
|
+
|
|
125
|
+
return mRtpConfigObject.Value();
|
|
126
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#ifndef MEDIA_H264RTPPACKETIZER_WRAPPER_H
|
|
2
|
+
#define MEDIA_H264RTPPACKETIZER_WRAPPER_H
|
|
3
|
+
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <unordered_set>
|
|
6
|
+
|
|
7
|
+
#include <napi.h>
|
|
8
|
+
#include <rtc/rtc.hpp>
|
|
9
|
+
|
|
10
|
+
class H264RtpPacketizerWrapper : public Napi::ObjectWrap<H264RtpPacketizerWrapper>
|
|
11
|
+
{
|
|
12
|
+
public:
|
|
13
|
+
static Napi::FunctionReference constructor;
|
|
14
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
15
|
+
H264RtpPacketizerWrapper(const Napi::CallbackInfo &info);
|
|
16
|
+
~H264RtpPacketizerWrapper();
|
|
17
|
+
std::shared_ptr<rtc::H264RtpPacketizer> getPacketizerInstance();
|
|
18
|
+
|
|
19
|
+
// Functions
|
|
20
|
+
Napi::Value getRtpPacketizationConfig(const Napi::CallbackInfo &info);
|
|
21
|
+
void addToChain(const Napi::CallbackInfo &info);
|
|
22
|
+
|
|
23
|
+
// Callbacks
|
|
24
|
+
|
|
25
|
+
private:
|
|
26
|
+
std::shared_ptr<rtc::H264RtpPacketizer> mPacketizerPtr = nullptr;
|
|
27
|
+
Napi::ObjectReference mRtpConfigObject;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
#endif // MEDIA_H264RTPPACKETIZER_WRAPPER_H
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
#include "media-h265rtppacketizer-wrapper.h"
|
|
2
|
+
#include "media-h26xseparator.h"
|
|
3
|
+
#include "media-rtppacketizationconfig-wrapper.h"
|
|
4
|
+
#include "media-mediahandler-helper.h"
|
|
5
|
+
|
|
6
|
+
Napi::FunctionReference H265RtpPacketizerWrapper::constructor = Napi::FunctionReference();
|
|
7
|
+
|
|
8
|
+
Napi::Object H265RtpPacketizerWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
9
|
+
{
|
|
10
|
+
Napi::HandleScope scope(env);
|
|
11
|
+
|
|
12
|
+
Napi::Function func = Napi::ObjectWrap<H265RtpPacketizerWrapper>::DefineClass(env, "H265RtpPacketizer",
|
|
13
|
+
{
|
|
14
|
+
// Instance Methods
|
|
15
|
+
InstanceMethod("addToChain", &H265RtpPacketizerWrapper::addToChain),
|
|
16
|
+
// Accessors
|
|
17
|
+
InstanceAccessor("rtpConfig", &H265RtpPacketizerWrapper::getRtpPacketizationConfig, nullptr),
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
|
|
21
|
+
if (constructor.IsEmpty())
|
|
22
|
+
{
|
|
23
|
+
constructor = Napi::Persistent(func);
|
|
24
|
+
constructor.SuppressDestruct();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
exports.Set("H265RtpPacketizer", func);
|
|
28
|
+
return exports;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
H265RtpPacketizerWrapper::H265RtpPacketizerWrapper(const Napi::CallbackInfo &info)
|
|
32
|
+
: Napi::ObjectWrap<H265RtpPacketizerWrapper>(info)
|
|
33
|
+
{
|
|
34
|
+
Napi::Env env = info.Env();
|
|
35
|
+
|
|
36
|
+
if (info.Length() < 2)
|
|
37
|
+
{
|
|
38
|
+
Napi::Error::New(env, "Expected 2 or 3 parameters").ThrowAsJavaScriptException();
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!info[0].IsString())
|
|
43
|
+
{
|
|
44
|
+
Napi::TypeError::New(env, "separator must be \"Length\", \"ShortStartSequence\", \"LongStartSequence\" or \"StartSequence\"")
|
|
45
|
+
.ThrowAsJavaScriptException();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
auto separatorOpt = strToSeparator(info[0].As<Napi::String>().Utf8Value());
|
|
49
|
+
if (!separatorOpt.has_value())
|
|
50
|
+
{
|
|
51
|
+
Napi::TypeError::New(env, "separator must be \"Length\", \"ShortStartSequence\", \"LongStartSequence\" or \"StartSequence\"")
|
|
52
|
+
.ThrowAsJavaScriptException();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
auto separator = separatorOpt.value();
|
|
56
|
+
|
|
57
|
+
if (!info[1].IsObject())
|
|
58
|
+
{
|
|
59
|
+
Napi::TypeError::New(env, "rtpConfig must be a RtpPacketizationConfig instance").ThrowAsJavaScriptException();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
auto obj = info[1].As<Napi::Object>();
|
|
63
|
+
if (!obj.InstanceOf(RtpPacketizationConfigWrapper::constructor.Value()))
|
|
64
|
+
{
|
|
65
|
+
Napi::TypeError::New(env, "rtpConfig must be a RtpPacketizationConfig instance").ThrowAsJavaScriptException();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// store original JS object so we can return it later
|
|
69
|
+
mRtpConfigObject = Napi::Persistent(obj);
|
|
70
|
+
mRtpConfigObject.SuppressDestruct();
|
|
71
|
+
auto rtpConfig = RtpPacketizationConfigWrapper::Unwrap(obj)->getConfigInstance();
|
|
72
|
+
|
|
73
|
+
size_t maxFragmentSize = rtc::RtpPacketizer::DefaultMaxFragmentSize;
|
|
74
|
+
if (info.Length() >= 3)
|
|
75
|
+
{
|
|
76
|
+
if (!info[2].IsNumber())
|
|
77
|
+
{
|
|
78
|
+
Napi::TypeError::New(env, "maxFragmentSize must be a number").ThrowAsJavaScriptException();
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
maxFragmentSize = info[2].As<Napi::Number>().Uint32Value();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
mPacketizerPtr = std::make_unique<rtc::H265RtpPacketizer>(separator, rtpConfig, maxFragmentSize);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
H265RtpPacketizerWrapper::~H265RtpPacketizerWrapper()
|
|
88
|
+
{
|
|
89
|
+
mPacketizerPtr.reset();
|
|
90
|
+
mRtpConfigObject.Reset();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
std::shared_ptr<rtc::H265RtpPacketizer> H265RtpPacketizerWrapper::getPacketizerInstance() { return mPacketizerPtr; }
|
|
94
|
+
|
|
95
|
+
void H265RtpPacketizerWrapper::addToChain(const Napi::CallbackInfo &info)
|
|
96
|
+
{
|
|
97
|
+
auto env = info.Env();
|
|
98
|
+
if (info.Length() < 1 || !info[0].IsObject())
|
|
99
|
+
{
|
|
100
|
+
Napi::TypeError::New(env, "Expected a MediaHandler instance").ThrowAsJavaScriptException();
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
auto mediaHandler = asMediaHandler(info[0].As<Napi::Object>());
|
|
104
|
+
if (!mediaHandler)
|
|
105
|
+
{
|
|
106
|
+
Napi::TypeError::New(env, "Expected a MediaHandler instance. If this error is unexpected, please report a bug!")
|
|
107
|
+
.ThrowAsJavaScriptException();
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
mPacketizerPtr->addToChain(mediaHandler);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
Napi::Value H265RtpPacketizerWrapper::getRtpPacketizationConfig(const Napi::CallbackInfo &info)
|
|
114
|
+
{
|
|
115
|
+
Napi::Env env = info.Env();
|
|
116
|
+
if (!mPacketizerPtr)
|
|
117
|
+
{
|
|
118
|
+
Napi::Error::New(env, "getRtpPacketizationConfig() called on destroyed packetizer").ThrowAsJavaScriptException();
|
|
119
|
+
return env.Null();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (mRtpConfigObject.IsEmpty())
|
|
123
|
+
return env.Null();
|
|
124
|
+
|
|
125
|
+
return mRtpConfigObject.Value();
|
|
126
|
+
}
|