@byteplus/react-native-live-push 1.2.0-rc.0 → 1.3.0-rc.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.
@@ -84,7 +84,7 @@ public class MixerManager {
84
84
  Log.w(TAG, "Failed to perform manual capture after addView", e);
85
85
  }
86
86
  }
87
- }, 300);
87
+ }, 1000);
88
88
  } else {
89
89
  pendingCallbacks.put(viewId, videoStreamId);
90
90
  }
@@ -20,24 +20,14 @@ public class MixerView extends FrameLayout {
20
20
  private ThemedReactContext context;
21
21
  private String viewId;
22
22
 
23
- // Mix configuration
24
- private float mixX = 0f;
25
- private float mixY = 0f;
26
- private float mixWidth = 0f;
27
- private float mixHeight = 0f;
28
- private int mixZOrder = 0;
29
- private int mixRenderMode = 0;
30
-
31
23
  // Capture configuration
32
24
  private String captureMode = "onchange";
33
- private float captureFramerate = 30f;
34
- private float autoSensitivity = 5f;
25
+ private float captureFramerate = 5f; // realTime mode default 5 fps
35
26
 
36
27
  // Capture state
37
28
  private Handler captureHandler;
38
29
  private Runnable captureRunnable;
39
30
  private ViewTreeObserver.OnGlobalLayoutListener layoutListener;
40
- private ViewTreeObserver.OnDrawListener drawListener;
41
31
  private AtomicBoolean isCapturing = new AtomicBoolean(false);
42
32
  private AtomicBoolean isDestroyed = new AtomicBoolean(false);
43
33
 
@@ -46,14 +36,6 @@ public class MixerView extends FrameLayout {
46
36
  private long lastCaptureTime = 0;
47
37
  private final Object captureLock = new Object();
48
38
 
49
- // Auto mode state
50
- private int changeCount = 0;
51
- private long windowStartTime = 0;
52
- private boolean isInRealtimeMode = false;
53
- private static final long AUTO_WINDOW_MS = 2000; // 2 second window
54
- private static final int HIGH_CHANGE_THRESHOLD = 10;
55
- private static final int LOW_CHANGE_THRESHOLD = 2;
56
-
57
39
  // Add callback support for MixerManager integration
58
40
  private MixerManager.BitmapCaptureCallback bitmapCaptureCallback;
59
41
 
@@ -67,19 +49,6 @@ public class MixerView extends FrameLayout {
67
49
  private void initializeCapture() {
68
50
  // Initialize layout change listener
69
51
  layoutListener = this::onViewChanged;
70
-
71
- // Initialize draw listener for auto mode
72
- drawListener = this::onViewDraw;
73
- }
74
-
75
- // Setters for mix configuration
76
- public void setMixX(float x) { this.mixX = x; }
77
- public void setMixY(float y) { this.mixY = y; }
78
- public void setMixWidth(float width) { this.mixWidth = width; }
79
- public void setMixHeight(float height) { this.mixHeight = height; }
80
- public void setMixZOrder(int zOrder) { this.mixZOrder = zOrder; }
81
- public void setMixRenderMode(int renderMode) {
82
- this.mixRenderMode = renderMode;
83
52
  }
84
53
 
85
54
  public void setCaptureMode(String mode) {
@@ -98,10 +67,6 @@ public class MixerView extends FrameLayout {
98
67
  }
99
68
  }
100
69
 
101
- public void setAutoSensitivity(float sensitivity) {
102
- this.autoSensitivity = Math.max(1f, Math.min(10f, sensitivity));
103
- }
104
-
105
70
  private void startCapture() {
106
71
  if (isDestroyed.get())
107
72
  return;
@@ -113,9 +78,6 @@ public class MixerView extends FrameLayout {
113
78
  case "realtime":
114
79
  startRealtimeCapture();
115
80
  break;
116
- case "auto":
117
- startAutoCapture();
118
- break;
119
81
  case "manual":
120
82
  // Manual mode doesn't auto-start
121
83
  break;
@@ -128,9 +90,6 @@ public class MixerView extends FrameLayout {
128
90
  if (layoutListener != null) {
129
91
  getViewTreeObserver().removeOnGlobalLayoutListener(layoutListener);
130
92
  }
131
- if (drawListener != null) {
132
- getViewTreeObserver().removeOnDrawListener(drawListener);
133
- }
134
93
  }
135
94
 
136
95
  // Stop realtime capture
@@ -143,9 +102,19 @@ public class MixerView extends FrameLayout {
143
102
  }
144
103
 
145
104
  private void startOnChangeCapture() {
146
- if (getViewTreeObserver().isAlive()) {
147
- getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
148
- }
105
+ // onChange mode triggers every 2 seconds
106
+ long interval = 2000; // 2 seconds
107
+
108
+ captureRunnable = new Runnable() {
109
+ @Override
110
+ public void run() {
111
+ if (!isDestroyed.get() && "onchange".equals(captureMode)) {
112
+ performCapture("onchange");
113
+ captureHandler.postDelayed(this, interval);
114
+ }
115
+ }
116
+ };
117
+ captureHandler.postDelayed(captureRunnable, interval);
149
118
  }
150
119
 
151
120
  private void startRealtimeCapture() {
@@ -170,82 +139,13 @@ public class MixerView extends FrameLayout {
170
139
  }
171
140
  }
172
141
 
173
- private void startAutoCapture() {
174
- // Start with onchange mode
175
- isInRealtimeMode = false;
176
- windowStartTime = System.currentTimeMillis();
177
- changeCount = 0;
178
-
179
- if (getViewTreeObserver().isAlive()) {
180
- getViewTreeObserver().addOnGlobalLayoutListener(layoutListener);
181
- getViewTreeObserver().addOnDrawListener(drawListener);
182
- }
183
- }
184
-
185
142
  private void onViewChanged() {
186
143
  if (isDestroyed.get()) {
187
144
  return;
188
145
  }
189
146
 
190
- switch (captureMode) {
191
- case "onchange":
147
+ if ("onchange".equals(captureMode)) {
192
148
  performCapture("onchange");
193
- break;
194
- case "auto":
195
- handleAutoModeChange();
196
- break;
197
- }
198
- }
199
-
200
- private void onViewDraw() {
201
- if (isDestroyed.get() || !"auto".equals(captureMode))
202
- return;
203
-
204
- // Count draws for auto mode sensitivity
205
- changeCount++;
206
-
207
- long currentTime = System.currentTimeMillis();
208
- if (currentTime - windowStartTime >= AUTO_WINDOW_MS) {
209
- evaluateAutoMode();
210
- // Reset window
211
- windowStartTime = currentTime;
212
- changeCount = 0;
213
- }
214
- }
215
-
216
- private void handleAutoModeChange() {
217
- if (!isInRealtimeMode) {
218
- performCapture("auto_onchange");
219
- }
220
- }
221
-
222
- private void evaluateAutoMode() {
223
- float changesPerSecond = changeCount * 1000f / AUTO_WINDOW_MS;
224
- float threshold = autoSensitivity;
225
-
226
- boolean shouldBeRealtime =
227
- changesPerSecond > (HIGH_CHANGE_THRESHOLD / threshold);
228
- boolean shouldBeOnChange =
229
- changesPerSecond < (LOW_CHANGE_THRESHOLD / threshold);
230
-
231
- if (shouldBeRealtime && !isInRealtimeMode) {
232
- switchToRealtimeMode();
233
- } else if (shouldBeOnChange && isInRealtimeMode) {
234
- switchToOnChangeMode();
235
- }
236
- }
237
-
238
- private void switchToRealtimeMode() {
239
- isInRealtimeMode = true;
240
- startRealtimeCapture();
241
- }
242
-
243
- private void switchToOnChangeMode() {
244
- isInRealtimeMode = false;
245
- // Stop realtime capture but keep layout listener
246
- if (captureRunnable != null) {
247
- captureHandler.removeCallbacks(captureRunnable);
248
- captureRunnable = null;
249
149
  }
250
150
  }
251
151
 
@@ -338,12 +238,6 @@ public class MixerView extends FrameLayout {
338
238
  WritableMap event = Arguments.createMap();
339
239
  event.putString("trigger", trigger);
340
240
  event.putBoolean("success", true);
341
- event.putDouble("x", mixX);
342
- event.putDouble("y", mixY);
343
- event.putDouble("width", mixWidth);
344
- event.putDouble("height", mixHeight);
345
- event.putInt("zOrder", mixZOrder);
346
- event.putInt("renderMode", mixRenderMode);
347
241
  event.putInt("bitmapWidth", bitmap.getWidth());
348
242
  event.putInt("bitmapHeight", bitmap.getHeight());
349
243
  } catch (IllegalStateException e) {
@@ -356,8 +250,8 @@ public class MixerView extends FrameLayout {
356
250
  lastBitmap.recycle();
357
251
  }
358
252
 
359
- // 如果没有设置回调,立即释放当前 bitmap 以避免内存累积
360
- // 如果设置了回调,bitmap 将由回调的接收方负责管理
253
+ // If no callback is set, immediately release current bitmap to avoid memory accumulation
254
+ // If callback is set, bitmap will be managed by the callback receiver
361
255
  if (bitmapCaptureCallback == null) {
362
256
  if (bitmap != null && !bitmap.isRecycled()) {
363
257
  bitmap.recycle();
@@ -392,7 +286,7 @@ public class MixerView extends FrameLayout {
392
286
  super.onAttachedToWindow();
393
287
  if (viewId != null) {
394
288
  MixerManager.cachedMixedViews.put(viewId, this);
395
- // 通知MixerManager视图已准备好,检查是否有待处理的回调
289
+ // Notify MixerManager that view is ready, check for pending callbacks
396
290
  MixerManager.onViewReady(viewId, this);
397
291
  }
398
292
  }
@@ -409,7 +303,7 @@ public class MixerView extends FrameLayout {
409
303
  public void setViewId(String viewId) {
410
304
  this.viewId = viewId;
411
305
  MixerManager.cachedMixedViews.put(viewId, this);
412
- // 通知MixerManager视图已准备好,检查是否有待处理的回调
306
+ // Notify MixerManager that view is ready, check for pending callbacks
413
307
  MixerManager.onViewReady(viewId, this);
414
308
  }
415
309
 
@@ -22,52 +22,16 @@ public class MixerViewManager extends ViewGroupManager<MixerView> {
22
22
  return new MixerView(reactContext);
23
23
  }
24
24
 
25
- // Props for mixing configuration
26
- @ReactProp(name = "x", defaultFloat = 0f)
27
- public void setX(MixerView view, float x) {
28
- view.setMixX(x);
29
- }
30
-
31
- @ReactProp(name = "y", defaultFloat = 0f)
32
- public void setY(MixerView view, float y) {
33
- view.setMixY(y);
34
- }
35
-
36
- @ReactProp(name = "width", defaultFloat = 0f)
37
- public void setWidth(MixerView view, float width) {
38
- view.setMixWidth(width);
39
- }
40
-
41
- @ReactProp(name = "height", defaultFloat = 0f)
42
- public void setHeight(MixerView view, float height) {
43
- view.setMixHeight(height);
44
- }
45
-
46
- @ReactProp(name = "zOrder", defaultInt = 0)
47
- public void setZOrder(MixerView view, int zOrder) {
48
- view.setMixZOrder(zOrder);
49
- }
50
-
51
- @ReactProp(name = "renderMode", defaultInt = 0)
52
- public void setRenderMode(MixerView view, int renderMode) {
53
- view.setMixRenderMode(renderMode);
54
- }
55
-
56
25
  @ReactProp(name = "captureMode")
57
26
  public void setCaptureMode(MixerView view, @Nullable String captureMode) {
58
27
  view.setCaptureMode(captureMode != null ? captureMode : "onchange");
59
28
  }
60
29
 
61
- @ReactProp(name = "captureFramerate", defaultFloat = 30f)
30
+ @ReactProp(name = "captureFramerate", defaultFloat = 5f)
62
31
  public void setCaptureFramerate(MixerView view, float framerate) {
63
32
  view.setCaptureFramerate(framerate);
64
33
  }
65
34
 
66
- @ReactProp(name = "autoSensitivity", defaultFloat = 5f)
67
- public void setAutoSensitivity(MixerView view, float sensitivity) {
68
- view.setAutoSensitivity(sensitivity);
69
- }
70
-
71
35
  @ReactProp(name = "viewId")
72
36
  public void setViewId(MixerView view, @Nullable String viewId) {
73
37
  if (viewId != null) {
@@ -6,17 +6,18 @@
6
6
  //
7
7
 
8
8
  #import "VeLiveMixerView.h"
9
+ #import <CoreVideo/CoreVideo.h>
9
10
  #import <Foundation/Foundation.h>
10
11
 
11
12
  NS_ASSUME_NONNULL_BEGIN
12
13
 
13
- // 前向声明
14
+ // Forward declaration
14
15
  @class VeLivePusher;
15
16
 
16
- // 混流管理器助手类 - 完全对齐Android MixerManager.java
17
+ // Mixer helper class - fully aligned with Android MixerManager.java
17
18
  @interface VeLiveMixerHelper : NSObject <VeLiveBitmapCaptureCallback>
18
19
 
19
- // 对齐Androidstatic cachedMixedViews
20
+ // Aligned with Android's static cachedMixedViews
20
21
  @property(class, nonatomic, strong)
21
22
  NSMutableDictionary<NSString *, VeLiveMixerUIView *> *cachedMixedViews;
22
23
 
@@ -24,21 +25,23 @@ NS_ASSUME_NONNULL_BEGIN
24
25
 
25
26
  - (instancetype)initWithPusher:(VeLivePusher *)pusher;
26
27
 
27
- // Public方法 - 完全对齐Android MixerManagerpublic接口
28
+ // Public methods - fully aligned with Android MixerManager's public interface
28
29
  - (void)setPusher:(VeLivePusher *)pusher;
29
30
  - (int)addView:(NSString *)viewId config:(NSDictionary *)viewInfo;
30
31
  - (BOOL)updateView:(NSString *)viewId config:(NSDictionary *)viewInfo;
31
32
  - (BOOL)removeView:(NSString *)viewId;
32
33
  - (void)captureView:(NSString *)viewId;
33
34
 
34
- // Static方法 - 只保留Android中实际存在的
35
+ // Static methods - for sending captured content to mixer
35
36
  + (void)setupCallbackForMixerView:(VeLiveMixerUIView *)mixerView
36
37
  streamId:(int)streamId;
37
38
  + (void)sendBitmapToMixerStatic:(int)streamId bitmap:(UIImage *)bitmap;
39
+ + (void)sendPixelBufferToMixerStatic:(int)streamId
40
+ pixelBuffer:(CVPixelBufferRef)pixelBuffer;
38
41
  + (VeLiveMixerHelper *)findActiveMixerManager;
39
42
  + (void)onViewReady:(NSString *)viewId mixerView:(VeLiveMixerUIView *)mixerView;
40
43
 
41
- // 清理资源
44
+ // Resource cleanup
42
45
  - (void)cleanup;
43
46
 
44
47
  @end
@@ -43,10 +43,11 @@ static NSString *TAG = @"VeLiveMixerHelper";
43
43
 
44
44
  @implementation VeLiveMixerHelper
45
45
 
46
- // 对齐Androidstatic cachedMixedViews
46
+ // Aligned with Android's static cachedMixedViews
47
47
  static NSMutableDictionary<NSString *, VeLiveMixerUIView *> *_cachedMixedViews =
48
48
  nil;
49
- static VeLiveMixerHelper *currentInstance = nil; // 强引用,防止被ARC释放
49
+ static VeLiveMixerHelper *currentInstance =
50
+ nil; // Strong reference to prevent ARC deallocation
50
51
 
51
52
  + (NSMutableDictionary<NSString *, VeLiveMixerUIView *> *)cachedMixedViews {
52
53
  if (!_cachedMixedViews) {
@@ -176,7 +177,7 @@ static VeLiveMixerHelper *currentInstance = nil; // 强引用,防止被ARC释
176
177
  if ([view isKindOfClass:[VeLiveMixerUIView class]]) {
177
178
  [VeLiveMixerHelper setupCallbackForMixerView:view streamId:videoStreamId];
178
179
 
179
- // 延迟执行捕获,确保视图布局完成
180
+ // Delayed capture execution to ensure view layout completion
180
181
  dispatch_after(
181
182
  dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)),
182
183
  dispatch_get_main_queue(), ^{
@@ -238,7 +239,7 @@ static VeLiveMixerHelper *currentInstance = nil; // 强引用,防止被ARC释
238
239
 
239
240
  [self.mixedViewLayout setObject:updatedLayout forKey:viewId];
240
241
 
241
- // 延迟执行捕获,确保属性更新完成
242
+ // Delayed capture execution to ensure property updates completion
242
243
  VeLiveMixerUIView *mixerView =
243
244
  [[VeLiveMixerHelper cachedMixedViews] objectForKey:viewId];
244
245
  if ([mixerView isKindOfClass:[VeLiveMixerUIView class]]) {
@@ -344,6 +345,7 @@ static VeLiveMixerHelper *currentInstance = nil; // 强引用,防止被ARC释
344
345
  videoLayout.width = [layout[@"width"] floatValue];
345
346
  videoLayout.height = [layout[@"height"] floatValue];
346
347
  videoLayout.zOrder = [layout[@"zOrder"] intValue];
348
+ videoLayout.alpha = [layout[@"alpha"] floatValue];
347
349
  videoLayout.renderMode = [layout[@"renderMode"] intValue];
348
350
  description.mixVideoStreams = @[ videoLayout ];
349
351
  [instance.pusher.getMixerManager
@@ -369,6 +371,15 @@ static VeLiveMixerHelper *currentInstance = nil; // 强引用,防止被ARC释
369
371
  }
370
372
  }
371
373
 
374
+ // New: Send pixelBuffer directly to mixer, avoiding UIImage conversion overhead
375
+ + (void)sendPixelBufferToMixerStatic:(int)streamId
376
+ pixelBuffer:(CVPixelBufferRef)pixelBuffer {
377
+ VeLiveMixerHelper *instance = [VeLiveMixerHelper findActiveMixerManager];
378
+ if (instance && instance.pusher) {
379
+ [instance sendPixelBufferToMixer:streamId pixelBuffer:pixelBuffer];
380
+ }
381
+ }
382
+
372
383
  + (VeLiveMixerHelper *)findActiveMixerManager {
373
384
  return currentInstance;
374
385
  }
@@ -503,6 +514,7 @@ static VeLiveMixerHelper *currentInstance = nil; // 强引用,防止被ARC释
503
514
 
504
515
  #pragma mark - Private Methods
505
516
 
517
+ // Send UIImage to mixer (via pixelBuffer conversion)
506
518
  - (void)sendBitmapToMixer:(int)streamId bitmap:(UIImage *)bitmap {
507
519
  @autoreleasepool {
508
520
  if (!self.pusher || !bitmap) {
@@ -517,6 +529,27 @@ static VeLiveMixerHelper *currentInstance = nil; // 强引用,防止被ARC释
517
529
  return;
518
530
  }
519
531
 
532
+ // Use new pixelBuffer method
533
+ [self sendPixelBufferToMixer:streamId pixelBuffer:pixelBuffer];
534
+
535
+ } @finally {
536
+ if (pixelBuffer) {
537
+ CVPixelBufferRelease(pixelBuffer);
538
+ pixelBuffer = NULL;
539
+ }
540
+ }
541
+ }
542
+ }
543
+
544
+ // Send pixelBuffer directly to mixer, better performance
545
+ - (void)sendPixelBufferToMixer:(int)streamId
546
+ pixelBuffer:(CVPixelBufferRef)pixelBuffer {
547
+ @autoreleasepool {
548
+ if (!self.pusher || !pixelBuffer) {
549
+ return;
550
+ }
551
+
552
+ @try {
520
553
  VeLiveVideoFrame *videoFrame = [[VeLiveVideoFrame alloc] init];
521
554
  videoFrame.bufferType = VeLiveVideoBufferTypePixelBuffer;
522
555
  videoFrame.pts = CMTimeMakeWithSeconds(CACurrentMediaTime(), 1000000000);
@@ -524,15 +557,8 @@ static VeLiveMixerHelper *currentInstance = nil; // 强引用,防止被ARC释
524
557
 
525
558
  [[self.pusher getMixerManager] sendCustomVideoFrame:videoFrame
526
559
  streamId:streamId];
527
- CVPixelBufferRelease(pixelBuffer);
528
-
529
- pixelBuffer = NULL;
530
-
531
560
  } @catch (NSException *exception) {
532
- if (pixelBuffer) {
533
- CVPixelBufferRelease(pixelBuffer);
534
- pixelBuffer = NULL;
535
- }
561
+ // Handle exception silently
536
562
  }
537
563
  }
538
564
  }
@@ -30,16 +30,9 @@ NS_ASSUME_NONNULL_BEGIN
30
30
  // 视图标识
31
31
  @property (nonatomic, strong) NSString *viewId;
32
32
 
33
- // 混流配置属性
34
- @property (nonatomic, strong) NSNumber *x;
35
- @property (nonatomic, strong) NSNumber *y;
36
- @property (nonatomic, strong) NSNumber *width;
37
- @property (nonatomic, strong) NSNumber *height;
38
- @property (nonatomic, strong) NSNumber *zOrder;
39
- @property (nonatomic, strong) NSNumber *renderMode;
33
+ // 捕获配置属性
40
34
  @property (nonatomic, strong) NSString *captureMode;
41
35
  @property (nonatomic, strong) NSNumber *captureFramerate;
42
- @property (nonatomic, strong) NSNumber *autoSensitivity;
43
36
 
44
37
  // React Native 事件回调
45
38
  @property (nonatomic, copy) RCTBubblingEventBlock onBitmapCapture;
@@ -8,24 +8,16 @@
8
8
  #import "VeLiveMixerView.h"
9
9
  #import "VeLiveMixerHelper.h"
10
10
  #import <AVFoundation/AVFoundation.h>
11
+ #import <CoreImage/CoreImage.h>
11
12
  #import <CoreMedia/CoreMedia.h>
12
13
  #import <CoreVideo/CoreVideo.h>
13
14
  #import <UIKit/UIKit.h>
14
15
 
15
16
  @interface VeLiveMixerUIView ()
16
17
 
17
- // Mix configuration - Align with Android
18
- @property(nonatomic, assign) float mixX;
19
- @property(nonatomic, assign) float mixY;
20
- @property(nonatomic, assign) float mixWidth;
21
- @property(nonatomic, assign) float mixHeight;
22
- @property(nonatomic, assign) int mixZOrder;
23
- @property(nonatomic, assign) int mixRenderMode;
24
-
25
18
  // Capture configuration - Internal properties
26
19
  @property(nonatomic, strong) NSString *internalCaptureMode;
27
20
  @property(nonatomic, assign) float internalCaptureFramerate;
28
- @property(nonatomic, assign) float internalAutoSensitivity;
29
21
 
30
22
  // Capture state - Align with Android
31
23
  @property(nonatomic, strong) NSTimer *captureTimer;
@@ -34,21 +26,12 @@
34
26
  @property(nonatomic, assign) CFTimeInterval lastCaptureTime;
35
27
 
36
28
  // Performance optimization - Align with Android
37
- @property(nonatomic, strong) UIImage *lastBitmap;
38
-
39
- // Auto mode state - Align with Android
40
- @property(nonatomic, assign) int changeCount;
41
- @property(nonatomic, assign) CFTimeInterval windowStartTime;
42
- @property(nonatomic, assign) BOOL isInRealtimeMode;
29
+ @property(nonatomic) CVPixelBufferRef lastPixelBuffer;
43
30
 
44
31
  @end
45
32
 
46
33
  @implementation VeLiveMixerUIView
47
34
 
48
- static const CFTimeInterval AUTO_WINDOW_SECONDS = 2.0; // 2 second window
49
- static const int HIGH_CHANGE_THRESHOLD = 10;
50
- static const int LOW_CHANGE_THRESHOLD = 2;
51
-
52
35
  - (instancetype)initWithFrame:(CGRect)frame {
53
36
  self = [super initWithFrame:frame];
54
37
  if (self) {
@@ -69,25 +52,13 @@ static const int LOW_CHANGE_THRESHOLD = 2;
69
52
 
70
53
  - (void)initializeCapture {
71
54
  // Initialize defaults - Completely align with Android
72
- _mixX = 0.0f;
73
- _mixY = 0.0f;
74
- _mixWidth = 0.0f;
75
- _mixHeight = 0.0f;
76
- _mixZOrder = 0;
77
- _mixRenderMode = 0;
78
-
79
55
  _internalCaptureMode = @"onchange";
80
- _internalCaptureFramerate = 30.0f;
81
- _internalAutoSensitivity = 5.0f;
56
+ _internalCaptureFramerate = 5.0f; // realTime mode default 5 fps
82
57
 
83
58
  _isCapturing = NO;
84
59
  _isDestroyed = NO;
85
60
  _lastCaptureTime = 0;
86
-
87
- // Auto mode state
88
- _changeCount = 0;
89
- _windowStartTime = 0;
90
- _isInRealtimeMode = NO;
61
+ _lastPixelBuffer = NULL;
91
62
  }
92
63
 
93
64
  #pragma mark - Property Getters/Setters - Align with React Native props
@@ -116,14 +87,6 @@ static const int LOW_CHANGE_THRESHOLD = 2;
116
87
  }
117
88
  }
118
89
 
119
- - (NSNumber *)autoSensitivity {
120
- return @(self.internalAutoSensitivity);
121
- }
122
-
123
- - (void)setAutoSensitivity:(NSNumber *)sensitivity {
124
- _internalAutoSensitivity = MAX(1.0f, MIN(10.0f, [sensitivity floatValue]));
125
- }
126
-
127
90
  - (void)setViewId:(NSString *)viewId {
128
91
  if (!viewId) {
129
92
  return;
@@ -142,61 +105,6 @@ static const int LOW_CHANGE_THRESHOLD = 2;
142
105
  }
143
106
  }
144
107
 
145
- #pragma mark - Property setters for React Native props - Align with Android
146
-
147
- // React Native property setter - Corresponds to VeLiveMixerViewManager.m
148
- // properties
149
- - (void)setX:(NSNumber *)x {
150
- _x = x;
151
- _mixX = [x floatValue];
152
- }
153
-
154
- - (void)setY:(NSNumber *)y {
155
- _y = y;
156
- _mixY = [y floatValue];
157
- }
158
-
159
- - (void)setWidth:(NSNumber *)width {
160
- _width = width;
161
- _mixWidth = [width floatValue];
162
- }
163
-
164
- - (void)setHeight:(NSNumber *)height {
165
- _height = height;
166
- _mixHeight = [height floatValue];
167
- }
168
-
169
- - (void)setZOrder:(NSNumber *)zOrder {
170
- _zOrder = zOrder;
171
- _mixZOrder = [zOrder intValue];
172
- }
173
-
174
- - (void)setRenderMode:(NSNumber *)renderMode {
175
- _renderMode = renderMode;
176
- _mixRenderMode = [renderMode intValue];
177
- }
178
-
179
- #pragma mark - Internal setters for mix configuration - Internal use
180
-
181
- - (void)setMixX:(float)x {
182
- _mixX = x;
183
- }
184
- - (void)setMixY:(float)y {
185
- _mixY = y;
186
- }
187
- - (void)setMixWidth:(float)width {
188
- _mixWidth = width;
189
- }
190
- - (void)setMixHeight:(float)height {
191
- _mixHeight = height;
192
- }
193
- - (void)setMixZOrder:(int)zOrder {
194
- _mixZOrder = zOrder;
195
- }
196
- - (void)setMixRenderMode:(int)renderMode {
197
- _mixRenderMode = renderMode;
198
- }
199
-
200
108
  #pragma mark - Capture Methods - Completely align with Android
201
109
 
202
110
  - (void)startCapture {
@@ -207,8 +115,6 @@ static const int LOW_CHANGE_THRESHOLD = 2;
207
115
  [self startOnChangeCapture];
208
116
  } else if ([self.internalCaptureMode isEqualToString:@"realtime"]) {
209
117
  [self startRealtimeCapture];
210
- } else if ([self.internalCaptureMode isEqualToString:@"auto"]) {
211
- [self startAutoCapture];
212
118
  }
213
119
  // manual mode doesn't auto-start
214
120
  }
@@ -220,7 +126,22 @@ static const int LOW_CHANGE_THRESHOLD = 2;
220
126
  }
221
127
 
222
128
  - (void)startOnChangeCapture {
223
- // onchange mode triggers in layoutSubviews
129
+ // onchange mode triggers every 2 seconds
130
+ self.captureTimer =
131
+ [NSTimer scheduledTimerWithTimeInterval:2.0
132
+ target:self
133
+ selector:@selector(onChangeCapture)
134
+ userInfo:nil
135
+ repeats:YES];
136
+ }
137
+
138
+ - (void)onChangeCapture {
139
+ if (!self.isDestroyed &&
140
+ [self.internalCaptureMode isEqualToString:@"onchange"]) {
141
+ @autoreleasepool {
142
+ [self performCapture:@"onchange"];
143
+ }
144
+ }
224
145
  }
225
146
 
226
147
  - (void)startRealtimeCapture {
@@ -262,59 +183,6 @@ static const int LOW_CHANGE_THRESHOLD = 2;
262
183
  }
263
184
  }
264
185
 
265
- - (void)startAutoCapture {
266
- // Start with onchange mode
267
- self.isInRealtimeMode = NO;
268
- self.windowStartTime = CACurrentMediaTime();
269
- self.changeCount = 0;
270
- [self startOnChangeCapture];
271
- }
272
-
273
- #pragma mark - Layout Change Detection - Align with Android's onViewChanged
274
-
275
- - (void)handleAutoModeChange {
276
- if (!self.isInRealtimeMode) {
277
- [self performCapture:@"auto_onchange"];
278
- }
279
-
280
- // Count changes for auto mode
281
- self.changeCount++;
282
-
283
- CFTimeInterval currentTime = CACurrentMediaTime();
284
- if (currentTime - self.windowStartTime >= AUTO_WINDOW_SECONDS) {
285
- [self evaluateAutoMode];
286
- // Reset window
287
- self.windowStartTime = currentTime;
288
- self.changeCount = 0;
289
- }
290
- }
291
-
292
- - (void)evaluateAutoMode {
293
- float changesPerSecond = self.changeCount / AUTO_WINDOW_SECONDS;
294
- float threshold = self.internalAutoSensitivity;
295
-
296
- BOOL shouldBeRealtime =
297
- changesPerSecond > (HIGH_CHANGE_THRESHOLD / threshold);
298
- BOOL shouldBeOnChange = changesPerSecond < (LOW_CHANGE_THRESHOLD / threshold);
299
-
300
- if (shouldBeRealtime && !self.isInRealtimeMode) {
301
- [self switchToRealtimeMode];
302
- } else if (shouldBeOnChange && self.isInRealtimeMode) {
303
- [self switchToOnChangeMode];
304
- }
305
- }
306
-
307
- - (void)switchToRealtimeMode {
308
- self.isInRealtimeMode = YES;
309
- [self startRealtimeCapture];
310
- }
311
-
312
- - (void)switchToOnChangeMode {
313
- self.isInRealtimeMode = NO;
314
- [self.captureTimer invalidate];
315
- self.captureTimer = nil;
316
- }
317
-
318
186
  #pragma mark - Core Capture Logic - Align with Android's performCapture
319
187
 
320
188
  - (void)performCapture:(NSString *)trigger {
@@ -323,7 +191,7 @@ static const int LOW_CHANGE_THRESHOLD = 2;
323
191
 
324
192
  // Throttle captures to prevent excessive calls
325
193
  CFTimeInterval currentTime = CACurrentMediaTime();
326
- if (currentTime - self.lastCaptureTime < 1.0 / 60.0) { // Max 60fps
194
+ if (currentTime - self.lastCaptureTime < 1.0 / 30.0) { // Max 30fps
327
195
  return;
328
196
  }
329
197
  self.lastCaptureTime = currentTime;
@@ -331,9 +199,10 @@ static const int LOW_CHANGE_THRESHOLD = 2;
331
199
  self.isCapturing = YES;
332
200
 
333
201
  @try {
334
- UIImage *bitmap = [self createBitmap];
335
- if (bitmap) {
336
- [self processBitmap:bitmap trigger:trigger];
202
+ CVPixelBufferRef pixelBuffer = [self createPixelBuffer];
203
+ if (pixelBuffer) {
204
+ [self processPixelBuffer:pixelBuffer trigger:trigger];
205
+ CVPixelBufferRelease(pixelBuffer);
337
206
  }
338
207
  } @finally {
339
208
  self.isCapturing = NO;
@@ -385,75 +254,6 @@ static const int LOW_CHANGE_THRESHOLD = 2;
385
254
  }
386
255
  }
387
256
 
388
- - (void)processBitmap:(UIImage *)bitmap trigger:(NSString *)trigger {
389
- @autoreleasepool {
390
- if (!bitmap || bitmap.size.width <= 0 || bitmap.size.height <= 0) {
391
- return;
392
- }
393
-
394
- // Check bitmap memory size and skip if too large
395
- CGFloat bitmapMemoryMB =
396
- (bitmap.size.width * bitmap.size.height * 4.0) / (1024.0 * 1024.0);
397
- if (bitmapMemoryMB > 50.0) { // Skip bitmaps larger than 50MB
398
- return;
399
- }
400
-
401
- if (self.bitmapCaptureCallback) {
402
- @try {
403
- [self.bitmapCaptureCallback onBitmapCaptured:bitmap];
404
- } @catch (NSException *exception) {
405
- if (self.bitmapCaptureCallback) {
406
- [self.bitmapCaptureCallback
407
- onCaptureError:[NSString stringWithFormat:@"Callback error: %@",
408
- exception.reason]];
409
- }
410
- }
411
- }
412
-
413
- if (self.onBitmapCapture) {
414
- @autoreleasepool {
415
- NSDictionary *event = @{
416
- @"trigger" : trigger ?: @"unknown",
417
- @"success" : @(YES),
418
- @"x" : @(self.mixX),
419
- @"y" : @(self.mixY),
420
- @"width" : @(self.mixWidth),
421
- @"height" : @(self.mixHeight),
422
- @"zOrder" : @(self.mixZOrder),
423
- @"renderMode" : @(self.mixRenderMode),
424
- @"bitmapWidth" : @(bitmap.size.width),
425
- @"bitmapHeight" : @(bitmap.size.height)
426
- };
427
- self.onBitmapCapture(event);
428
- }
429
- }
430
-
431
- // Clean up old bitmap immediately
432
- if (self.lastBitmap) {
433
- self.lastBitmap = nil;
434
- }
435
-
436
- // For realtime mode, don't keep bitmap reference to reduce memory usage
437
- if ([trigger isEqualToString:@"realtime"]) {
438
- // Bitmap will be auto-released at autoreleasepool end
439
-
440
- // Force memory cleanup every 10 realtime captures
441
- static int realtimeCount = 0;
442
- realtimeCount++;
443
- if (realtimeCount % 10 == 0) {
444
- dispatch_async(
445
- dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
446
- @autoreleasepool {
447
- [[NSURLCache sharedURLCache] removeAllCachedResponses];
448
- }
449
- });
450
- }
451
- } else {
452
- self.lastBitmap = bitmap;
453
- }
454
- }
455
- }
456
-
457
257
  #pragma mark - Public Methods - Align with Android interface
458
258
 
459
259
  // Align with Android's performManualCapture
@@ -472,8 +272,11 @@ static const int LOW_CHANGE_THRESHOLD = 2;
472
272
  self.isDestroyed = YES;
473
273
  [self stopCapture];
474
274
 
475
- // Clean up bitmap cache
476
- self.lastBitmap = nil;
275
+ // Clean up pixelBuffer cache
276
+ if (self.lastPixelBuffer) {
277
+ CVPixelBufferRelease(self.lastPixelBuffer);
278
+ self.lastPixelBuffer = NULL;
279
+ }
477
280
 
478
281
  // Clean up callback references, avoid circular references
479
282
  self.bitmapCaptureCallback = nil;
@@ -537,8 +340,12 @@ static const int LOW_CHANGE_THRESHOLD = 2;
537
340
  }
538
341
 
539
342
  - (CVPixelBufferRef)createPixelBuffer {
540
- // Implement pixel buffer creation (corresponds to Android's ByteBuffer)
541
- return NULL; // Temporary return NULL, implementation based on needs
343
+ UIImage *bitmap = [self createBitmap];
344
+ if (!bitmap) {
345
+ return NULL;
346
+ }
347
+
348
+ return [self pixelBufferFromUIImage:bitmap];
542
349
  }
543
350
 
544
351
  - (CMSampleBufferRef)createSampleBuffer {
@@ -587,8 +394,6 @@ static const int LOW_CHANGE_THRESHOLD = 2;
587
394
  // Original capture logic
588
395
  if ([self.internalCaptureMode isEqualToString:@"onchange"]) {
589
396
  [self performCapture:@"onchange"];
590
- } else if ([self.internalCaptureMode isEqualToString:@"auto"]) {
591
- [self handleAutoModeChange];
592
397
  }
593
398
  }
594
399
 
@@ -597,4 +402,146 @@ static const int LOW_CHANGE_THRESHOLD = 2;
597
402
  [super setBackgroundColor:backgroundColor];
598
403
  }
599
404
 
405
+ #pragma mark - Helper Methods
406
+
407
+ - (CVPixelBufferRef)pixelBufferFromUIImage:(UIImage *)image {
408
+ if (!image) {
409
+ return NULL;
410
+ }
411
+
412
+ CGImageRef cgImage = image.CGImage;
413
+ if (!cgImage) {
414
+ return NULL;
415
+ }
416
+
417
+ CGFloat width = CGImageGetWidth(cgImage);
418
+ CGFloat height = CGImageGetHeight(cgImage);
419
+
420
+ NSDictionary *options = @{
421
+ (NSString *)kCVPixelBufferCGImageCompatibilityKey : @YES,
422
+ (NSString *)kCVPixelBufferCGBitmapContextCompatibilityKey : @YES,
423
+ (NSString *)kCVPixelBufferIOSurfacePropertiesKey : @{}
424
+ };
425
+
426
+ CVPixelBufferRef pixelBuffer = NULL;
427
+ CVReturn status = CVPixelBufferCreate(
428
+ kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA,
429
+ (__bridge CFDictionaryRef)options, &pixelBuffer);
430
+
431
+ if (status != kCVReturnSuccess || !pixelBuffer) {
432
+ return NULL;
433
+ }
434
+
435
+ CVPixelBufferLockBaseAddress(pixelBuffer, 0);
436
+
437
+ void *pixelData = CVPixelBufferGetBaseAddress(pixelBuffer);
438
+ size_t bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
439
+
440
+ CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
441
+ CGContextRef context = CGBitmapContextCreate(
442
+ pixelData, width, height, 8, bytesPerRow, colorSpace,
443
+ kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
444
+
445
+ if (!context) {
446
+ CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
447
+ CVPixelBufferRelease(pixelBuffer);
448
+ CGColorSpaceRelease(colorSpace);
449
+ return NULL;
450
+ }
451
+
452
+ CGContextDrawImage(context, CGRectMake(0, 0, width, height), cgImage);
453
+
454
+ CGContextRelease(context);
455
+ CGColorSpaceRelease(colorSpace);
456
+ CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
457
+
458
+ return pixelBuffer;
459
+ }
460
+
461
+ - (void)processPixelBuffer:(CVPixelBufferRef)pixelBuffer
462
+ trigger:(NSString *)trigger {
463
+ @autoreleasepool {
464
+ if (!pixelBuffer) {
465
+ return;
466
+ }
467
+
468
+ // Clean up old pixelBuffer cache
469
+ if (self.lastPixelBuffer) {
470
+ CVPixelBufferRelease(self.lastPixelBuffer);
471
+ self.lastPixelBuffer = NULL;
472
+ }
473
+
474
+ // Cache pixelBuffer for non-realtime modes
475
+ if (![trigger isEqualToString:@"realtime"]) {
476
+ // Retain current pixelBuffer as cache
477
+ CVPixelBufferRetain(pixelBuffer);
478
+ self.lastPixelBuffer = pixelBuffer;
479
+ }
480
+
481
+ // If callback is needed, create temporary UIImage
482
+ if (self.bitmapCaptureCallback || self.onBitmapCapture) {
483
+ UIImage *bitmap = [self UIImageFromPixelBuffer:pixelBuffer];
484
+ if (bitmap) {
485
+ if (self.bitmapCaptureCallback) {
486
+ @try {
487
+ [self.bitmapCaptureCallback onBitmapCaptured:bitmap];
488
+ } @catch (NSException *exception) {
489
+ if (self.bitmapCaptureCallback) {
490
+ [self.bitmapCaptureCallback
491
+ onCaptureError:[NSString
492
+ stringWithFormat:@"Callback error: %@",
493
+ exception.reason]];
494
+ }
495
+ }
496
+ }
497
+
498
+ if (self.onBitmapCapture) {
499
+ @autoreleasepool {
500
+ NSDictionary *event = @{
501
+ @"trigger" : trigger ?: @"unknown",
502
+ @"success" : @(YES),
503
+ @"bitmapWidth" : @(bitmap.size.width),
504
+ @"bitmapHeight" : @(bitmap.size.height)
505
+ };
506
+ self.onBitmapCapture(event);
507
+ }
508
+ }
509
+ }
510
+ }
511
+
512
+ // Memory cleanup for realtime mode
513
+ if ([trigger isEqualToString:@"realtime"]) {
514
+ static int realtimeCount = 0;
515
+ realtimeCount++;
516
+ if (realtimeCount % 10 == 0) {
517
+ dispatch_async(
518
+ dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
519
+ @autoreleasepool {
520
+ [[NSURLCache sharedURLCache] removeAllCachedResponses];
521
+ }
522
+ });
523
+ }
524
+ }
525
+ }
526
+ }
527
+
528
+ - (UIImage *)UIImageFromPixelBuffer:(CVPixelBufferRef)pixelBuffer {
529
+ if (!pixelBuffer) {
530
+ return nil;
531
+ }
532
+
533
+ CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
534
+ CIContext *context = [CIContext contextWithOptions:nil];
535
+ CGImageRef cgImage = [context createCGImage:ciImage fromRect:ciImage.extent];
536
+
537
+ if (!cgImage) {
538
+ return nil;
539
+ }
540
+
541
+ UIImage *image = [UIImage imageWithCGImage:cgImage];
542
+ CGImageRelease(cgImage);
543
+
544
+ return image;
545
+ }
546
+
600
547
  @end
@@ -38,37 +38,6 @@ RCT_CUSTOM_VIEW_PROPERTY(viewId, NSString, VeLiveMixerUIView) {
38
38
  [view setViewId:viewId];
39
39
  }
40
40
 
41
- // 导出混合配置属性 - 与Android保持一致的属性名
42
- RCT_CUSTOM_VIEW_PROPERTY(x, NSNumber, VeLiveMixerUIView) {
43
- NSNumber *x = [RCTConvert NSNumber:json];
44
- [view setX:x];
45
- }
46
-
47
- RCT_CUSTOM_VIEW_PROPERTY(y, NSNumber, VeLiveMixerUIView) {
48
- NSNumber *y = [RCTConvert NSNumber:json];
49
- [view setY:y];
50
- }
51
-
52
- RCT_CUSTOM_VIEW_PROPERTY(width, NSNumber, VeLiveMixerUIView) {
53
- NSNumber *width = [RCTConvert NSNumber:json];
54
- [view setWidth:width];
55
- }
56
-
57
- RCT_CUSTOM_VIEW_PROPERTY(height, NSNumber, VeLiveMixerUIView) {
58
- NSNumber *height = [RCTConvert NSNumber:json];
59
- [view setHeight:height];
60
- }
61
-
62
- RCT_CUSTOM_VIEW_PROPERTY(zOrder, NSNumber, VeLiveMixerUIView) {
63
- NSNumber *zOrder = [RCTConvert NSNumber:json];
64
- [view setZOrder:zOrder];
65
- }
66
-
67
- RCT_CUSTOM_VIEW_PROPERTY(renderMode, NSNumber, VeLiveMixerUIView) {
68
- NSNumber *renderMode = [RCTConvert NSNumber:json];
69
- [view setRenderMode:renderMode];
70
- }
71
-
72
41
  // 导出捕获配置属性
73
42
  RCT_CUSTOM_VIEW_PROPERTY(captureMode, NSString, VeLiveMixerUIView) {
74
43
  NSString *captureMode = [RCTConvert NSString:json];
@@ -84,9 +53,4 @@ RCT_CUSTOM_VIEW_PROPERTY(captureFramerate, NSNumber, VeLiveMixerUIView) {
84
53
  [view setCaptureFramerate:framerate];
85
54
  }
86
55
 
87
- RCT_CUSTOM_VIEW_PROPERTY(autoSensitivity, NSNumber, VeLiveMixerUIView) {
88
- NSNumber *sensitivity = [RCTConvert NSNumber:json];
89
- [view setAutoSensitivity:sensitivity];
90
- }
91
-
92
56
  @end
@@ -26958,8 +26958,7 @@ var getId = function () {
26958
26958
  };
26959
26959
  var MixView = React.forwardRef(function (props, ref) {
26960
26960
  var _a = props.captureMode, captureMode = _a === void 0 ? 'onchange' : _a, // Default to most performant mode
26961
- captureFramerate = props.captureFramerate, _b = props.autoSensitivity, autoSensitivity = _b === void 0 ? 5 : _b, // Default sensitivity
26962
- onViewMount = props.onViewMount, onViewUnmount = props.onViewUnmount, restProps = __rest(props, ["captureMode", "captureFramerate", "autoSensitivity", "onViewMount", "onViewUnmount"]);
26961
+ captureFramerate = props.captureFramerate, onViewMount = props.onViewMount, onViewUnmount = props.onViewUnmount, restProps = __rest(props, ["captureMode", "captureFramerate", "onViewMount", "onViewUnmount"]);
26963
26962
  var viewId = React.useMemo(function () {
26964
26963
  return restProps.viewId || getId();
26965
26964
  }, [restProps.viewId]);
@@ -26974,7 +26973,7 @@ var MixView = React.forwardRef(function (props, ref) {
26974
26973
  };
26975
26974
  // eslint-disable-next-line react-hooks/exhaustive-deps
26976
26975
  }, [viewId]);
26977
- return (jsxRuntime.jsx(NativeMixView, __assign({}, restProps, { viewId: viewId, captureMode: captureMode, captureFramerate: captureFramerate, autoSensitivity: autoSensitivity, ref: ref })));
26976
+ return (jsxRuntime.jsx(NativeMixView, __assign({}, restProps, { viewId: viewId, captureMode: captureMode, captureFramerate: captureFramerate, ref: ref })));
26978
26977
  });
26979
26978
 
26980
26979
  var VeView = React.forwardRef(function (props, ref) {
@@ -27009,7 +27008,7 @@ var VeImageView = React.forwardRef(function (props, ref) {
27009
27008
  });
27010
27009
 
27011
27010
  var VeWebView = React.forwardRef(function (props, ref) {
27012
- var renderMode = props.renderMode, _a = props.captureMode, captureMode = _a === void 0 ? 'auto' : _a, onViewMount = props.onViewMount, onViewUnmount = props.onViewUnmount, viewId = props.viewId, viewProps = __rest(props, ["renderMode", "captureMode", "onViewMount", "onViewUnmount", "viewId"]);
27011
+ var renderMode = props.renderMode, _a = props.captureMode, captureMode = _a === void 0 ? 'realtime' : _a, onViewMount = props.onViewMount, onViewUnmount = props.onViewUnmount, viewId = props.viewId, viewProps = __rest(props, ["renderMode", "captureMode", "onViewMount", "onViewUnmount", "viewId"]);
27013
27012
  return (jsxRuntime.jsx(MixView, { renderMode: renderMode, captureMode: captureMode, viewId: viewId, onViewMount: onViewMount, onViewUnmount: onViewUnmount, children: jsxRuntime.jsx(reactNative.View, __assign({}, viewProps, { ref: ref })) }));
27014
27013
  });
27015
27014
 
@@ -7,12 +7,11 @@ export interface MixConfig {
7
7
  alpha?: number;
8
8
  zOrder?: number;
9
9
  renderMode?: number;
10
- captureMode?: 'onchange' | 'realtime' | 'auto' | 'manual';
10
+ captureMode?: 'onchange' | 'realtime' | 'manual';
11
11
  }
12
12
  export interface MixViewConfig {
13
13
  renderMode?: number;
14
- captureMode?: 'onchange' | 'realtime' | 'auto' | 'manual';
14
+ captureMode?: 'onchange' | 'realtime' | 'manual';
15
15
  captureFramerate?: number;
16
- autoSensitivity?: number;
17
16
  }
18
17
  export { VeLiveOrientation, VeLiveAudioBufferType, VeLiveAudioCaptureConfiguration, VeLiveAudioCaptureType, VeLiveAudioChannel, VeLiveAudioEncoderConfiguration, VeLiveAudioFrameSource, VeLiveAudioMixType, VeLiveAudioPowerLevel, VeLiveAudioProfile, VeLiveAudioSampleRate, VeLiveFileRecorderConfiguration, VeLiveFirstFrameType, VeLiveMixAudioLayout, VeLiveMixVideoLayout, VeLiveNetworkQuality, VeLivePixelFormat, VeLivePusherLogLevel, VeLivePusherRenderMode, VeLivePusherStatistics, VeLivePusherStatus, VeLiveStreamMixDescription, VeLiveVideoBufferType, VeLiveVideoCaptureConfiguration, VeLiveVideoCaptureType, VeLiveVideoCodec, VeLiveVideoEffectLicenseConfiguration, VeLiveVideoEffectLicenseType, VeLiveVideoEncoderConfiguration, VeLiveVideoFrameSource, VeLiveVideoMirrorType, VeLiveVideoResolution, VeLiveVideoRotation, };
@@ -17,20 +17,12 @@ export interface NativeMixViewProps extends ViewProps, Partial<MixViewConfig> {
17
17
  * - 'manual': User controls capture timing via ref methods
18
18
  * Best for: Custom scenarios where you want full control
19
19
  * Performance: Depends on user implementation
20
- *
21
- * - 'auto': Automatically detect based on content behavior (experimental)
22
- * Monitors view changes and switches between onchange/realtime
23
20
  */
24
- captureMode?: 'onchange' | 'realtime' | 'manual' | 'auto';
21
+ captureMode?: 'onchange' | 'realtime' | 'manual';
25
22
  /**
26
23
  * For realtime mode: custom framerate (default uses stream framerate)
27
24
  */
28
25
  captureFramerate?: number;
29
- /**
30
- * For auto mode: sensitivity threshold for switching to realtime
31
- * Higher values = less sensitive to changes
32
- */
33
- autoSensitivity?: number;
34
26
  }
35
27
  export interface MixViewEventProps {
36
28
  /**
@@ -26956,8 +26956,7 @@ var getId = function () {
26956
26956
  };
26957
26957
  var MixView = React.forwardRef(function (props, ref) {
26958
26958
  var _a = props.captureMode, captureMode = _a === void 0 ? 'onchange' : _a, // Default to most performant mode
26959
- captureFramerate = props.captureFramerate, _b = props.autoSensitivity, autoSensitivity = _b === void 0 ? 5 : _b, // Default sensitivity
26960
- onViewMount = props.onViewMount, onViewUnmount = props.onViewUnmount, restProps = __rest(props, ["captureMode", "captureFramerate", "autoSensitivity", "onViewMount", "onViewUnmount"]);
26959
+ captureFramerate = props.captureFramerate, onViewMount = props.onViewMount, onViewUnmount = props.onViewUnmount, restProps = __rest(props, ["captureMode", "captureFramerate", "onViewMount", "onViewUnmount"]);
26961
26960
  var viewId = useMemo(function () {
26962
26961
  return restProps.viewId || getId();
26963
26962
  }, [restProps.viewId]);
@@ -26972,7 +26971,7 @@ var MixView = React.forwardRef(function (props, ref) {
26972
26971
  };
26973
26972
  // eslint-disable-next-line react-hooks/exhaustive-deps
26974
26973
  }, [viewId]);
26975
- return (jsx(NativeMixView, __assign({}, restProps, { viewId: viewId, captureMode: captureMode, captureFramerate: captureFramerate, autoSensitivity: autoSensitivity, ref: ref })));
26974
+ return (jsx(NativeMixView, __assign({}, restProps, { viewId: viewId, captureMode: captureMode, captureFramerate: captureFramerate, ref: ref })));
26976
26975
  });
26977
26976
 
26978
26977
  var VeView = React.forwardRef(function (props, ref) {
@@ -27007,7 +27006,7 @@ var VeImageView = React.forwardRef(function (props, ref) {
27007
27006
  });
27008
27007
 
27009
27008
  var VeWebView = React.forwardRef(function (props, ref) {
27010
- var renderMode = props.renderMode, _a = props.captureMode, captureMode = _a === void 0 ? 'auto' : _a, onViewMount = props.onViewMount, onViewUnmount = props.onViewUnmount, viewId = props.viewId, viewProps = __rest(props, ["renderMode", "captureMode", "onViewMount", "onViewUnmount", "viewId"]);
27009
+ var renderMode = props.renderMode, _a = props.captureMode, captureMode = _a === void 0 ? 'realtime' : _a, onViewMount = props.onViewMount, onViewUnmount = props.onViewUnmount, viewId = props.viewId, viewProps = __rest(props, ["renderMode", "captureMode", "onViewMount", "onViewUnmount", "viewId"]);
27011
27010
  return (jsx(MixView, { renderMode: renderMode, captureMode: captureMode, viewId: viewId, onViewMount: onViewMount, onViewUnmount: onViewUnmount, children: jsx(View, __assign({}, viewProps, { ref: ref })) }));
27012
27011
  });
27013
27012
 
@@ -7,12 +7,11 @@ export interface MixConfig {
7
7
  alpha?: number;
8
8
  zOrder?: number;
9
9
  renderMode?: number;
10
- captureMode?: 'onchange' | 'realtime' | 'auto' | 'manual';
10
+ captureMode?: 'onchange' | 'realtime' | 'manual';
11
11
  }
12
12
  export interface MixViewConfig {
13
13
  renderMode?: number;
14
- captureMode?: 'onchange' | 'realtime' | 'auto' | 'manual';
14
+ captureMode?: 'onchange' | 'realtime' | 'manual';
15
15
  captureFramerate?: number;
16
- autoSensitivity?: number;
17
16
  }
18
17
  export { VeLiveOrientation, VeLiveAudioBufferType, VeLiveAudioCaptureConfiguration, VeLiveAudioCaptureType, VeLiveAudioChannel, VeLiveAudioEncoderConfiguration, VeLiveAudioFrameSource, VeLiveAudioMixType, VeLiveAudioPowerLevel, VeLiveAudioProfile, VeLiveAudioSampleRate, VeLiveFileRecorderConfiguration, VeLiveFirstFrameType, VeLiveMixAudioLayout, VeLiveMixVideoLayout, VeLiveNetworkQuality, VeLivePixelFormat, VeLivePusherLogLevel, VeLivePusherRenderMode, VeLivePusherStatistics, VeLivePusherStatus, VeLiveStreamMixDescription, VeLiveVideoBufferType, VeLiveVideoCaptureConfiguration, VeLiveVideoCaptureType, VeLiveVideoCodec, VeLiveVideoEffectLicenseConfiguration, VeLiveVideoEffectLicenseType, VeLiveVideoEncoderConfiguration, VeLiveVideoFrameSource, VeLiveVideoMirrorType, VeLiveVideoResolution, VeLiveVideoRotation, };
@@ -17,20 +17,12 @@ export interface NativeMixViewProps extends ViewProps, Partial<MixViewConfig> {
17
17
  * - 'manual': User controls capture timing via ref methods
18
18
  * Best for: Custom scenarios where you want full control
19
19
  * Performance: Depends on user implementation
20
- *
21
- * - 'auto': Automatically detect based on content behavior (experimental)
22
- * Monitors view changes and switches between onchange/realtime
23
20
  */
24
- captureMode?: 'onchange' | 'realtime' | 'manual' | 'auto';
21
+ captureMode?: 'onchange' | 'realtime' | 'manual';
25
22
  /**
26
23
  * For realtime mode: custom framerate (default uses stream framerate)
27
24
  */
28
25
  captureFramerate?: number;
29
- /**
30
- * For auto mode: sensitivity threshold for switching to realtime
31
- * Higher values = less sensitive to changes
32
- */
33
- autoSensitivity?: number;
34
26
  }
35
27
  export interface MixViewEventProps {
36
28
  /**
@@ -7,12 +7,11 @@ export interface MixConfig {
7
7
  alpha?: number;
8
8
  zOrder?: number;
9
9
  renderMode?: number;
10
- captureMode?: 'onchange' | 'realtime' | 'auto' | 'manual';
10
+ captureMode?: 'onchange' | 'realtime' | 'manual';
11
11
  }
12
12
  export interface MixViewConfig {
13
13
  renderMode?: number;
14
- captureMode?: 'onchange' | 'realtime' | 'auto' | 'manual';
14
+ captureMode?: 'onchange' | 'realtime' | 'manual';
15
15
  captureFramerate?: number;
16
- autoSensitivity?: number;
17
16
  }
18
17
  export { VeLiveOrientation, VeLiveAudioBufferType, VeLiveAudioCaptureConfiguration, VeLiveAudioCaptureType, VeLiveAudioChannel, VeLiveAudioEncoderConfiguration, VeLiveAudioFrameSource, VeLiveAudioMixType, VeLiveAudioPowerLevel, VeLiveAudioProfile, VeLiveAudioSampleRate, VeLiveFileRecorderConfiguration, VeLiveFirstFrameType, VeLiveMixAudioLayout, VeLiveMixVideoLayout, VeLiveNetworkQuality, VeLivePixelFormat, VeLivePusherLogLevel, VeLivePusherRenderMode, VeLivePusherStatistics, VeLivePusherStatus, VeLiveStreamMixDescription, VeLiveVideoBufferType, VeLiveVideoCaptureConfiguration, VeLiveVideoCaptureType, VeLiveVideoCodec, VeLiveVideoEffectLicenseConfiguration, VeLiveVideoEffectLicenseType, VeLiveVideoEncoderConfiguration, VeLiveVideoFrameSource, VeLiveVideoMirrorType, VeLiveVideoResolution, VeLiveVideoRotation, };
@@ -17,20 +17,12 @@ export interface NativeMixViewProps extends ViewProps, Partial<MixViewConfig> {
17
17
  * - 'manual': User controls capture timing via ref methods
18
18
  * Best for: Custom scenarios where you want full control
19
19
  * Performance: Depends on user implementation
20
- *
21
- * - 'auto': Automatically detect based on content behavior (experimental)
22
- * Monitors view changes and switches between onchange/realtime
23
20
  */
24
- captureMode?: 'onchange' | 'realtime' | 'manual' | 'auto';
21
+ captureMode?: 'onchange' | 'realtime' | 'manual';
25
22
  /**
26
23
  * For realtime mode: custom framerate (default uses stream framerate)
27
24
  */
28
25
  captureFramerate?: number;
29
- /**
30
- * For auto mode: sensitivity threshold for switching to realtime
31
- * Higher values = less sensitive to changes
32
- */
33
- autoSensitivity?: number;
34
26
  }
35
27
  export interface MixViewEventProps {
36
28
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byteplus/react-native-live-push",
3
- "version": "1.2.0-rc.0",
3
+ "version": "1.3.0-rc.0",
4
4
  "peerDependencies": {
5
5
  "react": "*",
6
6
  "react-native": "*"
@@ -50,6 +50,6 @@ Pod::Spec.new do |s|
50
50
  end
51
51
 
52
52
  s.dependency 'VolcApiEngine', '1.6.2'
53
- s.dependency 'TTSDKFramework/Core', '1.46.300.1-premium'
54
- s.dependency 'TTSDKFramework/LivePush-RTS', '1.46.300.1-premium'
53
+ s.dependency 'TTSDKFramework/Core', '1.46.300.3-premium'
54
+ s.dependency 'TTSDKFramework/LivePush-RTS', '1.46.300.3-premium'
55
55
  end