tirtc-react-native 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/LICENSE +11 -0
  2. package/README.md +140 -0
  3. package/TiRtcReactNative.podspec +35 -0
  4. package/android/build.gradle +37 -0
  5. package/android/src/main/AndroidManifest.xml +1 -0
  6. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcModule.kt +482 -0
  7. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcPackage.kt +43 -0
  8. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeErrors.kt +32 -0
  9. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeEventBinder.kt +99 -0
  10. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeEventSink.kt +168 -0
  11. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeMaps.kt +49 -0
  12. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeMetricsMaps.kt +173 -0
  13. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeModuleSupport.kt +91 -0
  14. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeOptions.kt +127 -0
  15. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcReactNativeRegistry.kt +71 -0
  16. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcVideoInputPreviewManager.kt +109 -0
  17. package/android/src/main/java/com/tange/ai/tirtc/reactnative/TiRtcVideoOutputViewManager.kt +109 -0
  18. package/ios/TiRtcReactNative+Conn.mm +112 -0
  19. package/ios/TiRtcReactNative+Input.mm +196 -0
  20. package/ios/TiRtcReactNative+Output.mm +172 -0
  21. package/ios/TiRtcReactNative+Private.h +28 -0
  22. package/ios/TiRtcReactNative.h +6 -0
  23. package/ios/TiRtcReactNative.mm +189 -0
  24. package/ios/TiRtcReactNativeErrors.h +18 -0
  25. package/ios/TiRtcReactNativeErrors.mm +105 -0
  26. package/ios/TiRtcReactNativeEventBinder.h +19 -0
  27. package/ios/TiRtcReactNativeEventBinder.mm +226 -0
  28. package/ios/TiRtcReactNativeEventSink.h +29 -0
  29. package/ios/TiRtcReactNativeEventSink.mm +125 -0
  30. package/ios/TiRtcReactNativeMaps.h +21 -0
  31. package/ios/TiRtcReactNativeMaps.mm +249 -0
  32. package/ios/TiRtcReactNativeNative.h +8 -0
  33. package/ios/TiRtcReactNativeOptions.h +11 -0
  34. package/ios/TiRtcReactNativeOptions.mm +123 -0
  35. package/ios/TiRtcReactNativeRegistry.h +20 -0
  36. package/ios/TiRtcReactNativeRegistry.mm +119 -0
  37. package/ios/TiRtcVideoInputPreview.h +5 -0
  38. package/ios/TiRtcVideoInputPreview.mm +149 -0
  39. package/ios/TiRtcVideoOutputView.h +5 -0
  40. package/ios/TiRtcVideoOutputView.mm +149 -0
  41. package/lib/module/audio_input.js +177 -0
  42. package/lib/module/audio_input.js.map +1 -0
  43. package/lib/module/audio_output.js +168 -0
  44. package/lib/module/audio_output.js.map +1 -0
  45. package/lib/module/conn.js +174 -0
  46. package/lib/module/conn.js.map +1 -0
  47. package/lib/module/errors.js +63 -0
  48. package/lib/module/errors.js.map +1 -0
  49. package/lib/module/events.js +37 -0
  50. package/lib/module/events.js.map +1 -0
  51. package/lib/module/index.js +9 -0
  52. package/lib/module/index.js.map +1 -0
  53. package/lib/module/logging.js +26 -0
  54. package/lib/module/logging.js.map +1 -0
  55. package/lib/module/native.js +5 -0
  56. package/lib/module/native.js.map +1 -0
  57. package/lib/module/native_object_id.js +47 -0
  58. package/lib/module/native_object_id.js.map +1 -0
  59. package/lib/module/runtime.js +27 -0
  60. package/lib/module/runtime.js.map +1 -0
  61. package/lib/module/specs/NativeTiRtc.js +3 -0
  62. package/lib/module/specs/NativeTiRtc.js.map +1 -0
  63. package/lib/module/specs/TiRtcVideoInputPreviewNativeComponent.js +24 -0
  64. package/lib/module/specs/TiRtcVideoOutputViewNativeComponent.js +24 -0
  65. package/lib/module/types.js +93 -0
  66. package/lib/module/types.js.map +1 -0
  67. package/lib/module/video_input.js +266 -0
  68. package/lib/module/video_input.js.map +1 -0
  69. package/lib/module/video_output.js +224 -0
  70. package/lib/module/video_output.js.map +1 -0
  71. package/lib/typescript/audio_input.d.ts +25 -0
  72. package/lib/typescript/audio_output.d.ts +25 -0
  73. package/lib/typescript/conn.d.ts +28 -0
  74. package/lib/typescript/errors.d.ts +19 -0
  75. package/lib/typescript/events.d.ts +6 -0
  76. package/lib/typescript/index.d.ts +9 -0
  77. package/lib/typescript/logging.d.ts +9 -0
  78. package/lib/typescript/native.d.ts +5 -0
  79. package/lib/typescript/native_object_id.d.ts +12 -0
  80. package/lib/typescript/runtime.d.ts +8 -0
  81. package/lib/typescript/specs/NativeTiRtc.d.ts +223 -0
  82. package/lib/typescript/specs/TiRtcVideoInputPreviewNativeComponent.d.ts +8 -0
  83. package/lib/typescript/specs/TiRtcVideoOutputViewNativeComponent.d.ts +8 -0
  84. package/lib/typescript/types.d.ts +281 -0
  85. package/lib/typescript/video_input.d.ts +50 -0
  86. package/lib/typescript/video_output.d.ts +46 -0
  87. package/package.json +80 -0
  88. package/react-native.config.js +10 -0
  89. package/src/audio_input.ts +205 -0
  90. package/src/audio_output.ts +202 -0
  91. package/src/conn.ts +222 -0
  92. package/src/errors.ts +81 -0
  93. package/src/events.ts +44 -0
  94. package/src/index.ts +61 -0
  95. package/src/logging.ts +33 -0
  96. package/src/native.ts +6 -0
  97. package/src/native_object_id.ts +63 -0
  98. package/src/runtime.ts +32 -0
  99. package/src/specs/NativeTiRtc.ts +256 -0
  100. package/src/specs/TiRtcVideoInputPreviewNativeComponent.ts +14 -0
  101. package/src/specs/TiRtcVideoOutputViewNativeComponent.ts +12 -0
  102. package/src/types.ts +340 -0
  103. package/src/video_input.ts +314 -0
  104. package/src/video_output.ts +273 -0
@@ -0,0 +1,123 @@
1
+ #import "TiRtcReactNativeOptions.h"
2
+
3
+ static TiRtcAudioAecMode TiRtcReactNativeAudioAecMode(NSString* value) {
4
+ return [value isEqualToString:@"enabled"] ? TiRtcAudioAecModeEnabled : TiRtcAudioAecModeDisabled;
5
+ }
6
+
7
+ static TiRtcAudioAgcLevel TiRtcReactNativeAudioAgcLevel(NSString* value) {
8
+ if ([value isEqualToString:@"low"]) {
9
+ return TiRtcAudioAgcLevelLow;
10
+ }
11
+ if ([value isEqualToString:@"medium"]) {
12
+ return TiRtcAudioAgcLevelMedium;
13
+ }
14
+ if ([value isEqualToString:@"high"]) {
15
+ return TiRtcAudioAgcLevelHigh;
16
+ }
17
+ return TiRtcAudioAgcLevelDisabled;
18
+ }
19
+
20
+ static TiRtcAudioAnsLevel TiRtcReactNativeAudioAnsLevel(NSString* value) {
21
+ if ([value isEqualToString:@"low"]) {
22
+ return TiRtcAudioAnsLevelLow;
23
+ }
24
+ if ([value isEqualToString:@"medium"]) {
25
+ return TiRtcAudioAnsLevelMedium;
26
+ }
27
+ if ([value isEqualToString:@"high"]) {
28
+ return TiRtcAudioAnsLevelHigh;
29
+ }
30
+ return TiRtcAudioAnsLevelDisabled;
31
+ }
32
+
33
+ static TiRtcVideoDecoderPreference TiRtcReactNativeVideoDecoderPreference(NSString* value) {
34
+ if ([value isEqualToString:@"software"]) {
35
+ return TiRtcVideoDecoderPreferenceSoftware;
36
+ }
37
+ if ([value isEqualToString:@"hardware"]) {
38
+ return TiRtcVideoDecoderPreferenceHardware;
39
+ }
40
+ return TiRtcVideoDecoderPreferenceAuto;
41
+ }
42
+
43
+ static TiRtcOutputBufferStrategy TiRtcReactNativeBufferStrategy(NSString* value) {
44
+ return [value isEqualToString:@"noBuffer"] ? TiRtcOutputBufferStrategyNoBuffer
45
+ : TiRtcOutputBufferStrategyAutomatic;
46
+ }
47
+
48
+ static NSNumber* TiRtcReactNativeOptionalDouble(std::optional<double> value) {
49
+ return value.has_value() ? @(value.value()) : nil;
50
+ }
51
+
52
+ TiRtcAudioOutputOptions* TiRtcReactNativeAudioOutputOptions(
53
+ JS::NativeTiRtc::NativeAudioOutputOptions& options) {
54
+ TiRtcAudioOutputOptions* nativeOptions = [TiRtcAudioOutputOptions new];
55
+ nativeOptions.agcLevel = TiRtcReactNativeAudioAgcLevel(options.agcLevel());
56
+ nativeOptions.ansLevel = TiRtcReactNativeAudioAnsLevel(options.ansLevel());
57
+ nativeOptions.bufferStrategy = TiRtcReactNativeBufferStrategy(options.bufferStrategy());
58
+ nativeOptions.maxBufferWatermarkMs =
59
+ TiRtcReactNativeOptionalDouble(options.maxBufferWatermarkMs());
60
+ return nativeOptions;
61
+ }
62
+
63
+ TiRtcVideoOutputOptions* TiRtcReactNativeVideoOutputOptions(
64
+ JS::NativeTiRtc::NativeVideoOutputOptions& options) {
65
+ TiRtcVideoOutputOptions* nativeOptions = [TiRtcVideoOutputOptions new];
66
+ nativeOptions.decoderPreference =
67
+ TiRtcReactNativeVideoDecoderPreference(options.decoderPreference());
68
+ nativeOptions.bufferStrategy = TiRtcReactNativeBufferStrategy(options.bufferStrategy());
69
+ nativeOptions.maxBufferWatermarkMs =
70
+ TiRtcReactNativeOptionalDouble(options.maxBufferWatermarkMs());
71
+ return nativeOptions;
72
+ }
73
+
74
+ TiRtcAudioInputOptions* TiRtcReactNativeAudioInputOptions(
75
+ JS::NativeTiRtc::NativeAudioInputOptions& options) {
76
+ TiRtcAudioInputOptions* nativeOptions = [TiRtcAudioInputOptions new];
77
+ NSString* codec = options.codec();
78
+ if ([codec isEqualToString:@"aac"]) {
79
+ nativeOptions.codec = TiRtcAudioCodecAac;
80
+ } else if ([codec isEqualToString:@"pcm"]) {
81
+ nativeOptions.codec = TiRtcAudioCodecPcm;
82
+ } else if ([codec isEqualToString:@"opus"]) {
83
+ nativeOptions.codec = TiRtcAudioCodecOpus;
84
+ } else if ([codec isEqualToString:@"amr"]) {
85
+ nativeOptions.codec = TiRtcAudioCodecAmr;
86
+ } else {
87
+ nativeOptions.codec = TiRtcAudioCodecG711a;
88
+ }
89
+ nativeOptions.sampleRate = [options.sampleRate() isEqualToString:@"rate8k"]
90
+ ? TiRtcAudioSampleRateRate8k
91
+ : TiRtcAudioSampleRateRate16k;
92
+ nativeOptions.channels = TiRtcAudioChannelCountMono;
93
+ nativeOptions.aecMode = TiRtcReactNativeAudioAecMode(options.aecMode());
94
+ nativeOptions.agcLevel = TiRtcReactNativeAudioAgcLevel(options.agcLevel());
95
+ nativeOptions.ansLevel = TiRtcReactNativeAudioAnsLevel(options.ansLevel());
96
+ return nativeOptions;
97
+ }
98
+
99
+ TiRtcVideoInputOptions* TiRtcReactNativeVideoInputOptions(
100
+ JS::NativeTiRtc::NativeVideoInputOptions& options) {
101
+ TiRtcVideoInputOptions* nativeOptions = [TiRtcVideoInputOptions new];
102
+ NSString* codec = options.codec();
103
+ if ([codec isEqualToString:@"mjpeg"]) {
104
+ nativeOptions.codec = TiRtcVideoEncoderCodecMjpeg;
105
+ } else {
106
+ nativeOptions.codec = TiRtcVideoEncoderCodecH264;
107
+ }
108
+ nativeOptions.width = (uint32_t)MAX(0, options.width());
109
+ nativeOptions.height = (uint32_t)MAX(0, options.height());
110
+ NSString* frameRate = options.frameRate();
111
+ if ([frameRate isEqualToString:@"fps10"]) {
112
+ nativeOptions.frameRate = TiRtcVideoFrameRateFps10;
113
+ } else if ([frameRate isEqualToString:@"fps30"]) {
114
+ nativeOptions.frameRate = TiRtcVideoFrameRateFps30;
115
+ } else {
116
+ nativeOptions.frameRate = TiRtcVideoFrameRateFps15;
117
+ }
118
+ nativeOptions.bitrateKbps = (uint32_t)MAX(0, options.bitrateKbps());
119
+ nativeOptions.cameraFacing = [options.cameraFacing() isEqualToString:@"back"]
120
+ ? TiRtcCameraFacingBack
121
+ : TiRtcCameraFacingFront;
122
+ return nativeOptions;
123
+ }
@@ -0,0 +1,20 @@
1
+ #import <Foundation/Foundation.h>
2
+
3
+ @class TiRtcReactNativeEventSink;
4
+
5
+ @interface TiRtcReactNativeRegistry : NSObject
6
+
7
+ + (instancetype)sharedRegistry;
8
+
9
+ - (NSInteger)addObject:(id)object;
10
+ - (NSInteger)addObject:(id)object generation:(NSInteger*)generation;
11
+ - (void)setEventSink:(TiRtcReactNativeEventSink*)eventSink;
12
+ - (void)setDelegate:(id)delegate forObjectId:(NSInteger)objectId;
13
+ - (id)objectForId:(NSInteger)objectId;
14
+ - (NSInteger)generationForObjectId:(NSInteger)objectId;
15
+ - (void)reportVideoOutputError:(NSInteger)objectId code:(int32_t)code message:(NSString*)message;
16
+ - (void)reportVideoInputError:(NSInteger)objectId code:(int32_t)code message:(NSString*)message;
17
+ - (void)releaseObject:(NSInteger)objectId;
18
+ - (BOOL)hasLiveObjects;
19
+
20
+ @end
@@ -0,0 +1,119 @@
1
+ #import "TiRtcReactNativeRegistry.h"
2
+
3
+ #import "TiRtcReactNativeEventSink.h"
4
+
5
+ @interface TiRtcReactNativeRegistryEntry : NSObject
6
+ @property(nonatomic, strong) id object;
7
+ @property(nonatomic, strong) id delegate;
8
+ @property(nonatomic, assign) NSInteger generation;
9
+ @end
10
+
11
+ @implementation TiRtcReactNativeRegistryEntry
12
+ @end
13
+
14
+ @implementation TiRtcReactNativeRegistry {
15
+ NSLock* _lock;
16
+ NSMutableDictionary<NSNumber*, TiRtcReactNativeRegistryEntry*>* _entries;
17
+ __weak TiRtcReactNativeEventSink* _eventSink;
18
+ NSInteger _nextId;
19
+ NSInteger _nextGeneration;
20
+ }
21
+
22
+ + (instancetype)sharedRegistry {
23
+ static TiRtcReactNativeRegistry* registry;
24
+ static dispatch_once_t onceToken;
25
+ dispatch_once(&onceToken, ^{
26
+ registry = [TiRtcReactNativeRegistry new];
27
+ });
28
+ return registry;
29
+ }
30
+
31
+ - (instancetype)init {
32
+ if (self = [super init]) {
33
+ _lock = [NSLock new];
34
+ _entries = [NSMutableDictionary new];
35
+ _nextId = 1;
36
+ _nextGeneration = 1;
37
+ }
38
+ return self;
39
+ }
40
+
41
+ - (NSInteger)addObject:(id)object {
42
+ return [self addObject:object generation:nil];
43
+ }
44
+
45
+ - (NSInteger)addObject:(id)object generation:(NSInteger*)generation {
46
+ [_lock lock];
47
+ NSInteger objectId = _nextId++;
48
+ NSInteger objectGeneration = _nextGeneration++;
49
+ TiRtcReactNativeRegistryEntry* entry = [TiRtcReactNativeRegistryEntry new];
50
+ entry.object = object;
51
+ entry.generation = objectGeneration;
52
+ _entries[@(objectId)] = entry;
53
+ if (generation != nil) {
54
+ *generation = objectGeneration;
55
+ }
56
+ [_lock unlock];
57
+ return objectId;
58
+ }
59
+
60
+ - (void)setEventSink:(TiRtcReactNativeEventSink*)eventSink {
61
+ [_lock lock];
62
+ _eventSink = eventSink;
63
+ [_lock unlock];
64
+ }
65
+
66
+ - (void)setDelegate:(id)delegate forObjectId:(NSInteger)objectId {
67
+ [_lock lock];
68
+ _entries[@(objectId)].delegate = delegate;
69
+ [_lock unlock];
70
+ }
71
+
72
+ - (id)objectForId:(NSInteger)objectId {
73
+ [_lock lock];
74
+ id object = _entries[@(objectId)].object;
75
+ [_lock unlock];
76
+ return object;
77
+ }
78
+
79
+ - (NSInteger)generationForObjectId:(NSInteger)objectId {
80
+ [_lock lock];
81
+ NSInteger generation = _entries[@(objectId)].generation;
82
+ [_lock unlock];
83
+ return generation;
84
+ }
85
+
86
+ - (void)reportVideoOutputError:(NSInteger)objectId code:(int32_t)code message:(NSString*)message {
87
+ [_lock lock];
88
+ TiRtcReactNativeEventSink* eventSink = _eventSink;
89
+ BOOL hasObject = _entries[@(objectId)] != nil;
90
+ [_lock unlock];
91
+ if (eventSink != nil && hasObject) {
92
+ [eventSink videoOutputError:objectId code:code message:message];
93
+ }
94
+ }
95
+
96
+ - (void)reportVideoInputError:(NSInteger)objectId code:(int32_t)code message:(NSString*)message {
97
+ [_lock lock];
98
+ TiRtcReactNativeEventSink* eventSink = _eventSink;
99
+ BOOL hasObject = _entries[@(objectId)] != nil;
100
+ [_lock unlock];
101
+ if (eventSink != nil && hasObject) {
102
+ [eventSink videoInputError:objectId code:code message:message];
103
+ }
104
+ }
105
+
106
+ - (void)releaseObject:(NSInteger)objectId {
107
+ [_lock lock];
108
+ [_entries removeObjectForKey:@(objectId)];
109
+ [_lock unlock];
110
+ }
111
+
112
+ - (BOOL)hasLiveObjects {
113
+ [_lock lock];
114
+ BOOL hasObjects = _entries.count > 0;
115
+ [_lock unlock];
116
+ return hasObjects;
117
+ }
118
+
119
+ @end
@@ -0,0 +1,5 @@
1
+ #import <React/RCTViewComponentView.h>
2
+ #import <react/renderer/components/TiRtcSpec/RCTComponentViewHelpers.h>
3
+
4
+ @interface TiRtcVideoInputPreview : RCTViewComponentView <RCTTiRtcVideoInputPreviewViewProtocol>
5
+ @end
@@ -0,0 +1,149 @@
1
+ #import "TiRtcVideoInputPreview.h"
2
+
3
+ #import <AVFoundation/AVFoundation.h>
4
+ #import <QuartzCore/QuartzCore.h>
5
+ #import <react/renderer/components/TiRtcSpec/ComponentDescriptors.h>
6
+ #import <react/renderer/components/TiRtcSpec/Props.h>
7
+ #import <react/renderer/components/TiRtcSpec/ShadowNodes.h>
8
+
9
+ #import "TiRtcReactNativeNative.h"
10
+ #import "TiRtcReactNativeRegistry.h"
11
+
12
+ using namespace facebook::react;
13
+
14
+ static AVLayerVideoGravity TiRtcVideoInputPreviewGravityForResizeMode(
15
+ TiRtcVideoInputPreviewResizeMode resizeMode) {
16
+ switch (resizeMode) {
17
+ case TiRtcVideoInputPreviewResizeMode::Cover:
18
+ return AVLayerVideoGravityResizeAspectFill;
19
+ case TiRtcVideoInputPreviewResizeMode::Stretch:
20
+ return AVLayerVideoGravityResize;
21
+ case TiRtcVideoInputPreviewResizeMode::Contain:
22
+ default:
23
+ return AVLayerVideoGravityResizeAspect;
24
+ }
25
+ }
26
+
27
+ @interface TiRtcVideoInputPreview ()
28
+ - (void)applyVideoLayerGeometry;
29
+ - (void)updateAttachedPreview;
30
+ @end
31
+
32
+ @implementation TiRtcVideoInputPreview {
33
+ NSInteger _nativeObjectId;
34
+ NSInteger _generation;
35
+ NSInteger _attachedObjectId;
36
+ NSInteger _attachedGeneration;
37
+ TiRtcVideoInputPreviewResizeMode _resizeMode;
38
+ }
39
+
40
+ - (instancetype)initWithFrame:(CGRect)frame {
41
+ if (self = [super initWithFrame:frame]) {
42
+ _props = TiRtcVideoInputPreviewShadowNode::defaultSharedProps();
43
+ _nativeObjectId = 0;
44
+ _generation = 0;
45
+ _attachedObjectId = 0;
46
+ _attachedGeneration = 0;
47
+ _resizeMode = TiRtcVideoInputPreviewResizeMode::Contain;
48
+ self.clipsToBounds = YES;
49
+ self.backgroundColor = UIColor.blackColor;
50
+ }
51
+ return self;
52
+ }
53
+
54
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
55
+ return concreteComponentDescriptorProvider<TiRtcVideoInputPreviewComponentDescriptor>();
56
+ }
57
+
58
+ - (void)updateProps:(const Props::Shared&)props oldProps:(const Props::Shared&)oldProps {
59
+ const auto& oldPropsValue = static_cast<const TiRtcVideoInputPreviewProps&>(*_props);
60
+ const auto& newPropsValue = static_cast<const TiRtcVideoInputPreviewProps&>(*props);
61
+ if (oldPropsValue.resizeMode != newPropsValue.resizeMode) {
62
+ _resizeMode = newPropsValue.resizeMode;
63
+ [self applyVideoLayerGeometry];
64
+ }
65
+ if (oldPropsValue.nativeObjectId != newPropsValue.nativeObjectId ||
66
+ oldPropsValue.generation != newPropsValue.generation) {
67
+ _nativeObjectId = newPropsValue.nativeObjectId;
68
+ _generation = newPropsValue.generation;
69
+ [self updateAttachedPreview];
70
+ }
71
+ [self applyVideoLayerGeometry];
72
+ [super updateProps:props oldProps:oldProps];
73
+ }
74
+
75
+ - (void)layoutSubviews {
76
+ [super layoutSubviews];
77
+ [self applyVideoLayerGeometry];
78
+ }
79
+
80
+ - (void)prepareForRecycle {
81
+ [self detachNativePreview:_attachedObjectId];
82
+ _nativeObjectId = 0;
83
+ _generation = 0;
84
+ _attachedObjectId = 0;
85
+ _attachedGeneration = 0;
86
+ [super prepareForRecycle];
87
+ }
88
+
89
+ - (void)dealloc {
90
+ [self detachNativePreview:_attachedObjectId];
91
+ }
92
+
93
+ - (void)updateAttachedPreview {
94
+ if (_attachedObjectId > 0 &&
95
+ (_attachedObjectId != _nativeObjectId || _attachedGeneration != _generation)) {
96
+ [self detachNativePreview:_attachedObjectId];
97
+ _attachedObjectId = 0;
98
+ _attachedGeneration = 0;
99
+ }
100
+ if (_nativeObjectId <= 0 || _generation <= 0 ||
101
+ (_attachedObjectId == _nativeObjectId && _attachedGeneration == _generation)) {
102
+ return;
103
+ }
104
+ TiRtcReactNativeRegistry* registry = [TiRtcReactNativeRegistry sharedRegistry];
105
+ if ([registry generationForObjectId:_nativeObjectId] != _generation) {
106
+ return;
107
+ }
108
+ id object = [registry objectForId:_nativeObjectId];
109
+ if ([object isKindOfClass:[TiRtcVideoInput class]]) {
110
+ int32_t code = [(TiRtcVideoInput*)object attachPreviewTo:self];
111
+ if (code != 0) {
112
+ [registry reportVideoInputError:_nativeObjectId code:code message:@"preview attach failed"];
113
+ return;
114
+ }
115
+ _attachedObjectId = _nativeObjectId;
116
+ _attachedGeneration = _generation;
117
+ [self applyVideoLayerGeometry];
118
+ }
119
+ }
120
+
121
+ - (void)detachNativePreview:(NSInteger)objectId {
122
+ if (objectId <= 0) {
123
+ return;
124
+ }
125
+ id object = [[TiRtcReactNativeRegistry sharedRegistry] objectForId:objectId];
126
+ if ([object isKindOfClass:[TiRtcVideoInput class]]) {
127
+ __unused int32_t code = [(TiRtcVideoInput*)object detachPreview];
128
+ }
129
+ }
130
+
131
+ - (void)applyVideoLayerGeometry {
132
+ AVLayerVideoGravity videoGravity = TiRtcVideoInputPreviewGravityForResizeMode(_resizeMode);
133
+ [CATransaction begin];
134
+ [CATransaction setDisableActions:YES];
135
+ for (CALayer* layer in self.layer.sublayers) {
136
+ if ([layer isKindOfClass:[AVSampleBufferDisplayLayer class]]) {
137
+ AVSampleBufferDisplayLayer* displayLayer = (AVSampleBufferDisplayLayer*)layer;
138
+ displayLayer.frame = self.bounds;
139
+ displayLayer.videoGravity = videoGravity;
140
+ }
141
+ }
142
+ [CATransaction commit];
143
+ }
144
+
145
+ @end
146
+
147
+ Class<RCTComponentViewProtocol> TiRtcVideoInputPreviewCls(void) {
148
+ return TiRtcVideoInputPreview.class;
149
+ }
@@ -0,0 +1,5 @@
1
+ #import <React/RCTViewComponentView.h>
2
+ #import <react/renderer/components/TiRtcSpec/RCTComponentViewHelpers.h>
3
+
4
+ @interface TiRtcVideoOutputView : RCTViewComponentView <RCTTiRtcVideoOutputViewViewProtocol>
5
+ @end
@@ -0,0 +1,149 @@
1
+ #import "TiRtcVideoOutputView.h"
2
+
3
+ #import <AVFoundation/AVFoundation.h>
4
+ #import <QuartzCore/QuartzCore.h>
5
+ #import <react/renderer/components/TiRtcSpec/ComponentDescriptors.h>
6
+ #import <react/renderer/components/TiRtcSpec/Props.h>
7
+ #import <react/renderer/components/TiRtcSpec/ShadowNodes.h>
8
+
9
+ #import "TiRtcReactNativeNative.h"
10
+ #import "TiRtcReactNativeRegistry.h"
11
+
12
+ using namespace facebook::react;
13
+
14
+ static AVLayerVideoGravity TiRtcVideoOutputGravityForResizeMode(
15
+ TiRtcVideoOutputViewResizeMode resizeMode) {
16
+ switch (resizeMode) {
17
+ case TiRtcVideoOutputViewResizeMode::Cover:
18
+ return AVLayerVideoGravityResizeAspectFill;
19
+ case TiRtcVideoOutputViewResizeMode::Stretch:
20
+ return AVLayerVideoGravityResize;
21
+ case TiRtcVideoOutputViewResizeMode::Contain:
22
+ default:
23
+ return AVLayerVideoGravityResizeAspect;
24
+ }
25
+ }
26
+
27
+ @interface TiRtcVideoOutputView ()
28
+ - (void)applyVideoLayerGeometry;
29
+ - (void)updateAttachedOutput;
30
+ @end
31
+
32
+ @implementation TiRtcVideoOutputView {
33
+ NSInteger _nativeObjectId;
34
+ NSInteger _generation;
35
+ NSInteger _attachedObjectId;
36
+ NSInteger _attachedGeneration;
37
+ TiRtcVideoOutputViewResizeMode _resizeMode;
38
+ }
39
+
40
+ - (instancetype)initWithFrame:(CGRect)frame {
41
+ if (self = [super initWithFrame:frame]) {
42
+ _props = TiRtcVideoOutputViewShadowNode::defaultSharedProps();
43
+ _nativeObjectId = 0;
44
+ _generation = 0;
45
+ _attachedObjectId = 0;
46
+ _attachedGeneration = 0;
47
+ _resizeMode = TiRtcVideoOutputViewResizeMode::Contain;
48
+ self.clipsToBounds = YES;
49
+ self.backgroundColor = UIColor.blackColor;
50
+ }
51
+ return self;
52
+ }
53
+
54
+ + (ComponentDescriptorProvider)componentDescriptorProvider {
55
+ return concreteComponentDescriptorProvider<TiRtcVideoOutputViewComponentDescriptor>();
56
+ }
57
+
58
+ - (void)updateProps:(const Props::Shared&)props oldProps:(const Props::Shared&)oldProps {
59
+ const auto& oldPropsValue = static_cast<const TiRtcVideoOutputViewProps&>(*_props);
60
+ const auto& newPropsValue = static_cast<const TiRtcVideoOutputViewProps&>(*props);
61
+ if (oldPropsValue.resizeMode != newPropsValue.resizeMode) {
62
+ _resizeMode = newPropsValue.resizeMode;
63
+ [self applyVideoLayerGeometry];
64
+ }
65
+ if (oldPropsValue.nativeObjectId != newPropsValue.nativeObjectId ||
66
+ oldPropsValue.generation != newPropsValue.generation) {
67
+ _nativeObjectId = newPropsValue.nativeObjectId;
68
+ _generation = newPropsValue.generation;
69
+ [self updateAttachedOutput];
70
+ }
71
+ [self applyVideoLayerGeometry];
72
+ [super updateProps:props oldProps:oldProps];
73
+ }
74
+
75
+ - (void)layoutSubviews {
76
+ [super layoutSubviews];
77
+ [self applyVideoLayerGeometry];
78
+ }
79
+
80
+ - (void)prepareForRecycle {
81
+ [self detachNativeOutput:_attachedObjectId];
82
+ _nativeObjectId = 0;
83
+ _generation = 0;
84
+ _attachedObjectId = 0;
85
+ _attachedGeneration = 0;
86
+ [super prepareForRecycle];
87
+ }
88
+
89
+ - (void)dealloc {
90
+ [self detachNativeOutput:_attachedObjectId];
91
+ }
92
+
93
+ - (void)updateAttachedOutput {
94
+ if (_attachedObjectId > 0 &&
95
+ (_attachedObjectId != _nativeObjectId || _attachedGeneration != _generation)) {
96
+ [self detachNativeOutput:_attachedObjectId];
97
+ _attachedObjectId = 0;
98
+ _attachedGeneration = 0;
99
+ }
100
+ if (_nativeObjectId <= 0 || _generation <= 0 ||
101
+ (_attachedObjectId == _nativeObjectId && _attachedGeneration == _generation)) {
102
+ return;
103
+ }
104
+ TiRtcReactNativeRegistry* registry = [TiRtcReactNativeRegistry sharedRegistry];
105
+ if ([registry generationForObjectId:_nativeObjectId] != _generation) {
106
+ return;
107
+ }
108
+ id object = [registry objectForId:_nativeObjectId];
109
+ if ([object isKindOfClass:[TiRtcVideoOutput class]]) {
110
+ int32_t code = [(TiRtcVideoOutput*)object attachView:self];
111
+ if (code != 0) {
112
+ [registry reportVideoOutputError:_nativeObjectId code:code message:@"view attach failed"];
113
+ return;
114
+ }
115
+ _attachedObjectId = _nativeObjectId;
116
+ _attachedGeneration = _generation;
117
+ [self applyVideoLayerGeometry];
118
+ }
119
+ }
120
+
121
+ - (void)detachNativeOutput:(NSInteger)objectId {
122
+ if (objectId <= 0) {
123
+ return;
124
+ }
125
+ id object = [[TiRtcReactNativeRegistry sharedRegistry] objectForId:objectId];
126
+ if ([object isKindOfClass:[TiRtcVideoOutput class]]) {
127
+ __unused int32_t code = [(TiRtcVideoOutput*)object detachView];
128
+ }
129
+ }
130
+
131
+ - (void)applyVideoLayerGeometry {
132
+ AVLayerVideoGravity videoGravity = TiRtcVideoOutputGravityForResizeMode(_resizeMode);
133
+ [CATransaction begin];
134
+ [CATransaction setDisableActions:YES];
135
+ for (CALayer* layer in self.layer.sublayers) {
136
+ if ([layer isKindOfClass:[AVSampleBufferDisplayLayer class]]) {
137
+ AVSampleBufferDisplayLayer* displayLayer = (AVSampleBufferDisplayLayer*)layer;
138
+ displayLayer.frame = self.bounds;
139
+ displayLayer.videoGravity = videoGravity;
140
+ }
141
+ }
142
+ [CATransaction commit];
143
+ }
144
+
145
+ @end
146
+
147
+ Class<RCTComponentViewProtocol> TiRtcVideoOutputViewCls(void) {
148
+ return TiRtcVideoOutputView.class;
149
+ }