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
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#ifndef MEDIA_H265RTPPACKETIZER_WRAPPER_H
|
|
2
|
+
#define MEDIA_H265RTPPACKETIZER_WRAPPER_H
|
|
3
|
+
|
|
4
|
+
#include <memory>
|
|
5
|
+
#include <unordered_set>
|
|
6
|
+
|
|
7
|
+
#include <napi.h>
|
|
8
|
+
#include <rtc/rtc.hpp>
|
|
9
|
+
|
|
10
|
+
class H265RtpPacketizerWrapper : public Napi::ObjectWrap<H265RtpPacketizerWrapper>
|
|
11
|
+
{
|
|
12
|
+
public:
|
|
13
|
+
static Napi::FunctionReference constructor;
|
|
14
|
+
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
15
|
+
H265RtpPacketizerWrapper(const Napi::CallbackInfo &info);
|
|
16
|
+
~H265RtpPacketizerWrapper();
|
|
17
|
+
std::shared_ptr<rtc::H265RtpPacketizer> 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::H265RtpPacketizer> mPacketizerPtr = nullptr;
|
|
27
|
+
Napi::ObjectReference mRtpConfigObject;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
#endif // MEDIA_H265RTPPACKETIZER_WRAPPER_H
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#include "media-h26xseparator.h"
|
|
2
|
+
|
|
3
|
+
using Separator = rtc::NalUnit::Separator;
|
|
4
|
+
|
|
5
|
+
std::optional<Separator> strToSeparator(const std::string &sepAsStr)
|
|
6
|
+
{
|
|
7
|
+
if (sepAsStr == "Length")
|
|
8
|
+
return Separator::Length;
|
|
9
|
+
if (sepAsStr == "ShortStartSequence")
|
|
10
|
+
return Separator::ShortStartSequence;
|
|
11
|
+
if (sepAsStr == "LongStartSequence")
|
|
12
|
+
return Separator::LongStartSequence;
|
|
13
|
+
if (sepAsStr == "StartSequence")
|
|
14
|
+
return Separator::StartSequence;
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
std::string separatorToStr(rtc::NalUnit::Separator sep)
|
|
19
|
+
{
|
|
20
|
+
switch (sep)
|
|
21
|
+
{
|
|
22
|
+
case Separator::Length:
|
|
23
|
+
return "Length";
|
|
24
|
+
case Separator::ShortStartSequence:
|
|
25
|
+
return "ShortStartSequence";
|
|
26
|
+
case Separator::LongStartSequence:
|
|
27
|
+
return "LongStartSequence";
|
|
28
|
+
case Separator::StartSequence:
|
|
29
|
+
return "StartSequence";
|
|
30
|
+
}
|
|
31
|
+
return "Unknown";
|
|
32
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#ifndef MEDIA_H26XSEPARATOR_H
|
|
2
|
+
#define MEDIA_H26XSEPARATOR_H
|
|
3
|
+
|
|
4
|
+
#include <napi.h>
|
|
5
|
+
#include <rtc/rtc.hpp>
|
|
6
|
+
#include <optional>
|
|
7
|
+
|
|
8
|
+
std::optional<rtc::NalUnit::Separator> strToSeparator(const std::string &sepAsStr);
|
|
9
|
+
std::string separatorToStr(rtc::NalUnit::Separator sep);
|
|
10
|
+
|
|
11
|
+
#endif // MEDIA_H26XSEPARATOR_H
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#include "media-mediahandler-helper.h"
|
|
2
|
+
#include "media-av1rtppacketizer-wrapper.h"
|
|
3
|
+
#include "media-h264rtppacketizer-wrapper.h"
|
|
4
|
+
#include "media-h265rtppacketizer-wrapper.h"
|
|
5
|
+
#include "media-rtcpnackresponder-wrapper.h"
|
|
6
|
+
#include "media-rtcpreceivingsession-wrapper.h"
|
|
7
|
+
#include "media-rtcpsrreporter-wrapper.h"
|
|
8
|
+
#include "media-rtppacketizer-wrapper.h"
|
|
9
|
+
|
|
10
|
+
std::shared_ptr<rtc::MediaHandler> asMediaHandler(const Napi::Object &val)
|
|
11
|
+
{
|
|
12
|
+
std::shared_ptr<rtc::MediaHandler> mediaHandler;
|
|
13
|
+
if (val.InstanceOf(AV1RtpPacketizerWrapper::constructor.Value()))
|
|
14
|
+
mediaHandler = AV1RtpPacketizerWrapper::Unwrap(val)->getPacketizerInstance();
|
|
15
|
+
else if (val.InstanceOf(H264RtpPacketizerWrapper::constructor.Value()))
|
|
16
|
+
mediaHandler = H264RtpPacketizerWrapper::Unwrap(val)->getPacketizerInstance();
|
|
17
|
+
else if (val.InstanceOf(H265RtpPacketizerWrapper::constructor.Value()))
|
|
18
|
+
mediaHandler = H265RtpPacketizerWrapper::Unwrap(val)->getPacketizerInstance();
|
|
19
|
+
else if (val.InstanceOf(RtcpNackResponderWrapper::constructor.Value()))
|
|
20
|
+
mediaHandler = RtcpNackResponderWrapper::Unwrap(val)->getResponderInstance();
|
|
21
|
+
else if (val.InstanceOf(RtcpReceivingSessionWrapper::constructor.Value()))
|
|
22
|
+
mediaHandler = RtcpReceivingSessionWrapper::Unwrap(val)->getSessionInstance();
|
|
23
|
+
else if (val.InstanceOf(RtcpSrReporterWrapper::constructor.Value()))
|
|
24
|
+
mediaHandler = RtcpSrReporterWrapper::Unwrap(val)->getReporterInstance();
|
|
25
|
+
else if (val.InstanceOf(RtpPacketizerWrapper::constructor.Value()))
|
|
26
|
+
mediaHandler = RtpPacketizerWrapper::Unwrap(val)->getPacketizerInstance();
|
|
27
|
+
return mediaHandler;
|
|
28
|
+
}
|
|
@@ -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,16 +1,17 @@
|
|
|
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
8
|
Napi::HandleScope scope(env);
|
|
9
9
|
|
|
10
10
|
Napi::Function func = Napi::ObjectWrap<RtcpReceivingSessionWrapper>::DefineClass(env, "RtcpReceivingSession",
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
{
|
|
12
|
+
// Instance Methods
|
|
13
|
+
InstanceMethod("addToChain", &RtcpReceivingSessionWrapper::addToChain),
|
|
14
|
+
});
|
|
14
15
|
|
|
15
16
|
// If this is not the first call, we don't want to reassign the constructor (hot-reload problem)
|
|
16
17
|
if (constructor.IsEmpty())
|
|
@@ -28,13 +29,29 @@ RtcpReceivingSessionWrapper::RtcpReceivingSessionWrapper(const Napi::CallbackInf
|
|
|
28
29
|
{
|
|
29
30
|
Napi::Env env = info.Env();
|
|
30
31
|
mSessionPtr = std::make_unique<rtc::RtcpReceivingSession>();
|
|
31
|
-
instances.insert(this);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
RtcpReceivingSessionWrapper::~RtcpReceivingSessionWrapper()
|
|
35
35
|
{
|
|
36
36
|
mSessionPtr.reset();
|
|
37
|
-
instances.erase(this);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
std::shared_ptr<rtc::RtcpReceivingSession> RtcpReceivingSessionWrapper::getSessionInstance() { return mSessionPtr; }
|
|
40
|
+
|
|
41
|
+
void RtcpReceivingSessionWrapper::addToChain(const Napi::CallbackInfo &info)
|
|
42
|
+
{
|
|
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);
|
|
57
|
+
}
|
|
@@ -17,11 +17,11 @@ public:
|
|
|
17
17
|
std::shared_ptr<rtc::RtcpReceivingSession> getSessionInstance();
|
|
18
18
|
|
|
19
19
|
// Functions
|
|
20
|
+
void addToChain(const Napi::CallbackInfo &info);
|
|
20
21
|
|
|
21
22
|
// Callbacks
|
|
22
23
|
|
|
23
24
|
private:
|
|
24
|
-
static std::unordered_set<RtcpReceivingSessionWrapper *> instances;
|
|
25
25
|
std::shared_ptr<rtc::RtcpReceivingSession> mSessionPtr = nullptr;
|
|
26
26
|
};
|
|
27
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
|