tirtc-react-native 2.3.0 → 2.4.0-alpha.3
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/README.md +23 -7
- package/TiRtcReactNative.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/src/main/AndroidManifest.xml +2 -1
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcModule.kt +585 -28
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeCleanup.kt +115 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeEventBinder.kt +35 -8
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeEventSink.kt +20 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeMaps.kt +62 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeModuleSupport.kt +6 -6
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeRegistry.kt +27 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeStoreSupport.kt +64 -0
- package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcVideoOutputViewManager.kt +17 -2
- package/ios/TiRtcReactNative+Conn.mm +173 -2
- package/ios/TiRtcReactNative+Input.mm +18 -4
- package/ios/TiRtcReactNative+Output.mm +41 -4
- package/ios/TiRtcReactNative+Private.h +4 -0
- package/ios/TiRtcReactNative+Store.mm +496 -0
- package/ios/TiRtcReactNative.h +2 -1
- package/ios/TiRtcReactNative.mm +109 -1
- package/ios/TiRtcReactNativeEventBinder.h +8 -0
- package/ios/TiRtcReactNativeEventBinder.mm +104 -0
- package/ios/TiRtcReactNativeEventSink.h +4 -0
- package/ios/TiRtcReactNativeEventSink.mm +20 -0
- package/ios/TiRtcReactNativeRegistry.h +5 -0
- package/ios/TiRtcReactNativeRegistry.mm +43 -0
- package/ios/TiRtcVideoOutputView.mm +11 -0
- package/lib/module/audio_input.js +33 -17
- package/lib/module/audio_input.js.map +1 -1
- package/lib/module/audio_output.js +27 -10
- package/lib/module/audio_output.js.map +1 -1
- package/lib/module/conn.js +31 -7
- package/lib/module/conn.js.map +1 -1
- package/lib/module/errors.js +4 -3
- package/lib/module/errors.js.map +1 -1
- package/lib/module/index.js +2 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/logging.js +9 -1
- package/lib/module/logging.js.map +1 -1
- package/lib/module/logging_internal.js +27 -0
- package/lib/module/logging_internal.js.map +1 -0
- package/lib/module/recording.js +210 -0
- package/lib/module/recording.js.map +1 -0
- package/lib/module/runtime.js +13 -5
- package/lib/module/runtime.js.map +1 -1
- package/lib/module/specs/NativeTiRtc.js.map +1 -1
- package/lib/module/store.js +698 -0
- package/lib/module/store.js.map +1 -0
- package/lib/module/video_input.js +40 -22
- package/lib/module/video_input.js.map +1 -1
- package/lib/module/video_output.js +51 -10
- package/lib/module/video_output.js.map +1 -1
- package/lib/typescript/audio_input.d.ts +1 -0
- package/lib/typescript/conn.d.ts +2 -0
- package/lib/typescript/errors.d.ts +3 -2
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/logging_internal.d.ts +2 -0
- package/lib/typescript/recording.d.ts +53 -0
- package/lib/typescript/runtime.d.ts +2 -0
- package/lib/typescript/specs/NativeTiRtc.d.ts +88 -0
- package/lib/typescript/store.d.ts +202 -0
- package/lib/typescript/video_input.d.ts +1 -0
- package/lib/typescript/video_output.d.ts +3 -0
- package/package.json +1 -1
- package/src/audio_input.ts +85 -59
- package/src/audio_output.ts +30 -17
- package/src/conn.ts +46 -28
- package/src/errors.ts +4 -3
- package/src/index.ts +54 -0
- package/src/logging.ts +7 -1
- package/src/logging_internal.ts +23 -0
- package/src/recording.ts +271 -0
- package/src/runtime.ts +14 -5
- package/src/specs/NativeTiRtc.ts +123 -0
- package/src/store.ts +760 -0
- package/src/video_input.ts +97 -62
- package/src/video_output.ts +54 -16
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
#import "TiRtcReactNative+Private.h"
|
|
2
|
+
|
|
3
|
+
#import "TiRtcReactNativeErrors.h"
|
|
4
|
+
#import "TiRtcReactNativeMaps.h"
|
|
5
|
+
|
|
6
|
+
#pragma clang diagnostic push
|
|
7
|
+
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
|
|
8
|
+
|
|
9
|
+
static NSInteger TiRtcReactNativeStoreReplaySpeedValue(TiStoreReplaySpeed speed) {
|
|
10
|
+
switch (speed) {
|
|
11
|
+
case TiStoreReplaySpeedX1: return 0;
|
|
12
|
+
case TiStoreReplaySpeedX2: return 1;
|
|
13
|
+
case TiStoreReplaySpeedX4: return 2;
|
|
14
|
+
case TiStoreReplaySpeedX8: return 3;
|
|
15
|
+
}
|
|
16
|
+
return 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static BOOL TiRtcReactNativeStoreReplaySpeedFromValue(NSInteger value, TiStoreReplaySpeed* speed) {
|
|
20
|
+
switch (value) {
|
|
21
|
+
case 0: *speed = TiStoreReplaySpeedX1; return YES;
|
|
22
|
+
case 1: *speed = TiStoreReplaySpeedX2; return YES;
|
|
23
|
+
case 2: *speed = TiStoreReplaySpeedX4; return YES;
|
|
24
|
+
case 3: *speed = TiStoreReplaySpeedX8; return YES;
|
|
25
|
+
default: return NO;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static NSString* TiRtcReactNativeStoreAudioState(TiStoreAudioOutputState state) {
|
|
30
|
+
switch (state) {
|
|
31
|
+
case TiStoreAudioOutputStateIdle: return @"idle";
|
|
32
|
+
case TiStoreAudioOutputStateBuffering: return @"buffering";
|
|
33
|
+
case TiStoreAudioOutputStatePlaying: return @"playing";
|
|
34
|
+
case TiStoreAudioOutputStateFailed: return @"failed";
|
|
35
|
+
case TiStoreAudioOutputStatePaused: return @"paused";
|
|
36
|
+
case TiStoreAudioOutputStateCompleted: return @"completed";
|
|
37
|
+
}
|
|
38
|
+
return @"failed";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static NSString* TiRtcReactNativeStoreVideoState(TiStoreVideoOutputState state) {
|
|
42
|
+
switch (state) {
|
|
43
|
+
case TiStoreVideoOutputStateIdle: return @"idle";
|
|
44
|
+
case TiStoreVideoOutputStateBuffering: return @"buffering";
|
|
45
|
+
case TiStoreVideoOutputStateRendering: return @"rendering";
|
|
46
|
+
case TiStoreVideoOutputStateFailed: return @"failed";
|
|
47
|
+
case TiStoreVideoOutputStatePaused: return @"paused";
|
|
48
|
+
case TiStoreVideoOutputStateCompleted: return @"completed";
|
|
49
|
+
}
|
|
50
|
+
return @"failed";
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static NSDictionary* TiRtcReactNativeStoreMp4Result(
|
|
54
|
+
TiRtcReactNativeRegistry* registry, TiStoreRecordingResult* result) {
|
|
55
|
+
NSInteger fileId = result.file == nil ? 0 : [registry addTransientObject:result.file];
|
|
56
|
+
return @{
|
|
57
|
+
@"code" : @(TiRtcReactNativeNormalizeDarwin(result.code)),
|
|
58
|
+
@"fileId" : fileId == 0 ? (id)kCFNull : @(fileId),
|
|
59
|
+
@"filePath" : result.file.path ?: (id)kCFNull,
|
|
60
|
+
@"durationMs" : result.file == nil ? (id)kCFNull : @(result.file.durationMs),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@interface TiRtcReactNativeStoreExportBridge : NSObject <TiRtcReactNativeReloadTask>
|
|
65
|
+
@property(nonatomic, strong) TiStoreExportTask* task;
|
|
66
|
+
@property(nonatomic, assign) NSInteger objectId;
|
|
67
|
+
- (instancetype)initWithRegistry:(TiRtcReactNativeRegistry*)registry;
|
|
68
|
+
- (void)complete:(TiStoreRecordingResult*)result;
|
|
69
|
+
- (void)await:(RCTPromiseResolveBlock)resolve;
|
|
70
|
+
@end
|
|
71
|
+
|
|
72
|
+
@implementation TiRtcReactNativeStoreExportBridge {
|
|
73
|
+
TiRtcReactNativeRegistry* _registry;
|
|
74
|
+
TiStoreRecordingResult* _result;
|
|
75
|
+
NSMutableArray<RCTPromiseResolveBlock>* _waiters;
|
|
76
|
+
BOOL _invalidated;
|
|
77
|
+
void (^_invalidationCompletion)(id file);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
- (instancetype)initWithRegistry:(TiRtcReactNativeRegistry*)registry {
|
|
81
|
+
if (self = [super init]) {
|
|
82
|
+
_registry = registry;
|
|
83
|
+
_waiters = [NSMutableArray new];
|
|
84
|
+
}
|
|
85
|
+
return self;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
- (void)complete:(TiStoreRecordingResult*)result {
|
|
89
|
+
NSArray<RCTPromiseResolveBlock>* waiters;
|
|
90
|
+
void (^invalidationCompletion)(id file);
|
|
91
|
+
@synchronized(self) {
|
|
92
|
+
if (_result != nil) return;
|
|
93
|
+
_result = result;
|
|
94
|
+
waiters = _invalidated ? @[] : [_waiters copy];
|
|
95
|
+
[_waiters removeAllObjects];
|
|
96
|
+
invalidationCompletion = _invalidationCompletion;
|
|
97
|
+
_invalidationCompletion = nil;
|
|
98
|
+
}
|
|
99
|
+
for (RCTPromiseResolveBlock resolve in waiters) {
|
|
100
|
+
resolve(TiRtcReactNativeStoreMp4Result(_registry, result));
|
|
101
|
+
}
|
|
102
|
+
if (waiters.count > 0 && self.objectId > 0) [_registry releaseObject:self.objectId];
|
|
103
|
+
if (invalidationCompletion != nil) invalidationCompletion(result.file);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
- (void)await:(RCTPromiseResolveBlock)resolve {
|
|
107
|
+
TiStoreRecordingResult* result;
|
|
108
|
+
@synchronized(self) {
|
|
109
|
+
result = _result;
|
|
110
|
+
if (result == nil) {
|
|
111
|
+
[_waiters addObject:[resolve copy]];
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
resolve(TiRtcReactNativeStoreMp4Result(_registry, result));
|
|
116
|
+
if (self.objectId > 0) [_registry releaseObject:self.objectId];
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
- (void)stopForReactNativeInvalidation:(void (^)(id file))completion {
|
|
120
|
+
TiStoreRecordingResult* result;
|
|
121
|
+
@synchronized(self) {
|
|
122
|
+
_invalidated = YES;
|
|
123
|
+
[_waiters removeAllObjects];
|
|
124
|
+
result = _result;
|
|
125
|
+
if (result == nil) _invalidationCompletion = [completion copy];
|
|
126
|
+
}
|
|
127
|
+
if (result != nil) {
|
|
128
|
+
completion(result.file);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
int32_t code = [self.task stop];
|
|
132
|
+
if (code != 0) {
|
|
133
|
+
@synchronized(self) {
|
|
134
|
+
_invalidationCompletion = nil;
|
|
135
|
+
}
|
|
136
|
+
completion(nil);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@end
|
|
141
|
+
|
|
142
|
+
@implementation TiRtcReactNative (Store)
|
|
143
|
+
|
|
144
|
+
- (void)storeInitialize:(JS::NativeTiRtc::NativeInitOptions&)options
|
|
145
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
146
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
147
|
+
int32_t code = [TiStore initializeWithAppId:options.appId() ?: @""
|
|
148
|
+
endpoint:options.endpoint() ?: @""
|
|
149
|
+
consoleLogEnabled:options.consoleLogEnabled()];
|
|
150
|
+
resolve(@(TiRtcReactNativeNormalizeDarwin(code)));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
- (NSNumber*)storeShutdown {
|
|
154
|
+
return @(TiRtcReactNativeNormalizeDarwin([TiStore shutdown]));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
- (NSDictionary*)storeCreate:(NSString*)token {
|
|
158
|
+
return [self
|
|
159
|
+
registerObject:^id { return [[TiStore alloc] initWithToken:token]; }
|
|
160
|
+
wire:^id(NSInteger objectId, id object) {
|
|
161
|
+
return [[self eventBinder] wireStore:(TiStore*)object objectId:objectId];
|
|
162
|
+
}];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
- (NSNumber*)storeUpdateToken:(double)objectId token:(NSString*)token {
|
|
166
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
167
|
+
return [object isKindOfClass:[TiStore class]]
|
|
168
|
+
? @(TiRtcReactNativeNormalizeDarwin([(TiStore*)object updateToken:token]))
|
|
169
|
+
: @(TiRtcReactNativeErrorObjectReleased);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
- (void)storeListRecordings:(double)objectId
|
|
173
|
+
startTimeMs:(double)startTimeMs
|
|
174
|
+
endTimeMs:(double)endTimeMs
|
|
175
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
176
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
177
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
178
|
+
if (![object isKindOfClass:[TiStore class]]) {
|
|
179
|
+
resolve(@{@"code" : @(TiRtcReactNativeErrorObjectReleased), @"recordings" : @[]});
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
TiStore* store = (TiStore*)object;
|
|
183
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
184
|
+
[store listRecordingsWithStartTimeMs:(int64_t)startTimeMs
|
|
185
|
+
endTimeMs:(int64_t)endTimeMs
|
|
186
|
+
completion:^(TiStoreRecordingRangesResult* result) {
|
|
187
|
+
NSMutableArray* ranges = [NSMutableArray arrayWithCapacity:result.recordings.count];
|
|
188
|
+
for (TiStoreRecordingRange* range in result.recordings) {
|
|
189
|
+
[ranges addObject:@{@"startTimeMs" : @(range.startTimeMs), @"endTimeMs" : @(range.endTimeMs)}];
|
|
190
|
+
}
|
|
191
|
+
resolve(@{@"code" : @(TiRtcReactNativeNormalizeDarwin(result.code)), @"recordings" : ranges});
|
|
192
|
+
}];
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
- (void)storeListRecordingDays:(double)objectId
|
|
197
|
+
startDate:(NSString*)startDate
|
|
198
|
+
endDate:(NSString*)endDate
|
|
199
|
+
timeZoneId:(NSString*)timeZoneId
|
|
200
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
201
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
202
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
203
|
+
if (![object isKindOfClass:[TiStore class]]) {
|
|
204
|
+
resolve(@{@"code" : @(TiRtcReactNativeErrorObjectReleased), @"days" : @[]});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
TiStore* store = (TiStore*)object;
|
|
208
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
209
|
+
[store listRecordingDaysWithStartDate:startDate
|
|
210
|
+
endDate:endDate
|
|
211
|
+
timeZoneId:timeZoneId
|
|
212
|
+
completion:^(TiStoreRecordingDaysResult* result) {
|
|
213
|
+
NSMutableArray* days = [NSMutableArray arrayWithCapacity:result.days.count];
|
|
214
|
+
for (TiStoreRecordingDay* day in result.days) {
|
|
215
|
+
[days addObject:@{@"date" : day.date, @"hasRecording" : @(day.hasRecording)}];
|
|
216
|
+
}
|
|
217
|
+
resolve(@{@"code" : @(TiRtcReactNativeNormalizeDarwin(result.code)), @"days" : days});
|
|
218
|
+
}];
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
- (NSDictionary*)storeCreateReplay:(double)objectId {
|
|
223
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
224
|
+
if (![object isKindOfClass:[TiStore class]]) {
|
|
225
|
+
return TiRtcReactNativeCreateResult(TiRtcReactNativeErrorObjectReleased, 0, 0, nil);
|
|
226
|
+
}
|
|
227
|
+
return [self
|
|
228
|
+
registerObject:^id { return [(TiStore*)object createReplay]; }
|
|
229
|
+
wire:^id(NSInteger replayId, id replay) {
|
|
230
|
+
return [[self eventBinder] wireStoreReplay:(TiStoreReplay*)replay objectId:replayId];
|
|
231
|
+
}];
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
- (NSDictionary*)storeExportRecording:(double)objectId
|
|
235
|
+
startTimeMs:(double)startTimeMs
|
|
236
|
+
endTimeMs:(double)endTimeMs
|
|
237
|
+
videoChannelId:(double)videoChannelId
|
|
238
|
+
audioChannelId:(NSNumber*)audioChannelId {
|
|
239
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
240
|
+
if (![object isKindOfClass:[TiStore class]]) {
|
|
241
|
+
return @{@"code" : @(TiRtcReactNativeErrorObjectReleased), @"taskId" : (id)kCFNull};
|
|
242
|
+
}
|
|
243
|
+
TiRtcReactNativeStoreExportBridge* bridge =
|
|
244
|
+
[[TiRtcReactNativeStoreExportBridge alloc] initWithRegistry:[self registry]];
|
|
245
|
+
TiStoreExportRequest* request = [[TiStoreExportRequest alloc]
|
|
246
|
+
initWithStartTimeMs:(int64_t)startTimeMs
|
|
247
|
+
endTimeMs:(int64_t)endTimeMs
|
|
248
|
+
videoChannelId:(NSInteger)videoChannelId
|
|
249
|
+
audioChannelId:audioChannelId];
|
|
250
|
+
TiStoreExportTaskStartResult* started = [(TiStore*)object
|
|
251
|
+
exportRecording:request
|
|
252
|
+
progress:nil
|
|
253
|
+
completion:^(TiStoreRecordingResult* result) { [bridge complete:result]; }];
|
|
254
|
+
if (started.code != 0 || started.task == nil) {
|
|
255
|
+
return @{@"code" : @(TiRtcReactNativeNormalizeDarwin(started.code)), @"taskId" : (id)kCFNull};
|
|
256
|
+
}
|
|
257
|
+
bridge.task = started.task;
|
|
258
|
+
bridge.objectId = [[self registry] addObject:bridge];
|
|
259
|
+
return @{@"code" : @0, @"taskId" : @(bridge.objectId)};
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
- (NSNumber*)storeExportProgress:(double)objectId {
|
|
263
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
264
|
+
return [object isKindOfClass:[TiRtcReactNativeStoreExportBridge class]]
|
|
265
|
+
? @(((TiRtcReactNativeStoreExportBridge*)object).task.progress)
|
|
266
|
+
: @0;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
- (void)storeExportResult:(double)objectId
|
|
270
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
271
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
272
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
273
|
+
if (![object isKindOfClass:[TiRtcReactNativeStoreExportBridge class]]) {
|
|
274
|
+
resolve(@{@"code" : @(TiRtcReactNativeErrorObjectReleased), @"fileId" : (id)kCFNull,
|
|
275
|
+
@"filePath" : (id)kCFNull, @"durationMs" : (id)kCFNull});
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
[(TiRtcReactNativeStoreExportBridge*)object await:resolve];
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
- (NSNumber*)storeExportStop:(double)objectId {
|
|
282
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
283
|
+
if (![object isKindOfClass:[TiRtcReactNativeStoreExportBridge class]]) {
|
|
284
|
+
return @(TiRtcReactNativeErrorObjectReleased);
|
|
285
|
+
}
|
|
286
|
+
TiStoreExportTask* task = ((TiRtcReactNativeStoreExportBridge*)object).task;
|
|
287
|
+
return @(TiRtcReactNativeNormalizeDarwin([task stop]));
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
- (NSNumber*)storeDispose:(double)objectId {
|
|
291
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
292
|
+
if (![object isKindOfClass:[TiStore class]]) return @(TiRtcReactNativeErrorObjectReleased);
|
|
293
|
+
int32_t code = [(TiStore*)object dispose];
|
|
294
|
+
if (code == 0) [[self registry] releaseObject:(NSInteger)objectId];
|
|
295
|
+
return @(TiRtcReactNativeNormalizeDarwin(code));
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
- (NSDictionary*)storeReplayGetInfo:(double)objectId {
|
|
299
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
300
|
+
if (![object isKindOfClass:[TiStoreReplay class]]) {
|
|
301
|
+
return @{@"code" : @(TiRtcReactNativeErrorObjectReleased), @"speed" : @0,
|
|
302
|
+
@"currentTimeMs" : (id)kCFNull};
|
|
303
|
+
}
|
|
304
|
+
TiStoreReplay* replay = (TiStoreReplay*)object;
|
|
305
|
+
return @{@"code" : @0, @"speed" : @(TiRtcReactNativeStoreReplaySpeedValue(replay.speed)),
|
|
306
|
+
@"currentTimeMs" : replay.currentTimeMs ?: (id)kCFNull};
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
- (NSNumber*)storeReplayPlay:(double)objectId
|
|
310
|
+
startTimeMs:(double)startTimeMs
|
|
311
|
+
endTimeMs:(double)endTimeMs
|
|
312
|
+
initialTimeMs:(NSNumber*)initialTimeMs {
|
|
313
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
314
|
+
return [object isKindOfClass:[TiStoreReplay class]]
|
|
315
|
+
? @(TiRtcReactNativeNormalizeDarwin([(TiStoreReplay*)object
|
|
316
|
+
playWithStartTimeMs:(int64_t)startTimeMs
|
|
317
|
+
endTimeMs:(int64_t)endTimeMs
|
|
318
|
+
initialTimeMs:initialTimeMs]))
|
|
319
|
+
: @(TiRtcReactNativeErrorObjectReleased);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
- (NSNumber*)storeReplayPause:(double)objectId { return [self storeReplayCode:objectId selector:@selector(pause)]; }
|
|
323
|
+
- (NSNumber*)storeReplayResume:(double)objectId { return [self storeReplayCode:objectId selector:@selector(resume)]; }
|
|
324
|
+
- (NSNumber*)storeReplayStop:(double)objectId { return [self storeReplayCode:objectId selector:@selector(stop)]; }
|
|
325
|
+
|
|
326
|
+
- (NSNumber*)storeReplaySeek:(double)objectId timeMs:(double)timeMs {
|
|
327
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
328
|
+
return [object isKindOfClass:[TiStoreReplay class]]
|
|
329
|
+
? @(TiRtcReactNativeNormalizeDarwin([(TiStoreReplay*)object seekToTimeMs:(int64_t)timeMs]))
|
|
330
|
+
: @(TiRtcReactNativeErrorObjectReleased);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
- (NSNumber*)storeReplaySetSpeed:(double)objectId speed:(double)speed {
|
|
334
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
335
|
+
if (![object isKindOfClass:[TiStoreReplay class]]) return @(TiRtcReactNativeErrorObjectReleased);
|
|
336
|
+
TiStoreReplaySpeed mapped;
|
|
337
|
+
if (!TiRtcReactNativeStoreReplaySpeedFromValue((NSInteger)speed, &mapped)) return @(6000);
|
|
338
|
+
return @(TiRtcReactNativeNormalizeDarwin([(TiStoreReplay*)object setSpeed:mapped]));
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
- (NSDictionary*)storeReplayStartRecording:(double)objectId
|
|
342
|
+
videoChannelId:(double)videoChannelId
|
|
343
|
+
audioChannelId:(NSNumber*)audioChannelId {
|
|
344
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
345
|
+
if (![object isKindOfClass:[TiStoreReplay class]]) {
|
|
346
|
+
return @{@"code" : @(TiRtcReactNativeErrorObjectReleased), @"taskId" : (id)kCFNull};
|
|
347
|
+
}
|
|
348
|
+
TiStoreRecordingTaskStartResult* started = [(TiStoreReplay*)object
|
|
349
|
+
startRecordingWithVideoChannelId:(NSInteger)videoChannelId audioChannelId:audioChannelId];
|
|
350
|
+
if (started.code != 0 || started.task == nil) {
|
|
351
|
+
return @{@"code" : @(TiRtcReactNativeNormalizeDarwin(started.code)), @"taskId" : (id)kCFNull};
|
|
352
|
+
}
|
|
353
|
+
NSInteger taskId = [[self registry] addObject:started.task];
|
|
354
|
+
return @{@"code" : @0, @"taskId" : @(taskId)};
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
- (void)storeRecordingTaskStop:(double)objectId
|
|
358
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
359
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
360
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
361
|
+
if (![object isKindOfClass:[TiStoreRecordingTask class]]) {
|
|
362
|
+
resolve(@{@"code" : @(TiRtcReactNativeErrorObjectReleased), @"fileId" : (id)kCFNull,
|
|
363
|
+
@"filePath" : (id)kCFNull, @"durationMs" : (id)kCFNull});
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
[(TiStoreRecordingTask*)object stopWithCompletion:^(TiStoreRecordingResult* result) {
|
|
367
|
+
[[self registry] releaseObject:(NSInteger)objectId];
|
|
368
|
+
resolve(TiRtcReactNativeStoreMp4Result([self registry], result));
|
|
369
|
+
}];
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
- (NSNumber*)storeReplayDispose:(double)objectId {
|
|
373
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
374
|
+
if (![object isKindOfClass:[TiStoreReplay class]]) return @(TiRtcReactNativeErrorObjectReleased);
|
|
375
|
+
int32_t code = [(TiStoreReplay*)object dispose];
|
|
376
|
+
if (code == 0) [[self registry] releaseObject:(NSInteger)objectId];
|
|
377
|
+
return @(TiRtcReactNativeNormalizeDarwin(code));
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
- (NSNumber*)storeReplayCode:(double)objectId selector:(SEL)selector {
|
|
381
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
382
|
+
if (![object isKindOfClass:[TiStoreReplay class]]) return @(TiRtcReactNativeErrorObjectReleased);
|
|
383
|
+
IMP implementation = [object methodForSelector:selector];
|
|
384
|
+
int32_t (*call)(id, SEL) = (int32_t (*)(id, SEL))implementation;
|
|
385
|
+
return @(TiRtcReactNativeNormalizeDarwin(call(object, selector)));
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
- (NSDictionary*)storeCreateAudioOutput {
|
|
389
|
+
return [self
|
|
390
|
+
registerObject:^id { return [TiStoreAudioOutput new]; }
|
|
391
|
+
wire:^id(NSInteger objectId, id object) {
|
|
392
|
+
return [[self eventBinder] wireStoreAudioOutput:(TiStoreAudioOutput*)object objectId:objectId];
|
|
393
|
+
}];
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
- (NSDictionary*)storeAudioOutputGetState:(double)objectId {
|
|
397
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
398
|
+
if (![object isKindOfClass:[TiStoreAudioOutput class]]) {
|
|
399
|
+
return TiRtcReactNativeStateResult(TiRtcReactNativeErrorObjectReleased, nil);
|
|
400
|
+
}
|
|
401
|
+
return TiRtcReactNativeStateResult(0, TiRtcReactNativeStoreAudioState(((TiStoreAudioOutput*)object).state));
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
- (NSNumber*)storeAudioOutputSetVolume:(double)objectId volumePercent:(double)volumePercent {
|
|
405
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
406
|
+
return [object isKindOfClass:[TiStoreAudioOutput class]]
|
|
407
|
+
? @(TiRtcReactNativeNormalizeDarwin([(TiStoreAudioOutput*)object setVolume:(uint32_t)volumePercent]))
|
|
408
|
+
: @(TiRtcReactNativeErrorObjectReleased);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
- (NSNumber*)storeAudioOutputAttach:(double)outputId replayId:(double)replayId channelId:(double)channelId {
|
|
412
|
+
id output = [[self registry] objectForId:(NSInteger)outputId];
|
|
413
|
+
id replay = [[self registry] objectForId:(NSInteger)replayId];
|
|
414
|
+
return [output isKindOfClass:[TiStoreAudioOutput class]] && [replay isKindOfClass:[TiStoreReplay class]]
|
|
415
|
+
? @(TiRtcReactNativeNormalizeDarwin([(TiStoreAudioOutput*)output
|
|
416
|
+
attachWithReplay:(TiStoreReplay*)replay channelId:(uint8_t)channelId]))
|
|
417
|
+
: @(TiRtcReactNativeErrorObjectReleased);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
- (NSNumber*)storeAudioOutputDetach:(double)objectId {
|
|
421
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
422
|
+
return [object isKindOfClass:[TiStoreAudioOutput class]]
|
|
423
|
+
? @(TiRtcReactNativeNormalizeDarwin([(TiStoreAudioOutput*)object detach]))
|
|
424
|
+
: @(TiRtcReactNativeErrorObjectReleased);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
- (NSNumber*)storeAudioOutputDispose:(double)objectId {
|
|
428
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
429
|
+
if (![object isKindOfClass:[TiStoreAudioOutput class]]) return @(TiRtcReactNativeErrorObjectReleased);
|
|
430
|
+
int32_t code = [(TiStoreAudioOutput*)object dispose];
|
|
431
|
+
if (code == 0) [[self registry] releaseObject:(NSInteger)objectId];
|
|
432
|
+
return @(TiRtcReactNativeNormalizeDarwin(code));
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
- (NSDictionary*)storeCreateVideoOutput {
|
|
436
|
+
return [self
|
|
437
|
+
registerObject:^id { return [TiStoreVideoOutput new]; }
|
|
438
|
+
wire:^id(NSInteger objectId, id object) {
|
|
439
|
+
return [[self eventBinder] wireStoreVideoOutput:(TiStoreVideoOutput*)object objectId:objectId];
|
|
440
|
+
}];
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
- (NSDictionary*)storeVideoOutputGetState:(double)objectId {
|
|
444
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
445
|
+
if (![object isKindOfClass:[TiStoreVideoOutput class]]) {
|
|
446
|
+
return TiRtcReactNativeStateResult(TiRtcReactNativeErrorObjectReleased, nil);
|
|
447
|
+
}
|
|
448
|
+
return TiRtcReactNativeStateResult(0, TiRtcReactNativeStoreVideoState(((TiStoreVideoOutput*)object).state));
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
- (NSNumber*)storeVideoOutputAttach:(double)outputId replayId:(double)replayId channelId:(double)channelId {
|
|
452
|
+
id output = [[self registry] objectForId:(NSInteger)outputId];
|
|
453
|
+
id replay = [[self registry] objectForId:(NSInteger)replayId];
|
|
454
|
+
return [output isKindOfClass:[TiStoreVideoOutput class]] && [replay isKindOfClass:[TiStoreReplay class]]
|
|
455
|
+
? @(TiRtcReactNativeNormalizeDarwin([(TiStoreVideoOutput*)output
|
|
456
|
+
attachWithReplay:(TiStoreReplay*)replay channelId:(uint8_t)channelId]))
|
|
457
|
+
: @(TiRtcReactNativeErrorObjectReleased);
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
- (NSNumber*)storeVideoOutputDetach:(double)objectId {
|
|
461
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
462
|
+
return [object isKindOfClass:[TiStoreVideoOutput class]]
|
|
463
|
+
? @(TiRtcReactNativeNormalizeDarwin([(TiStoreVideoOutput*)object detach]))
|
|
464
|
+
: @(TiRtcReactNativeErrorObjectReleased);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
- (void)storeVideoOutputTakeSnapshot:(double)objectId
|
|
468
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
469
|
+
reject:(RCTPromiseRejectBlock)reject {
|
|
470
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
471
|
+
if (![object isKindOfClass:[TiStoreVideoOutput class]]) {
|
|
472
|
+
resolve(@{@"code" : @(TiRtcReactNativeErrorObjectReleased), @"fileId" : (id)kCFNull,
|
|
473
|
+
@"filePath" : (id)kCFNull});
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
TiStoreVideoOutput* output = (TiStoreVideoOutput*)object;
|
|
477
|
+
dispatch_async(dispatch_get_main_queue(), ^{
|
|
478
|
+
[output takeSnapshotWithCompletion:^(TiStoreSnapshotResult* result) {
|
|
479
|
+
NSInteger fileId = result.file == nil ? 0 : [[self registry] addTransientObject:result.file];
|
|
480
|
+
resolve(@{@"code" : @(TiRtcReactNativeNormalizeDarwin(result.code)),
|
|
481
|
+
@"fileId" : fileId == 0 ? (id)kCFNull : @(fileId),
|
|
482
|
+
@"filePath" : result.file.path ?: (id)kCFNull});
|
|
483
|
+
}];
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
- (NSNumber*)storeVideoOutputDispose:(double)objectId {
|
|
488
|
+
id object = [[self registry] objectForId:(NSInteger)objectId];
|
|
489
|
+
if (![object isKindOfClass:[TiStoreVideoOutput class]]) return @(TiRtcReactNativeErrorObjectReleased);
|
|
490
|
+
int32_t code = [(TiStoreVideoOutput*)object dispose];
|
|
491
|
+
if (code == 0) [[self registry] releaseObject:(NSInteger)objectId];
|
|
492
|
+
return @(TiRtcReactNativeNormalizeDarwin(code));
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
@end
|
|
496
|
+
#pragma clang diagnostic pop
|
package/ios/TiRtcReactNative.h
CHANGED
package/ios/TiRtcReactNative.mm
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#import "TiRtcReactNative.h"
|
|
2
|
+
#import "TiRtcReactNative+Private.h"
|
|
2
3
|
|
|
3
4
|
#import <React/RCTBridgeModule.h>
|
|
4
5
|
|
|
6
|
+
#import <atomic>
|
|
5
7
|
#import <memory>
|
|
6
8
|
|
|
7
9
|
#import "TiRtcReactNativeErrors.h"
|
|
@@ -12,23 +14,51 @@
|
|
|
12
14
|
#import "TiRtcReactNativeOptions.h"
|
|
13
15
|
#import "TiRtcReactNativeRegistry.h"
|
|
14
16
|
|
|
17
|
+
@protocol TiRtcReactNativeMediaFile <NSObject>
|
|
18
|
+
- (void)deleteWithCompletion:(void (^)(int32_t code))completion;
|
|
19
|
+
@end
|
|
20
|
+
|
|
21
|
+
static void TiRtcReactNativeLogInvalidationFailure(NSString* operation, int32_t code) {
|
|
22
|
+
if (code == 0 || code == TiRtcReactNativeErrorObjectReleased) return;
|
|
23
|
+
[TiRtcLogging logWithLevel:TiRtcLogLevelWarning
|
|
24
|
+
tag:@"TIRTC_REACT_NATIVE"
|
|
25
|
+
message:[NSString stringWithFormat:
|
|
26
|
+
@"[module_invalidate] operation=%@ error_code=%d",
|
|
27
|
+
operation, code]];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
static void TiRtcReactNativeDeleteForInvalidation(id file, dispatch_group_t group) {
|
|
31
|
+
if (file == nil || ![file respondsToSelector:@selector(deleteWithCompletion:)]) return;
|
|
32
|
+
dispatch_group_enter(group);
|
|
33
|
+
[(id<TiRtcReactNativeMediaFile>)file deleteWithCompletion:^(int32_t code) {
|
|
34
|
+
TiRtcReactNativeLogInvalidationFailure(@"media_delete", code);
|
|
35
|
+
dispatch_group_leave(group);
|
|
36
|
+
}];
|
|
37
|
+
}
|
|
38
|
+
|
|
15
39
|
#pragma clang diagnostic push
|
|
16
40
|
#pragma clang diagnostic ignored "-Wprotocol"
|
|
17
41
|
@implementation TiRtcReactNative {
|
|
18
42
|
TiRtcReactNativeRegistry* _registry;
|
|
19
43
|
TiRtcReactNativeEventSink* _eventSink;
|
|
20
44
|
TiRtcReactNativeEventBinder* _eventBinder;
|
|
45
|
+
std::atomic_bool _invalidated;
|
|
21
46
|
}
|
|
22
47
|
|
|
23
48
|
RCT_EXPORT_MODULE(TiRtc)
|
|
24
49
|
|
|
25
50
|
- (instancetype)init {
|
|
26
51
|
if (self = [super init]) {
|
|
52
|
+
_invalidated.store(false);
|
|
27
53
|
_registry = [TiRtcReactNativeRegistry sharedRegistry];
|
|
28
54
|
__weak TiRtcReactNative* weakSelf = self;
|
|
29
55
|
_eventSink = [[TiRtcReactNativeEventSink alloc] initWithRegistry:_registry
|
|
30
56
|
emitBlock:^(NSDictionary* event) {
|
|
31
|
-
|
|
57
|
+
TiRtcReactNative* strongSelf = weakSelf;
|
|
58
|
+
if (strongSelf != nil &&
|
|
59
|
+
!strongSelf->_invalidated.load()) {
|
|
60
|
+
[strongSelf emitOnTiRtcEvent:event];
|
|
61
|
+
}
|
|
32
62
|
}];
|
|
33
63
|
[_registry setEventSink:_eventSink];
|
|
34
64
|
_eventBinder = [[TiRtcReactNativeEventBinder alloc] initWithEventSink:_eventSink];
|
|
@@ -36,6 +66,84 @@ RCT_EXPORT_MODULE(TiRtc)
|
|
|
36
66
|
return self;
|
|
37
67
|
}
|
|
38
68
|
|
|
69
|
+
- (void)invalidate {
|
|
70
|
+
if (_invalidated.exchange(true)) return;
|
|
71
|
+
NSArray* objects = [_registry drainObjects];
|
|
72
|
+
NSArray* files = [_registry drainTransientObjects];
|
|
73
|
+
dispatch_group_t pending = dispatch_group_create();
|
|
74
|
+
for (id file in files) TiRtcReactNativeDeleteForInvalidation(file, pending);
|
|
75
|
+
for (id object in objects) {
|
|
76
|
+
if ([object isKindOfClass:[TiRtcRecordingTask class]]) {
|
|
77
|
+
dispatch_group_enter(pending);
|
|
78
|
+
[(TiRtcRecordingTask*)object stopWithCompletion:^(TiRtcRecordingResult* result) {
|
|
79
|
+
TiRtcReactNativeDeleteForInvalidation(result.file, pending);
|
|
80
|
+
dispatch_group_leave(pending);
|
|
81
|
+
}];
|
|
82
|
+
} else if ([object isKindOfClass:[TiStoreRecordingTask class]]) {
|
|
83
|
+
dispatch_group_enter(pending);
|
|
84
|
+
[(TiStoreRecordingTask*)object stopWithCompletion:^(TiStoreRecordingResult* result) {
|
|
85
|
+
TiRtcReactNativeDeleteForInvalidation(result.file, pending);
|
|
86
|
+
dispatch_group_leave(pending);
|
|
87
|
+
}];
|
|
88
|
+
} else if ([object conformsToProtocol:@protocol(TiRtcReactNativeReloadTask)]) {
|
|
89
|
+
dispatch_group_enter(pending);
|
|
90
|
+
[(id<TiRtcReactNativeReloadTask>)object
|
|
91
|
+
stopForReactNativeInvalidation:^(id file) {
|
|
92
|
+
TiRtcReactNativeDeleteForInvalidation(file, pending);
|
|
93
|
+
dispatch_group_leave(pending);
|
|
94
|
+
}];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
dispatch_group_notify(pending, dispatch_get_main_queue(), ^{
|
|
98
|
+
for (TiStoreAudioOutput* output in objects) {
|
|
99
|
+
if (![output isKindOfClass:[TiStoreAudioOutput class]]) continue;
|
|
100
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_audio_detach", [output detach]);
|
|
101
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_audio_dispose", [output dispose]);
|
|
102
|
+
}
|
|
103
|
+
for (TiStoreVideoOutput* output in objects) {
|
|
104
|
+
if (![output isKindOfClass:[TiStoreVideoOutput class]]) continue;
|
|
105
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_video_detach", [output detach]);
|
|
106
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_video_view_detach", [output detachView]);
|
|
107
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_video_dispose", [output dispose]);
|
|
108
|
+
}
|
|
109
|
+
for (TiRtcAudioOutput* output in objects) {
|
|
110
|
+
if ([output isKindOfClass:[TiRtcAudioOutput class]])
|
|
111
|
+
TiRtcReactNativeLogInvalidationFailure(@"audio_output_dispose", [output dispose]);
|
|
112
|
+
}
|
|
113
|
+
for (TiRtcVideoOutput* output in objects) {
|
|
114
|
+
if ([output isKindOfClass:[TiRtcVideoOutput class]])
|
|
115
|
+
TiRtcReactNativeLogInvalidationFailure(@"video_output_dispose", [output dispose]);
|
|
116
|
+
}
|
|
117
|
+
for (TiRtcAudioInput* input in objects) {
|
|
118
|
+
if ([input isKindOfClass:[TiRtcAudioInput class]])
|
|
119
|
+
TiRtcReactNativeLogInvalidationFailure(@"audio_input_dispose", [input dispose]);
|
|
120
|
+
}
|
|
121
|
+
for (TiRtcVideoInput* input in objects) {
|
|
122
|
+
if ([input isKindOfClass:[TiRtcVideoInput class]])
|
|
123
|
+
TiRtcReactNativeLogInvalidationFailure(@"video_input_dispose", [input dispose]);
|
|
124
|
+
}
|
|
125
|
+
for (TiStoreReplay* replay in objects) {
|
|
126
|
+
if (![replay isKindOfClass:[TiStoreReplay class]]) continue;
|
|
127
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_replay_stop", [replay stop]);
|
|
128
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_replay_dispose", [replay dispose]);
|
|
129
|
+
}
|
|
130
|
+
for (TiRtcConn* conn in objects) {
|
|
131
|
+
if (![conn isKindOfClass:[TiRtcConn class]]) continue;
|
|
132
|
+
TiRtcReactNativeLogInvalidationFailure(@"conn_disconnect", [conn disconnect]);
|
|
133
|
+
TiRtcReactNativeLogInvalidationFailure(@"conn_dispose", [conn dispose]);
|
|
134
|
+
}
|
|
135
|
+
for (TiStore* store in objects) {
|
|
136
|
+
if ([store isKindOfClass:[TiStore class]])
|
|
137
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_dispose", [store dispose]);
|
|
138
|
+
}
|
|
139
|
+
TiRtcReactNativeLogInvalidationFailure(@"store_shutdown", [TiStore shutdown]);
|
|
140
|
+
TiRtcReactNativeLogInvalidationFailure(@"runtime_shutdown", [TiRtc shutdown]);
|
|
141
|
+
[TiRtcLogging logWithLevel:TiRtcLogLevelInfo
|
|
142
|
+
tag:@"TIRTC_REACT_NATIVE"
|
|
143
|
+
message:@"[module_invalidate] native owners released"];
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
39
147
|
- (void)initialize:(JS::NativeTiRtc::NativeInitOptions&)options
|
|
40
148
|
resolve:(RCTPromiseResolveBlock)resolve
|
|
41
149
|
reject:(RCTPromiseRejectBlock)reject {
|
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
@class TiRtcReactNativeEventSink;
|
|
7
7
|
@class TiRtcVideoInput;
|
|
8
8
|
@class TiRtcVideoOutput;
|
|
9
|
+
@class TiStore;
|
|
10
|
+
@class TiStoreAudioOutput;
|
|
11
|
+
@class TiStoreReplay;
|
|
12
|
+
@class TiStoreVideoOutput;
|
|
9
13
|
|
|
10
14
|
@interface TiRtcReactNativeEventBinder : NSObject
|
|
11
15
|
|
|
@@ -15,5 +19,9 @@
|
|
|
15
19
|
- (id)wireVideoOutput:(TiRtcVideoOutput*)output objectId:(NSInteger)objectId;
|
|
16
20
|
- (id)wireAudioInput:(TiRtcAudioInput*)input objectId:(NSInteger)objectId;
|
|
17
21
|
- (id)wireVideoInput:(TiRtcVideoInput*)input objectId:(NSInteger)objectId;
|
|
22
|
+
- (id)wireStore:(TiStore*)store objectId:(NSInteger)objectId;
|
|
23
|
+
- (id)wireStoreReplay:(TiStoreReplay*)replay objectId:(NSInteger)objectId;
|
|
24
|
+
- (id)wireStoreAudioOutput:(TiStoreAudioOutput*)output objectId:(NSInteger)objectId;
|
|
25
|
+
- (id)wireStoreVideoOutput:(TiStoreVideoOutput*)output objectId:(NSInteger)objectId;
|
|
18
26
|
|
|
19
27
|
@end
|