react-native-webrtc-nitro 1.0.0 → 1.1.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/cpp/FFmpeg/Muxer.cpp +1 -1
- package/cpp/Hybrid/HybridMediaRecorder.cpp +118 -0
- package/cpp/Hybrid/HybridMediaRecorder.hpp +36 -0
- package/cpp/__tests__/FFmpeg/testMuxer.cpp +18 -32
- package/lib/commonjs/index.js +11 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/specs/MediaRecorder.nitro.js +16 -0
- package/lib/commonjs/specs/MediaRecorder.nitro.js.map +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/specs/MediaRecorder.nitro.js +13 -0
- package/lib/module/specs/MediaRecorder.nitro.js.map +1 -0
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/specs/MediaRecorder.nitro.d.ts +17 -0
- package/lib/typescript/src/specs/MediaRecorder.nitro.d.ts.map +1 -0
- package/nitro.json +3 -0
- package/nitrogen/generated/android/Webrtc+autolinking.cmake +1 -0
- package/nitrogen/generated/android/WebrtcOnLoad.cpp +10 -0
- package/nitrogen/generated/ios/WebrtcAutolinking.mm +10 -0
- package/nitrogen/generated/shared/c++/HybridMediaRecorderSpec.cpp +25 -0
- package/nitrogen/generated/shared/c++/HybridMediaRecorderSpec.hpp +69 -0
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/specs/MediaRecorder.nitro.ts +24 -0
package/cpp/FFmpeg/Muxer.cpp
CHANGED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
#include "HybridMediaRecorder.hpp"
|
|
2
|
+
#include "FramePipe.hpp"
|
|
3
|
+
#include <filesystem>
|
|
4
|
+
|
|
5
|
+
using namespace margelo::nitro::webrtc;
|
|
6
|
+
|
|
7
|
+
auto HybridMediaRecorder::takePhoto (const std::string &file)
|
|
8
|
+
-> std::shared_ptr<Promise<void>>
|
|
9
|
+
{
|
|
10
|
+
if (mediaStream == nullptr)
|
|
11
|
+
{
|
|
12
|
+
throw std::runtime_error (
|
|
13
|
+
"MediaStream is not set for HybridMediaRecorder");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if (std::filesystem::path (file).extension () != ".png")
|
|
17
|
+
{
|
|
18
|
+
throw std::invalid_argument ("Only .png format is supported");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
auto tracks = mediaStream->getVideoTracks ();
|
|
22
|
+
if (tracks.empty ())
|
|
23
|
+
{
|
|
24
|
+
throw std::runtime_error ("No video tracks available in MediaStream");
|
|
25
|
+
}
|
|
26
|
+
std::string srcPipeId = tracks[0]->get_srcPipeId ();
|
|
27
|
+
return Promise<void>::async (
|
|
28
|
+
[this, srcPipeId, file] () -> void
|
|
29
|
+
{
|
|
30
|
+
auto encoder = std::make_shared<FFmpeg::Encoder> (AV_CODEC_ID_PNG);
|
|
31
|
+
FrameCallback callback =
|
|
32
|
+
[this, encoder, file] (const std::string &, int subscriptionId,
|
|
33
|
+
const FFmpeg::Frame &frame)
|
|
34
|
+
{
|
|
35
|
+
FILE *f = fopen (file.c_str (), "wb");
|
|
36
|
+
if (!f)
|
|
37
|
+
{
|
|
38
|
+
throw std::invalid_argument ("Failed to open file " + file
|
|
39
|
+
+ " for writing");
|
|
40
|
+
}
|
|
41
|
+
encoder->send (frame);
|
|
42
|
+
encoder->flush ();
|
|
43
|
+
for (const FFmpeg::Packet &packet : encoder->receive ())
|
|
44
|
+
{
|
|
45
|
+
fwrite (packet->data, 1, packet->size, f);
|
|
46
|
+
}
|
|
47
|
+
fclose (f);
|
|
48
|
+
::unsubscribe (subscriptionId);
|
|
49
|
+
this->subscriptionId = -1;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
this->subscriptionId
|
|
53
|
+
= subscribe ({ srcPipeId }, callback, nullptr);
|
|
54
|
+
|
|
55
|
+
// wait for the callback to be called
|
|
56
|
+
while (this->subscriptionId != -1)
|
|
57
|
+
{
|
|
58
|
+
std::this_thread::sleep_for (std::chrono::milliseconds (10));
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
void HybridMediaRecorder::startRecording (const std::string &file)
|
|
64
|
+
{
|
|
65
|
+
if (mediaStream == nullptr)
|
|
66
|
+
{
|
|
67
|
+
throw std::runtime_error (
|
|
68
|
+
"MediaStream is not set for HybridMediaRecorder");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (std::filesystem::path (file).extension () != ".mp4")
|
|
72
|
+
{
|
|
73
|
+
throw std::invalid_argument ("Only .mp4 format is supported c++");
|
|
74
|
+
}
|
|
75
|
+
AVCodecID audioCodecId = AV_CODEC_ID_NONE;
|
|
76
|
+
AVCodecID videoCodecId = AV_CODEC_ID_NONE;
|
|
77
|
+
std::string audioPipeId = "";
|
|
78
|
+
std::string videoPipeId = "";
|
|
79
|
+
std::vector<std::string> pipeIds;
|
|
80
|
+
if (!mediaStream->getAudioTracks ().empty ())
|
|
81
|
+
{
|
|
82
|
+
audioPipeId = mediaStream->getAudioTracks ()[0]->get_srcPipeId ();
|
|
83
|
+
pipeIds.push_back (audioPipeId);
|
|
84
|
+
audioCodecId = AV_CODEC_ID_AAC;
|
|
85
|
+
}
|
|
86
|
+
if (!mediaStream->getVideoTracks ().empty ())
|
|
87
|
+
{
|
|
88
|
+
videoPipeId = mediaStream->getVideoTracks ()[0]->get_srcPipeId ();
|
|
89
|
+
pipeIds.push_back (videoPipeId);
|
|
90
|
+
videoCodecId = AV_CODEC_ID_H264;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
auto muxer
|
|
94
|
+
= std::make_shared<FFmpeg::Muxer> (file, audioCodecId, videoCodecId);
|
|
95
|
+
FrameCallback callback
|
|
96
|
+
= [muxer, audioPipeId, videoPipeId] (const std::string &pipeId, int,
|
|
97
|
+
const FFmpeg::Frame &frame)
|
|
98
|
+
{
|
|
99
|
+
if (pipeId == audioPipeId)
|
|
100
|
+
{
|
|
101
|
+
muxer->writeAudio (frame);
|
|
102
|
+
}
|
|
103
|
+
if (pipeId == videoPipeId)
|
|
104
|
+
{
|
|
105
|
+
muxer->writeVideo (frame);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
CleanupCallback cleanup = [muxer] (int) { muxer->stop (); };
|
|
110
|
+
|
|
111
|
+
subscriptionId = subscribe (pipeIds, callback, cleanup);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
void HybridMediaRecorder::stopRecording ()
|
|
115
|
+
{
|
|
116
|
+
unsubscribe (subscriptionId);
|
|
117
|
+
subscriptionId = -1;
|
|
118
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
#include "HybridMediaRecorderSpec.hpp"
|
|
3
|
+
#include "HybridMediaStream.hpp"
|
|
4
|
+
#include <NitroModules/Promise.hpp>
|
|
5
|
+
|
|
6
|
+
namespace margelo::nitro::webrtc
|
|
7
|
+
{
|
|
8
|
+
class HybridMediaRecorder : public HybridMediaRecorderSpec
|
|
9
|
+
{
|
|
10
|
+
private:
|
|
11
|
+
std::shared_ptr<HybridMediaStream> mediaStream = nullptr;
|
|
12
|
+
int subscriptionId = -1;
|
|
13
|
+
|
|
14
|
+
public:
|
|
15
|
+
HybridMediaRecorder () : HybridObject (TAG), HybridMediaRecorderSpec ()
|
|
16
|
+
{
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
auto getStream () -> std::shared_ptr<HybridMediaStreamSpec> override
|
|
20
|
+
{
|
|
21
|
+
return mediaStream;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
void setStream (
|
|
25
|
+
const std::shared_ptr<HybridMediaStreamSpec> &mediaStream) override
|
|
26
|
+
{
|
|
27
|
+
this->mediaStream
|
|
28
|
+
= std::dynamic_pointer_cast<HybridMediaStream> (mediaStream);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
auto takePhoto (const std::string &file)
|
|
32
|
+
-> std::shared_ptr<Promise<void>> override;
|
|
33
|
+
void startRecording (const std::string &file) override;
|
|
34
|
+
void stopRecording () override;
|
|
35
|
+
};
|
|
36
|
+
} // namespace margelo::nitro::webrtc
|
|
@@ -11,13 +11,16 @@ constexpr int HEIGHT = 480;
|
|
|
11
11
|
|
|
12
12
|
TEST (MuxerTest, testMuxerAAC)
|
|
13
13
|
{
|
|
14
|
-
std::string file =
|
|
14
|
+
std::string file = "test_aac.mp4";
|
|
15
15
|
Muxer muxer (file, AV_CODEC_ID_AAC, AV_CODEC_ID_NONE);
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
for (int i = 0; i < 1000; ++i)
|
|
18
|
+
{
|
|
19
|
+
Frame inputFrame (AV_SAMPLE_FMT_FLT, AUDIO_SAMPLE_RATE, 1,
|
|
20
|
+
AUDIO_NB_SAMPLES, i * AUDIO_NB_SAMPLES);
|
|
21
|
+
inputFrame.fillNoise ();
|
|
22
|
+
muxer.writeAudio (inputFrame);
|
|
23
|
+
}
|
|
21
24
|
muxer.stop ();
|
|
22
25
|
|
|
23
26
|
EXPECT_TRUE (std::filesystem::exists (file));
|
|
@@ -25,46 +28,29 @@ TEST (MuxerTest, testMuxerAAC)
|
|
|
25
28
|
|
|
26
29
|
TEST (MuxerTest, testMuxerH264)
|
|
27
30
|
{
|
|
28
|
-
std::string file =
|
|
29
|
-
|
|
31
|
+
std::string file = "test_h264.mp4";
|
|
30
32
|
Muxer muxer (file, AV_CODEC_ID_NONE, AV_CODEC_ID_H264);
|
|
31
|
-
Frame inputFrame (AV_PIX_FMT_NV12, WIDTH, HEIGHT);
|
|
32
|
-
inputFrame.fillNoise ();
|
|
33
|
-
muxer.writeVideo (inputFrame);
|
|
34
|
-
muxer.stop ();
|
|
35
|
-
|
|
36
|
-
EXPECT_TRUE (std::filesystem::exists (file));
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
TEST (MuxerTest, testMuxerVideo)
|
|
40
|
-
{
|
|
41
|
-
std::string file = testing::TempDir () + "/test_file.mp4";
|
|
42
|
-
Muxer muxer (file, AV_CODEC_ID_AAC, AV_CODEC_ID_H264);
|
|
43
|
-
|
|
44
|
-
Frame audioFrame (AV_SAMPLE_FMT_FLT, AUDIO_SAMPLE_RATE, 1,
|
|
45
|
-
AUDIO_NB_SAMPLES);
|
|
46
|
-
Frame videoFrame (AV_PIX_FMT_NV12, WIDTH, HEIGHT);
|
|
47
|
-
audioFrame.fillNoise ();
|
|
48
|
-
videoFrame.fillNoise ();
|
|
49
|
-
muxer.writeAudio (audioFrame);
|
|
50
|
-
muxer.writeVideo (videoFrame);
|
|
51
33
|
|
|
34
|
+
for (int i = 0; i < 1000; ++i)
|
|
35
|
+
{
|
|
36
|
+
Frame inputFrame (AV_PIX_FMT_NV12, WIDTH, HEIGHT, i * 3000);
|
|
37
|
+
inputFrame.fillNoise ();
|
|
38
|
+
muxer.writeVideo (inputFrame);
|
|
39
|
+
}
|
|
52
40
|
muxer.stop ();
|
|
53
41
|
EXPECT_TRUE (std::filesystem::exists (file));
|
|
54
42
|
}
|
|
55
43
|
|
|
56
|
-
TEST (MuxerTest,
|
|
44
|
+
TEST (MuxerTest, testMuxerVideo)
|
|
57
45
|
{
|
|
58
46
|
std::string file = "output.mp4";
|
|
59
47
|
Muxer muxer (file, AV_CODEC_ID_AAC, AV_CODEC_ID_H264);
|
|
60
|
-
constexpr int LOOPS = 1000;
|
|
61
|
-
constexpr int VIDEO_SAMPLES = 3000;
|
|
62
48
|
|
|
63
|
-
for (int i = 0; i <
|
|
49
|
+
for (int i = 0; i < 1000; ++i)
|
|
64
50
|
{
|
|
65
51
|
Frame audioFrame (AV_SAMPLE_FMT_FLT, AUDIO_SAMPLE_RATE, 1,
|
|
66
52
|
AUDIO_NB_SAMPLES, i * AUDIO_NB_SAMPLES);
|
|
67
|
-
Frame videoFrame (AV_PIX_FMT_NV12, WIDTH, HEIGHT, i *
|
|
53
|
+
Frame videoFrame (AV_PIX_FMT_NV12, WIDTH, HEIGHT, i * 3000);
|
|
68
54
|
audioFrame.fillNoise ();
|
|
69
55
|
videoFrame.fillNoise ();
|
|
70
56
|
muxer.writeAudio (audioFrame);
|
package/lib/commonjs/index.js
CHANGED
|
@@ -91,4 +91,15 @@ Object.keys(_RTCRtpTransceiver).forEach(function (key) {
|
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
93
|
});
|
|
94
|
+
var _MediaRecorder = require("./specs/MediaRecorder.nitro");
|
|
95
|
+
Object.keys(_MediaRecorder).forEach(function (key) {
|
|
96
|
+
if (key === "default" || key === "__esModule") return;
|
|
97
|
+
if (key in exports && exports[key] === _MediaRecorder[key]) return;
|
|
98
|
+
Object.defineProperty(exports, key, {
|
|
99
|
+
enumerable: true,
|
|
100
|
+
get: function () {
|
|
101
|
+
return _MediaRecorder[key];
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
94
105
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_WebrtcView","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_MediaDevices","_MediaStream","_MediaStreamTrack","_RTCPeerConnection","_RTCRtpSender","_RTCRtpReceiver","_RTCRtpTransceiver"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["_WebrtcView","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_MediaDevices","_MediaStream","_MediaStreamTrack","_RTCPeerConnection","_RTCRtpSender","_RTCRtpReceiver","_RTCRtpTransceiver","_MediaRecorder"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.MediaRecorder = void 0;
|
|
7
|
+
var _reactNativeNitroModules = require("react-native-nitro-modules");
|
|
8
|
+
const MediaRecorderConstructor = (0, _reactNativeNitroModules.getHybridObjectConstructor)('MediaRecorder');
|
|
9
|
+
const MediaRecorderExport = exports.MediaRecorder = new Proxy(MediaRecorderConstructor, {
|
|
10
|
+
construct(target, args) {
|
|
11
|
+
const instance = new target();
|
|
12
|
+
instance.stream = args[0];
|
|
13
|
+
return instance;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=MediaRecorder.nitro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNativeNitroModules","require","MediaRecorderConstructor","getHybridObjectConstructor","MediaRecorderExport","exports","MediaRecorder","Proxy","construct","target","args","instance","stream"],"sourceRoot":"../../../src","sources":["specs/MediaRecorder.nitro.ts"],"mappings":";;;;;;AACA,IAAAA,wBAAA,GAAAC,OAAA;AAUA,MAAMC,wBAAwB,GAC5B,IAAAC,mDAA0B,EAAgB,eAAe,CAAC;AAE5D,MAAMC,mBAAmB,GAAAC,OAAA,CAAAC,aAAA,GAAG,IAAIC,KAAK,CAACL,wBAAwB,EAAE;EAC9DM,SAASA,CAACC,MAAM,EAAEC,IAAI,EAAE;IACtB,MAAMC,QAAQ,GAAG,IAAIF,MAAM,CAAC,CAAC;IAC7BE,QAAQ,CAACC,MAAM,GAAGF,IAAI,CAAC,CAAC,CAAgB;IACxC,OAAOC,QAAQ;EACjB;AACF,CAAC,CAAiD","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -8,4 +8,5 @@ export * from './specs/RTCPeerConnection.nitro';
|
|
|
8
8
|
export * from './specs/RTCRtpSender.nitro';
|
|
9
9
|
export * from './specs/RTCRtpReceiver.nitro';
|
|
10
10
|
export * from './specs/RTCRtpTransceiver.nitro';
|
|
11
|
+
export * from './specs/MediaRecorder.nitro';
|
|
11
12
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,cAAc,oBAAoB;AAClC,cAAc,4BAA4B;AAC1C,cAAc,2BAA2B;AACzC,cAAc,gCAAgC;AAC9C,cAAc,iCAAiC;AAC/C,cAAc,4BAA4B;AAC1C,cAAc,8BAA8B;AAC5C,cAAc,iCAAiC","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,cAAc,oBAAoB;AAClC,cAAc,4BAA4B;AAC1C,cAAc,2BAA2B;AACzC,cAAc,gCAAgC;AAC9C,cAAc,iCAAiC;AAC/C,cAAc,4BAA4B;AAC1C,cAAc,8BAA8B;AAC5C,cAAc,iCAAiC;AAC/C,cAAc,6BAA6B","ignoreList":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { getHybridObjectConstructor } from 'react-native-nitro-modules';
|
|
4
|
+
const MediaRecorderConstructor = getHybridObjectConstructor('MediaRecorder');
|
|
5
|
+
const MediaRecorderExport = new Proxy(MediaRecorderConstructor, {
|
|
6
|
+
construct(target, args) {
|
|
7
|
+
const instance = new target();
|
|
8
|
+
instance.stream = args[0];
|
|
9
|
+
return instance;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
export { MediaRecorderExport as MediaRecorder };
|
|
13
|
+
//# sourceMappingURL=MediaRecorder.nitro.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["getHybridObjectConstructor","MediaRecorderConstructor","MediaRecorderExport","Proxy","construct","target","args","instance","stream","MediaRecorder"],"sourceRoot":"../../../src","sources":["specs/MediaRecorder.nitro.ts"],"mappings":";;AACA,SAASA,0BAA0B,QAAQ,4BAA4B;AAUvE,MAAMC,wBAAwB,GAC5BD,0BAA0B,CAAgB,eAAe,CAAC;AAE5D,MAAME,mBAAmB,GAAG,IAAIC,KAAK,CAACF,wBAAwB,EAAE;EAC9DG,SAASA,CAACC,MAAM,EAAEC,IAAI,EAAE;IACtB,MAAMC,QAAQ,GAAG,IAAIF,MAAM,CAAC,CAAC;IAC7BE,QAAQ,CAACC,MAAM,GAAGF,IAAI,CAAC,CAAC,CAAgB;IACxC,OAAOC,QAAQ;EACjB;AACF,CAAC,CAAiD;AAGlD,SAASL,mBAAmB,IAAIO,aAAa","ignoreList":[]}
|
|
@@ -6,4 +6,5 @@ export * from './specs/RTCPeerConnection.nitro';
|
|
|
6
6
|
export * from './specs/RTCRtpSender.nitro';
|
|
7
7
|
export * from './specs/RTCRtpReceiver.nitro';
|
|
8
8
|
export * from './specs/RTCRtpTransceiver.nitro';
|
|
9
|
+
export * from './specs/MediaRecorder.nitro';
|
|
9
10
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,iCAAiC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAA;AAClC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,2BAA2B,CAAA;AACzC,cAAc,gCAAgC,CAAA;AAC9C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,4BAA4B,CAAA;AAC1C,cAAc,8BAA8B,CAAA;AAC5C,cAAc,iCAAiC,CAAA;AAC/C,cAAc,6BAA6B,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type HybridObject } from 'react-native-nitro-modules';
|
|
2
|
+
import { MediaStream } from './MediaStream.nitro';
|
|
3
|
+
interface MediaRecorder extends HybridObject<{
|
|
4
|
+
ios: 'c++';
|
|
5
|
+
android: 'c++';
|
|
6
|
+
}> {
|
|
7
|
+
stream: MediaStream;
|
|
8
|
+
takePhoto(file: string): Promise<void>;
|
|
9
|
+
startRecording(file: string): void;
|
|
10
|
+
stopRecording(): void;
|
|
11
|
+
}
|
|
12
|
+
declare const MediaRecorderExport: {
|
|
13
|
+
new (stream: MediaStream): MediaRecorder;
|
|
14
|
+
};
|
|
15
|
+
type MediaRecorderExport = MediaRecorder;
|
|
16
|
+
export { MediaRecorderExport as MediaRecorder };
|
|
17
|
+
//# sourceMappingURL=MediaRecorder.nitro.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaRecorder.nitro.d.ts","sourceRoot":"","sources":["../../../../src/specs/MediaRecorder.nitro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAE9D,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEjD,UAAU,aAAc,SAAQ,YAAY,CAAC;IAAE,GAAG,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,CAAC;IAC1E,MAAM,EAAE,WAAW,CAAA;IACnB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,IAAI,IAAI,CAAA;CACtB;AAKD,QAAA,MAAM,mBAAmB,EAMnB;IAAE,KAAK,MAAM,EAAE,WAAW,GAAG,aAAa,CAAA;CAAE,CAAA;AAElD,KAAK,mBAAmB,GAAG,aAAa,CAAA;AACxC,OAAO,EAAE,mBAAmB,IAAI,aAAa,EAAE,CAAA"}
|
package/nitro.json
CHANGED
|
@@ -35,6 +35,7 @@ target_sources(
|
|
|
35
35
|
# Shared Nitrogen C++ sources
|
|
36
36
|
../nitrogen/generated/shared/c++/HybridCameraSpec.cpp
|
|
37
37
|
../nitrogen/generated/shared/c++/HybridMediaDevicesSpec.cpp
|
|
38
|
+
../nitrogen/generated/shared/c++/HybridMediaRecorderSpec.cpp
|
|
38
39
|
../nitrogen/generated/shared/c++/HybridMediaStreamSpec.cpp
|
|
39
40
|
../nitrogen/generated/shared/c++/HybridMediaStreamTrackSpec.cpp
|
|
40
41
|
../nitrogen/generated/shared/c++/HybridMicrophoneSpec.cpp
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
#include "HybridMediaStreamTrack.hpp"
|
|
24
24
|
#include "HybridMediaStream.hpp"
|
|
25
25
|
#include "HybridMediaDevices.hpp"
|
|
26
|
+
#include "HybridMediaRecorder.hpp"
|
|
26
27
|
#include "HybridRTCRtpSender.hpp"
|
|
27
28
|
#include "HybridRTCRtpReceiver.hpp"
|
|
28
29
|
#include "HybridRTCRtpTransceiver.hpp"
|
|
@@ -94,6 +95,15 @@ int initialize(JavaVM* vm) {
|
|
|
94
95
|
return std::make_shared<HybridMediaDevices>();
|
|
95
96
|
}
|
|
96
97
|
);
|
|
98
|
+
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
99
|
+
"MediaRecorder",
|
|
100
|
+
[]() -> std::shared_ptr<HybridObject> {
|
|
101
|
+
static_assert(std::is_default_constructible_v<HybridMediaRecorder>,
|
|
102
|
+
"The HybridObject \"HybridMediaRecorder\" is not default-constructible! "
|
|
103
|
+
"Create a public constructor that takes zero arguments to be able to autolink this HybridObject.");
|
|
104
|
+
return std::make_shared<HybridMediaRecorder>();
|
|
105
|
+
}
|
|
106
|
+
);
|
|
97
107
|
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
98
108
|
"RTCRtpSender",
|
|
99
109
|
[]() -> std::shared_ptr<HybridObject> {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
#include "HybridMediaStream.hpp"
|
|
17
17
|
#include "HybridWebrtcViewSpecSwift.hpp"
|
|
18
18
|
#include "HybridMediaDevices.hpp"
|
|
19
|
+
#include "HybridMediaRecorder.hpp"
|
|
19
20
|
#include "HybridRTCRtpSender.hpp"
|
|
20
21
|
#include "HybridRTCRtpReceiver.hpp"
|
|
21
22
|
#include "HybridRTCRtpTransceiver.hpp"
|
|
@@ -78,6 +79,15 @@
|
|
|
78
79
|
return std::make_shared<HybridMediaDevices>();
|
|
79
80
|
}
|
|
80
81
|
);
|
|
82
|
+
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
83
|
+
"MediaRecorder",
|
|
84
|
+
[]() -> std::shared_ptr<HybridObject> {
|
|
85
|
+
static_assert(std::is_default_constructible_v<HybridMediaRecorder>,
|
|
86
|
+
"The HybridObject \"HybridMediaRecorder\" is not default-constructible! "
|
|
87
|
+
"Create a public constructor that takes zero arguments to be able to autolink this HybridObject.");
|
|
88
|
+
return std::make_shared<HybridMediaRecorder>();
|
|
89
|
+
}
|
|
90
|
+
);
|
|
81
91
|
HybridObjectRegistry::registerHybridObjectConstructor(
|
|
82
92
|
"RTCRtpSender",
|
|
83
93
|
[]() -> std::shared_ptr<HybridObject> {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// HybridMediaRecorderSpec.cpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#include "HybridMediaRecorderSpec.hpp"
|
|
9
|
+
|
|
10
|
+
namespace margelo::nitro::webrtc {
|
|
11
|
+
|
|
12
|
+
void HybridMediaRecorderSpec::loadHybridMethods() {
|
|
13
|
+
// load base methods/properties
|
|
14
|
+
HybridObject::loadHybridMethods();
|
|
15
|
+
// load custom methods/properties
|
|
16
|
+
registerHybrids(this, [](Prototype& prototype) {
|
|
17
|
+
prototype.registerHybridGetter("stream", &HybridMediaRecorderSpec::getStream);
|
|
18
|
+
prototype.registerHybridSetter("stream", &HybridMediaRecorderSpec::setStream);
|
|
19
|
+
prototype.registerHybridMethod("takePhoto", &HybridMediaRecorderSpec::takePhoto);
|
|
20
|
+
prototype.registerHybridMethod("startRecording", &HybridMediaRecorderSpec::startRecording);
|
|
21
|
+
prototype.registerHybridMethod("stopRecording", &HybridMediaRecorderSpec::stopRecording);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
} // namespace margelo::nitro::webrtc
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
///
|
|
2
|
+
/// HybridMediaRecorderSpec.hpp
|
|
3
|
+
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
|
|
4
|
+
/// https://github.com/mrousavy/nitro
|
|
5
|
+
/// Copyright © 2025 Marc Rousavy @ Margelo
|
|
6
|
+
///
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#if __has_include(<NitroModules/HybridObject.hpp>)
|
|
11
|
+
#include <NitroModules/HybridObject.hpp>
|
|
12
|
+
#else
|
|
13
|
+
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
|
|
14
|
+
#endif
|
|
15
|
+
|
|
16
|
+
// Forward declaration of `HybridMediaStreamSpec` to properly resolve imports.
|
|
17
|
+
namespace margelo::nitro::webrtc { class HybridMediaStreamSpec; }
|
|
18
|
+
|
|
19
|
+
#include <memory>
|
|
20
|
+
#include "HybridMediaStreamSpec.hpp"
|
|
21
|
+
#include <NitroModules/Promise.hpp>
|
|
22
|
+
#include <string>
|
|
23
|
+
|
|
24
|
+
namespace margelo::nitro::webrtc {
|
|
25
|
+
|
|
26
|
+
using namespace margelo::nitro;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* An abstract base class for `MediaRecorder`
|
|
30
|
+
* Inherit this class to create instances of `HybridMediaRecorderSpec` in C++.
|
|
31
|
+
* You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
|
|
32
|
+
* @example
|
|
33
|
+
* ```cpp
|
|
34
|
+
* class HybridMediaRecorder: public HybridMediaRecorderSpec {
|
|
35
|
+
* public:
|
|
36
|
+
* HybridMediaRecorder(...): HybridObject(TAG) { ... }
|
|
37
|
+
* // ...
|
|
38
|
+
* };
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
class HybridMediaRecorderSpec: public virtual HybridObject {
|
|
42
|
+
public:
|
|
43
|
+
// Constructor
|
|
44
|
+
explicit HybridMediaRecorderSpec(): HybridObject(TAG) { }
|
|
45
|
+
|
|
46
|
+
// Destructor
|
|
47
|
+
~HybridMediaRecorderSpec() override = default;
|
|
48
|
+
|
|
49
|
+
public:
|
|
50
|
+
// Properties
|
|
51
|
+
virtual std::shared_ptr<HybridMediaStreamSpec> getStream() = 0;
|
|
52
|
+
virtual void setStream(const std::shared_ptr<HybridMediaStreamSpec>& stream) = 0;
|
|
53
|
+
|
|
54
|
+
public:
|
|
55
|
+
// Methods
|
|
56
|
+
virtual std::shared_ptr<Promise<void>> takePhoto(const std::string& file) = 0;
|
|
57
|
+
virtual void startRecording(const std::string& file) = 0;
|
|
58
|
+
virtual void stopRecording() = 0;
|
|
59
|
+
|
|
60
|
+
protected:
|
|
61
|
+
// Hybrid Setup
|
|
62
|
+
void loadHybridMethods() override;
|
|
63
|
+
|
|
64
|
+
protected:
|
|
65
|
+
// Tag for logging
|
|
66
|
+
static constexpr auto TAG = "MediaRecorder";
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
} // namespace margelo::nitro::webrtc
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type HybridObject } from 'react-native-nitro-modules'
|
|
2
|
+
import { getHybridObjectConstructor } from 'react-native-nitro-modules'
|
|
3
|
+
import { MediaStream } from './MediaStream.nitro'
|
|
4
|
+
|
|
5
|
+
interface MediaRecorder extends HybridObject<{ ios: 'c++'; android: 'c++' }> {
|
|
6
|
+
stream: MediaStream
|
|
7
|
+
takePhoto(file: string): Promise<void>
|
|
8
|
+
startRecording(file: string): void
|
|
9
|
+
stopRecording(): void
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const MediaRecorderConstructor =
|
|
13
|
+
getHybridObjectConstructor<MediaRecorder>('MediaRecorder')
|
|
14
|
+
|
|
15
|
+
const MediaRecorderExport = new Proxy(MediaRecorderConstructor, {
|
|
16
|
+
construct(target, args) {
|
|
17
|
+
const instance = new target()
|
|
18
|
+
instance.stream = args[0] as MediaStream
|
|
19
|
+
return instance
|
|
20
|
+
},
|
|
21
|
+
}) as { new (stream: MediaStream): MediaRecorder }
|
|
22
|
+
|
|
23
|
+
type MediaRecorderExport = MediaRecorder
|
|
24
|
+
export { MediaRecorderExport as MediaRecorder }
|