@bits-innovate/react-native-vstarcam 1.0.18 → 1.0.20

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.
@@ -0,0 +1,9 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+ package="com.veepai.app_player" >
4
+
5
+ <uses-sdk
6
+ android:minSdkVersion="24"
7
+ android:targetSdkVersion="24" />
8
+
9
+ </manifest>
@@ -0,0 +1,4 @@
1
+ aarFormatVersion=1.0
2
+ aarMetadataVersion=1.0
3
+ minCompileSdk=1
4
+ minAndroidGradlePluginVersion=1.0.0
@@ -0,0 +1,229 @@
1
+ int attr activityAction 0x0
2
+ int attr activityName 0x0
3
+ int attr alpha 0x0
4
+ int attr alwaysExpand 0x0
5
+ int attr clearTop 0x0
6
+ int attr finishPrimaryWithSecondary 0x0
7
+ int attr finishSecondaryWithPrimary 0x0
8
+ int attr font 0x0
9
+ int attr fontProviderAuthority 0x0
10
+ int attr fontProviderCerts 0x0
11
+ int attr fontProviderFetchStrategy 0x0
12
+ int attr fontProviderFetchTimeout 0x0
13
+ int attr fontProviderPackage 0x0
14
+ int attr fontProviderQuery 0x0
15
+ int attr fontProviderSystemFontFamily 0x0
16
+ int attr fontStyle 0x0
17
+ int attr fontVariationSettings 0x0
18
+ int attr fontWeight 0x0
19
+ int attr nestedScrollViewStyle 0x0
20
+ int attr placeholderActivityName 0x0
21
+ int attr primaryActivityName 0x0
22
+ int attr queryPatterns 0x0
23
+ int attr secondaryActivityAction 0x0
24
+ int attr secondaryActivityName 0x0
25
+ int attr shortcutMatchRequired 0x0
26
+ int attr splitLayoutDirection 0x0
27
+ int attr splitMinSmallestWidth 0x0
28
+ int attr splitMinWidth 0x0
29
+ int attr splitRatio 0x0
30
+ int attr ttcIndex 0x0
31
+ int color androidx_core_ripple_material_light 0x0
32
+ int color androidx_core_secondary_text_default_material_light 0x0
33
+ int color notification_action_color_filter 0x0
34
+ int color notification_icon_bg_color 0x0
35
+ int color ripple_material_light 0x0
36
+ int color secondary_text_default_material_light 0x0
37
+ int dimen compat_button_inset_horizontal_material 0x0
38
+ int dimen compat_button_inset_vertical_material 0x0
39
+ int dimen compat_button_padding_horizontal_material 0x0
40
+ int dimen compat_button_padding_vertical_material 0x0
41
+ int dimen compat_control_corner_material 0x0
42
+ int dimen compat_notification_large_icon_max_height 0x0
43
+ int dimen compat_notification_large_icon_max_width 0x0
44
+ int dimen notification_action_icon_size 0x0
45
+ int dimen notification_action_text_size 0x0
46
+ int dimen notification_big_circle_margin 0x0
47
+ int dimen notification_content_margin_start 0x0
48
+ int dimen notification_large_icon_height 0x0
49
+ int dimen notification_large_icon_width 0x0
50
+ int dimen notification_main_column_padding_top 0x0
51
+ int dimen notification_media_narrow_margin 0x0
52
+ int dimen notification_right_icon_size 0x0
53
+ int dimen notification_right_side_padding_top 0x0
54
+ int dimen notification_small_icon_background_padding 0x0
55
+ int dimen notification_small_icon_size_as_large 0x0
56
+ int dimen notification_subtext_size 0x0
57
+ int dimen notification_top_pad 0x0
58
+ int dimen notification_top_pad_large_text 0x0
59
+ int drawable launch_background 0x0
60
+ int drawable notification_action_background 0x0
61
+ int drawable notification_bg 0x0
62
+ int drawable notification_bg_low 0x0
63
+ int drawable notification_bg_low_normal 0x0
64
+ int drawable notification_bg_low_pressed 0x0
65
+ int drawable notification_bg_normal 0x0
66
+ int drawable notification_bg_normal_pressed 0x0
67
+ int drawable notification_icon_background 0x0
68
+ int drawable notification_template_icon_bg 0x0
69
+ int drawable notification_template_icon_low_bg 0x0
70
+ int drawable notification_tile_bg 0x0
71
+ int drawable notify_panel_notification_icon_bg 0x0
72
+ int id accessibility_action_clickable_span 0x0
73
+ int id accessibility_custom_action_0 0x0
74
+ int id accessibility_custom_action_1 0x0
75
+ int id accessibility_custom_action_10 0x0
76
+ int id accessibility_custom_action_11 0x0
77
+ int id accessibility_custom_action_12 0x0
78
+ int id accessibility_custom_action_13 0x0
79
+ int id accessibility_custom_action_14 0x0
80
+ int id accessibility_custom_action_15 0x0
81
+ int id accessibility_custom_action_16 0x0
82
+ int id accessibility_custom_action_17 0x0
83
+ int id accessibility_custom_action_18 0x0
84
+ int id accessibility_custom_action_19 0x0
85
+ int id accessibility_custom_action_2 0x0
86
+ int id accessibility_custom_action_20 0x0
87
+ int id accessibility_custom_action_21 0x0
88
+ int id accessibility_custom_action_22 0x0
89
+ int id accessibility_custom_action_23 0x0
90
+ int id accessibility_custom_action_24 0x0
91
+ int id accessibility_custom_action_25 0x0
92
+ int id accessibility_custom_action_26 0x0
93
+ int id accessibility_custom_action_27 0x0
94
+ int id accessibility_custom_action_28 0x0
95
+ int id accessibility_custom_action_29 0x0
96
+ int id accessibility_custom_action_3 0x0
97
+ int id accessibility_custom_action_30 0x0
98
+ int id accessibility_custom_action_31 0x0
99
+ int id accessibility_custom_action_4 0x0
100
+ int id accessibility_custom_action_5 0x0
101
+ int id accessibility_custom_action_6 0x0
102
+ int id accessibility_custom_action_7 0x0
103
+ int id accessibility_custom_action_8 0x0
104
+ int id accessibility_custom_action_9 0x0
105
+ int id action_container 0x0
106
+ int id action_divider 0x0
107
+ int id action_image 0x0
108
+ int id action_text 0x0
109
+ int id actions 0x0
110
+ int id androidx_window_activity_scope 0x0
111
+ int id async 0x0
112
+ int id blocking 0x0
113
+ int id chronometer 0x0
114
+ int id dialog_button 0x0
115
+ int id forever 0x0
116
+ int id icon 0x0
117
+ int id icon_group 0x0
118
+ int id info 0x0
119
+ int id italic 0x0
120
+ int id line1 0x0
121
+ int id line3 0x0
122
+ int id locale 0x0
123
+ int id ltr 0x0
124
+ int id normal 0x0
125
+ int id notification_background 0x0
126
+ int id notification_main_column 0x0
127
+ int id notification_main_column_container 0x0
128
+ int id right_icon 0x0
129
+ int id right_side 0x0
130
+ int id rtl 0x0
131
+ int id tag_accessibility_actions 0x0
132
+ int id tag_accessibility_clickable_spans 0x0
133
+ int id tag_accessibility_heading 0x0
134
+ int id tag_accessibility_pane_title 0x0
135
+ int id tag_on_apply_window_listener 0x0
136
+ int id tag_on_receive_content_listener 0x0
137
+ int id tag_on_receive_content_mime_types 0x0
138
+ int id tag_screen_reader_focusable 0x0
139
+ int id tag_state_description 0x0
140
+ int id tag_transition_group 0x0
141
+ int id tag_unhandled_key_event_manager 0x0
142
+ int id tag_unhandled_key_listeners 0x0
143
+ int id tag_window_insets_animation_callback 0x0
144
+ int id text 0x0
145
+ int id text2 0x0
146
+ int id time 0x0
147
+ int id title 0x0
148
+ int integer status_bar_notification_info_maxnum 0x0
149
+ int layout custom_dialog 0x0
150
+ int layout notification_action 0x0
151
+ int layout notification_action_tombstone 0x0
152
+ int layout notification_template_custom_big 0x0
153
+ int layout notification_template_icon_group 0x0
154
+ int layout notification_template_part_chronometer 0x0
155
+ int layout notification_template_part_time 0x0
156
+ int string status_bar_notification_info_overflow 0x0
157
+ int style LaunchTheme 0x0
158
+ int style TextAppearance_Compat_Notification 0x0
159
+ int style TextAppearance_Compat_Notification_Info 0x0
160
+ int style TextAppearance_Compat_Notification_Line2 0x0
161
+ int style TextAppearance_Compat_Notification_Time 0x0
162
+ int style TextAppearance_Compat_Notification_Title 0x0
163
+ int style Widget_Compat_NotificationActionContainer 0x0
164
+ int style Widget_Compat_NotificationActionText 0x0
165
+ int[] styleable ActivityFilter { 0x0, 0x0 }
166
+ int styleable ActivityFilter_activityAction 0
167
+ int styleable ActivityFilter_activityName 1
168
+ int[] styleable ActivityRule { 0x0 }
169
+ int styleable ActivityRule_alwaysExpand 0
170
+ int[] styleable Capability { 0x0, 0x0 }
171
+ int styleable Capability_queryPatterns 0
172
+ int styleable Capability_shortcutMatchRequired 1
173
+ int[] styleable ColorStateListItem { 0x0, 0x101031f, 0x10101a5 }
174
+ int styleable ColorStateListItem_alpha 0
175
+ int styleable ColorStateListItem_android_alpha 1
176
+ int styleable ColorStateListItem_android_color 2
177
+ int[] styleable FontFamily { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
178
+ int styleable FontFamily_fontProviderAuthority 0
179
+ int styleable FontFamily_fontProviderCerts 1
180
+ int styleable FontFamily_fontProviderFetchStrategy 2
181
+ int styleable FontFamily_fontProviderFetchTimeout 3
182
+ int styleable FontFamily_fontProviderPackage 4
183
+ int styleable FontFamily_fontProviderQuery 5
184
+ int styleable FontFamily_fontProviderSystemFontFamily 6
185
+ int[] styleable FontFamilyFont { 0x1010532, 0x101053f, 0x1010570, 0x1010533, 0x101056f, 0x0, 0x0, 0x0, 0x0, 0x0 }
186
+ int styleable FontFamilyFont_android_font 0
187
+ int styleable FontFamilyFont_android_fontStyle 1
188
+ int styleable FontFamilyFont_android_fontVariationSettings 2
189
+ int styleable FontFamilyFont_android_fontWeight 3
190
+ int styleable FontFamilyFont_android_ttcIndex 4
191
+ int styleable FontFamilyFont_font 5
192
+ int styleable FontFamilyFont_fontStyle 6
193
+ int styleable FontFamilyFont_fontVariationSettings 7
194
+ int styleable FontFamilyFont_fontWeight 8
195
+ int styleable FontFamilyFont_ttcIndex 9
196
+ int[] styleable GradientColor { 0x101020b, 0x10101a2, 0x10101a3, 0x101019e, 0x1010512, 0x1010513, 0x10101a4, 0x101019d, 0x1010510, 0x1010511, 0x1010201, 0x10101a1 }
197
+ int styleable GradientColor_android_centerColor 0
198
+ int styleable GradientColor_android_centerX 1
199
+ int styleable GradientColor_android_centerY 2
200
+ int styleable GradientColor_android_endColor 3
201
+ int styleable GradientColor_android_endX 4
202
+ int styleable GradientColor_android_endY 5
203
+ int styleable GradientColor_android_gradientRadius 6
204
+ int styleable GradientColor_android_startColor 7
205
+ int styleable GradientColor_android_startX 8
206
+ int styleable GradientColor_android_startY 9
207
+ int styleable GradientColor_android_tileMode 10
208
+ int styleable GradientColor_android_type 11
209
+ int[] styleable GradientColorItem { 0x10101a5, 0x1010514 }
210
+ int styleable GradientColorItem_android_color 0
211
+ int styleable GradientColorItem_android_offset 1
212
+ int[] styleable SplitPairFilter { 0x0, 0x0, 0x0 }
213
+ int styleable SplitPairFilter_primaryActivityName 0
214
+ int styleable SplitPairFilter_secondaryActivityAction 1
215
+ int styleable SplitPairFilter_secondaryActivityName 2
216
+ int[] styleable SplitPairRule { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
217
+ int styleable SplitPairRule_clearTop 0
218
+ int styleable SplitPairRule_finishPrimaryWithSecondary 1
219
+ int styleable SplitPairRule_finishSecondaryWithPrimary 2
220
+ int styleable SplitPairRule_splitLayoutDirection 3
221
+ int styleable SplitPairRule_splitMinSmallestWidth 4
222
+ int styleable SplitPairRule_splitMinWidth 5
223
+ int styleable SplitPairRule_splitRatio 6
224
+ int[] styleable SplitPlaceholderRule { 0x0, 0x0, 0x0, 0x0, 0x0 }
225
+ int styleable SplitPlaceholderRule_placeholderActivityName 0
226
+ int styleable SplitPlaceholderRule_splitLayoutDirection 1
227
+ int styleable SplitPlaceholderRule_splitMinSmallestWidth 2
228
+ int styleable SplitPlaceholderRule_splitMinWidth 3
229
+ int styleable SplitPlaceholderRule_splitRatio 4
@@ -140,7 +140,8 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
140
140
  private final ExecutorService executor;
141
141
 
142
142
  // Client tracking - maps our clientPtr to actual SDK client handle
143
- private Map<Integer, ClientInfo> clients = new HashMap<>();
143
+ // Made static so VStarCamVideoView can access SDK pointers
144
+ private static Map<Integer, ClientInfo> clients = new HashMap<>();
144
145
  private boolean isNativeLibraryLoaded = false;
145
146
  private boolean isP2PInitialized = false;
146
147
 
@@ -156,8 +157,21 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
156
157
  long sdkClientPtr = 0; // Actual SDK client pointer (long)
157
158
  boolean isConnected = false;
158
159
  boolean isLoggedIn = false;
160
+ String username; // Login username for CGI commands
161
+ String password; // Login password for CGI commands
159
162
  }
160
163
 
164
+ /**
165
+ * Get the actual SDK client pointer for a given internal client ID.
166
+ * This is needed by VStarCamVideoView to connect to the player.
167
+ */
168
+ public static long getSdkClientPtr(int clientPtr) {
169
+ ClientInfo info = clients.get(clientPtr);
170
+ if (info != null) {
171
+ return info.sdkClientPtr;
172
+ }
173
+ return 0;
174
+ }
161
175
 
162
176
  public VStarCamModule(ReactApplicationContext reactContext) {
163
177
  super(reactContext);
@@ -552,6 +566,8 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
552
566
  }
553
567
 
554
568
  clientInfo.isLoggedIn = true;
569
+ clientInfo.username = username;
570
+ clientInfo.password = password;
555
571
  Log.d(TAG, "JNIApi.login called successfully");
556
572
 
557
573
  promise.resolve(true);
@@ -680,13 +696,45 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
680
696
  }
681
697
 
682
698
  /**
683
- * Start video stream
699
+ * Start video stream by sending livestream.cgi command
700
+ * Resolution: 1=high, 2=general, 4=low, 100=superHD
684
701
  */
685
702
  @ReactMethod
686
703
  public void startVideoStream(int clientPtr, int streamType, Promise promise) {
687
- // TODO: Implement video streaming
688
- Log.d(TAG, "startVideoStream called - not yet implemented");
689
- promise.resolve(true);
704
+ Log.d(TAG, "startVideoStream called with type: " + streamType);
705
+ try {
706
+ ClientInfo clientInfo = clients.get(clientPtr);
707
+ if (clientInfo == null || clientInfo.sdkClientPtr == 0) {
708
+ promise.reject("E_NOT_CONNECTED", "Client not connected");
709
+ return;
710
+ }
711
+
712
+ // Send livestream.cgi command to start streaming
713
+ // streamid=10 starts the stream, substream is the resolution
714
+ String cgi = String.format(
715
+ "livestream.cgi?streamid=10&substream=%d&loginuse=%s&loginpas=%s",
716
+ streamType,
717
+ clientInfo.username != null ? clientInfo.username : "admin",
718
+ clientInfo.password != null ? clientInfo.password : ""
719
+ );
720
+
721
+ Log.d(TAG, "Sending livestream start command: " + cgi);
722
+
723
+ Method writeCgiMethod = jniApiClass.getMethod("writeCgi", long.class, String.class, int.class);
724
+ Object result = writeCgiMethod.invoke(null, clientInfo.sdkClientPtr, cgi, 5);
725
+
726
+ Log.d(TAG, "livestream start command sent, result: " + result);
727
+
728
+ WritableMap response = Arguments.createMap();
729
+ response.putBoolean("success", true);
730
+ response.putString("message", "Video stream started");
731
+ response.putInt("resolution", streamType);
732
+ promise.resolve(response);
733
+
734
+ } catch (Exception e) {
735
+ Log.e(TAG, "startVideoStream error", e);
736
+ promise.reject("E_VIDEO_START_FAILED", e.getMessage(), e);
737
+ }
690
738
  }
691
739
 
692
740
  /**
@@ -695,7 +743,37 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
695
743
  @ReactMethod
696
744
  public void stopVideoStream(int clientPtr, Promise promise) {
697
745
  Log.d(TAG, "stopVideoStream called");
698
- promise.resolve(true);
746
+ try {
747
+ ClientInfo clientInfo = clients.get(clientPtr);
748
+ if (clientInfo == null || clientInfo.sdkClientPtr == 0) {
749
+ promise.reject("E_NOT_CONNECTED", "Client not connected");
750
+ return;
751
+ }
752
+
753
+ // Send livestream.cgi command to stop streaming
754
+ // streamid=16 stops the stream
755
+ String cgi = String.format(
756
+ "livestream.cgi?streamid=16&substream=0&loginuse=%s&loginpas=%s",
757
+ clientInfo.username != null ? clientInfo.username : "admin",
758
+ clientInfo.password != null ? clientInfo.password : ""
759
+ );
760
+
761
+ Log.d(TAG, "Sending livestream stop command: " + cgi);
762
+
763
+ Method writeCgiMethod = jniApiClass.getMethod("writeCgi", long.class, String.class, int.class);
764
+ Object result = writeCgiMethod.invoke(null, clientInfo.sdkClientPtr, cgi, 5);
765
+
766
+ Log.d(TAG, "livestream stop command sent, result: " + result);
767
+
768
+ WritableMap response = Arguments.createMap();
769
+ response.putBoolean("success", true);
770
+ response.putString("message", "Video stream stopped");
771
+ promise.resolve(response);
772
+
773
+ } catch (Exception e) {
774
+ Log.e(TAG, "stopVideoStream error", e);
775
+ promise.reject("E_VIDEO_STOP_FAILED", e.getMessage(), e);
776
+ }
699
777
  }
700
778
 
701
779
  /**
@@ -757,7 +835,7 @@ public class VStarCamModule extends ReactContextBaseJavaModule {
757
835
  @ReactMethod
758
836
  public void getSdkVersion(Promise promise) {
759
837
  WritableMap result = Arguments.createMap();
760
- result.putString("version", "1.0.18");
838
+ result.putString("version", "1.0.20");
761
839
  result.putBoolean("nativeLoaded", isNativeLibraryLoaded);
762
840
  result.putString("nativeLib", "OKSMARTPPCS");
763
841
  result.putBoolean("p2pInitialized", isP2PInitialized);
@@ -4,6 +4,7 @@ import android.content.Context;
4
4
  import android.graphics.Color;
5
5
  import android.graphics.SurfaceTexture;
6
6
  import android.util.Log;
7
+ import android.view.Surface;
7
8
  import android.view.TextureView;
8
9
  import android.view.Gravity;
9
10
  import android.widget.FrameLayout;
@@ -13,39 +14,46 @@ import java.lang.reflect.Method;
13
14
 
14
15
  /**
15
16
  * Native video view for VStarCam camera streaming.
16
- * Uses TextureView for video rendering with the native player SDK.
17
+ * Uses TextureView for video rendering with the native AppPlayer SDK.
17
18
  */
18
- public class VStarCamVideoView extends FrameLayout implements TextureView.SurfaceTextureListener {
19
+ public class VStarCamVideoView extends FrameLayout
20
+ implements TextureView.SurfaceTextureListener {
21
+
19
22
  private static final String TAG = "VStarCamVideoView";
20
-
23
+
21
24
  private TextureView textureView;
22
25
  private TextView statusView;
26
+ private Surface surface;
27
+
28
+ // Client info
23
29
  private long clientPtr = 0;
30
+ private long sdkClientPtr = 0; // Actual SDK pointer from VStarCamModule
31
+ private int resolution = 2;
32
+
33
+ // Player info
24
34
  private long playerPtr = 0;
25
35
  private boolean isStreaming = false;
26
- private int resolution = 2; // Default to general resolution
27
-
28
- // Player library class
36
+ private boolean playerInitialized = false;
37
+
38
+ // Player class (from AAR)
29
39
  private Class<?> appPlayerClass;
30
- private Object playerInstance;
31
- private boolean playerLibLoaded = false;
32
-
40
+
33
41
  public VStarCamVideoView(Context context) {
34
42
  super(context);
35
43
  init(context);
36
44
  }
37
-
45
+
38
46
  private void init(Context context) {
39
47
  setBackgroundColor(Color.BLACK);
40
-
41
- // Create texture view for video rendering
48
+
49
+ // Create TextureView for video rendering
42
50
  textureView = new TextureView(context);
43
51
  textureView.setSurfaceTextureListener(this);
44
52
  addView(textureView, new LayoutParams(
45
- LayoutParams.MATCH_PARENT,
53
+ LayoutParams.MATCH_PARENT,
46
54
  LayoutParams.MATCH_PARENT
47
55
  ));
48
-
56
+
49
57
  // Status overlay
50
58
  statusView = new TextView(context);
51
59
  statusView.setTextColor(Color.WHITE);
@@ -58,140 +66,291 @@ public class VStarCamVideoView extends FrameLayout implements TextureView.Surfac
58
66
  );
59
67
  statusParams.gravity = Gravity.CENTER;
60
68
  addView(statusView, statusParams);
61
-
62
- // Try to load player library
69
+
70
+ // Load player library and find class
63
71
  loadPlayerLibrary();
64
72
  }
65
-
73
+
66
74
  private void loadPlayerLibrary() {
67
75
  try {
76
+ // Load the player native lib
68
77
  System.loadLibrary("OKSMARTPLAY");
69
- playerLibLoaded = true;
70
- Log.d(TAG, "Player library loaded successfully");
71
-
72
- // Try to find player class via reflection
73
- try {
74
- appPlayerClass = Class.forName("com.vstarcam.player.AppPlayer");
75
- Log.d(TAG, "AppPlayer class found");
76
- } catch (ClassNotFoundException e) {
77
- // Try alternative class names
78
+ Log.d(TAG, "OKSMARTPLAY library loaded");
79
+
80
+ // Find AppPlayer class - try multiple possible package names
81
+ // Based on decompiling app_player-5.0.0.aar classes.jar
82
+ String[] classNames = {
83
+ "com.veepai.AppPlayerApi", // Main API class from AAR
84
+ "com.veepai.app_player.AppPlayerPlugin", // Flutter plugin wrapper
85
+ "com.vstarcam.player.AppPlayer",
86
+ "com.vstarcam.AppPlayer",
87
+ "com.oksmartplay.AppPlayer"
88
+ };
89
+
90
+ for (String className : classNames) {
78
91
  try {
79
- appPlayerClass = Class.forName("com.vstarcam.AppPlayer");
80
- Log.d(TAG, "AppPlayer class found (alt path)");
81
- } catch (ClassNotFoundException e2) {
82
- Log.w(TAG, "AppPlayer class not found, using native methods directly");
92
+ appPlayerClass = Class.forName(className);
93
+ Log.d(TAG, "Found player class: " + className);
94
+
95
+ // Log available methods for debugging
96
+ logPlayerMethods();
97
+ break;
98
+ } catch (ClassNotFoundException ignored) {
99
+ Log.d(TAG, "Class not found: " + className);
83
100
  }
84
101
  }
102
+
103
+ if (appPlayerClass == null) {
104
+ Log.e(TAG, "Could not find AppPlayer class in AAR");
105
+ }
106
+
85
107
  } catch (UnsatisfiedLinkError e) {
86
- Log.e(TAG, "Failed to load player library: " + e.getMessage());
87
- playerLibLoaded = false;
108
+ Log.e(TAG, "Failed to load OKSMARTPLAY: " + e.getMessage());
88
109
  }
89
110
  }
90
-
111
+
112
+ private void logPlayerMethods() {
113
+ if (appPlayerClass == null) return;
114
+
115
+ Log.d(TAG, "=== AppPlayer Methods ===");
116
+ for (Method m : appPlayerClass.getDeclaredMethods()) {
117
+ StringBuilder params = new StringBuilder();
118
+ for (Class<?> p : m.getParameterTypes()) {
119
+ if (params.length() > 0) params.append(", ");
120
+ params.append(p.getSimpleName());
121
+ }
122
+ Log.d(TAG, " " + m.getName() + "(" + params + ") -> " +
123
+ m.getReturnType().getSimpleName());
124
+ }
125
+ }
126
+
91
127
  /**
92
- * Set the client pointer for video streaming
128
+ * Set the client pointer from VStarCamModule.
129
+ * This is our internal pointer ID, not the SDK pointer.
93
130
  */
94
131
  public void setClientPtr(long ptr) {
95
132
  this.clientPtr = ptr;
96
133
  Log.d(TAG, "Client pointer set: " + ptr);
97
-
98
- if (clientPtr != 0) {
134
+
135
+ // Lookup the actual SDK pointer from VStarCamModule
136
+ this.sdkClientPtr = VStarCamModule.getSdkClientPtr((int) ptr);
137
+ Log.d(TAG, "SDK client pointer: " + sdkClientPtr);
138
+
139
+ if (sdkClientPtr != 0) {
99
140
  statusView.setText("Ready to stream");
141
+ } else {
142
+ statusView.setText("Waiting for connection...");
100
143
  }
101
144
  }
102
-
145
+
103
146
  /**
104
- * Set video resolution (1=high, 2=general, 4=low, 100=superHD)
147
+ * Set video resolution.
148
+ * 1=high, 2=general, 4=low, 100=superHD
105
149
  */
106
150
  public void setResolution(int res) {
107
151
  this.resolution = res;
108
152
  Log.d(TAG, "Resolution set: " + res);
109
153
  }
110
-
154
+
111
155
  /**
112
- * Start video streaming
156
+ * Start video streaming.
113
157
  */
114
158
  public void startStream() {
115
- if (clientPtr == 0) {
116
- Log.e(TAG, "Cannot start stream: no client pointer");
117
- statusView.setText("No connection");
159
+ if (sdkClientPtr == 0) {
160
+ // Try to get SDK pointer again in case it was set after setClientPtr
161
+ this.sdkClientPtr = VStarCamModule.getSdkClientPtr((int) clientPtr);
162
+ if (sdkClientPtr == 0) {
163
+ Log.e(TAG, "Cannot start: no SDK client pointer");
164
+ statusView.setText("Not connected");
165
+ return;
166
+ }
167
+ }
168
+
169
+ if (surface == null) {
170
+ Log.e(TAG, "Cannot start: no surface available");
171
+ statusView.setText("No surface");
118
172
  return;
119
173
  }
120
-
121
- if (!playerLibLoaded) {
122
- Log.e(TAG, "Cannot start stream: player library not loaded");
123
- statusView.setText("Player not available");
174
+
175
+ if (appPlayerClass == null) {
176
+ Log.e(TAG, "Cannot start: player class not found");
177
+ statusView.setText("Player unavailable");
124
178
  return;
125
179
  }
126
-
127
- Log.d(TAG, "Starting video stream...");
180
+
128
181
  statusView.setText("Starting stream...");
129
-
130
- // The actual streaming is handled by sending CGI command
131
- // Video frames come through the native player SDK
132
- isStreaming = true;
133
-
134
- // Hide status once streaming
135
- statusView.setVisibility(GONE);
182
+
183
+ try {
184
+ // 1. Create player instance if needed
185
+ if (playerPtr == 0) {
186
+ Method createMethod = appPlayerClass.getMethod("create");
187
+ Object result = createMethod.invoke(null);
188
+ playerPtr = (Long) result;
189
+ Log.d(TAG, "Player created: " + playerPtr);
190
+ }
191
+
192
+ // 2. Set the video source (P2P client)
193
+ try {
194
+ Method setSourceMethod = appPlayerClass.getMethod(
195
+ "setSource", long.class, long.class);
196
+ setSourceMethod.invoke(null, playerPtr, sdkClientPtr);
197
+ Log.d(TAG, "Source set to client: " + sdkClientPtr);
198
+ } catch (NoSuchMethodException e) {
199
+ Log.w(TAG, "setSource method not found, trying alternative...");
200
+ // Try alternative method signatures if the main one doesn't exist
201
+ }
202
+
203
+ // 3. Set the render surface
204
+ try {
205
+ Method setSurfaceMethod = appPlayerClass.getMethod(
206
+ "setSurface", long.class, Surface.class);
207
+ setSurfaceMethod.invoke(null, playerPtr, surface);
208
+ Log.d(TAG, "Surface set");
209
+ } catch (NoSuchMethodException e) {
210
+ Log.w(TAG, "setSurface method not found, trying alternative...");
211
+ // Try with Object parameter
212
+ try {
213
+ Method setSurfaceMethod = appPlayerClass.getMethod(
214
+ "setSurface", long.class, Object.class);
215
+ setSurfaceMethod.invoke(null, playerPtr, surface);
216
+ Log.d(TAG, "Surface set (via Object)");
217
+ } catch (NoSuchMethodException e2) {
218
+ Log.e(TAG, "No setSurface method found");
219
+ }
220
+ }
221
+
222
+ // 4. Start playback
223
+ try {
224
+ Method startMethod = appPlayerClass.getMethod("start", long.class);
225
+ startMethod.invoke(null, playerPtr);
226
+ Log.d(TAG, "Playback started");
227
+ } catch (NoSuchMethodException e) {
228
+ // Try play() instead of start()
229
+ try {
230
+ Method playMethod = appPlayerClass.getMethod("play", long.class);
231
+ playMethod.invoke(null, playerPtr);
232
+ Log.d(TAG, "Playback started (via play)");
233
+ } catch (NoSuchMethodException e2) {
234
+ Log.e(TAG, "No start/play method found");
235
+ }
236
+ }
237
+
238
+ isStreaming = true;
239
+ statusView.setVisibility(GONE);
240
+
241
+ } catch (Exception e) {
242
+ Log.e(TAG, "Failed to start stream", e);
243
+ statusView.setText("Start failed: " + e.getMessage());
244
+ }
136
245
  }
137
-
246
+
138
247
  /**
139
- * Stop video streaming
248
+ * Stop video streaming.
140
249
  */
141
250
  public void stopStream() {
142
- if (!isStreaming) return;
143
-
144
- Log.d(TAG, "Stopping video stream...");
145
- isStreaming = false;
146
- statusView.setVisibility(VISIBLE);
147
- statusView.setText("Stream stopped");
251
+ if (!isStreaming || playerPtr == 0) return;
252
+
253
+ Log.d(TAG, "Stopping stream...");
254
+
255
+ try {
256
+ try {
257
+ Method stopMethod = appPlayerClass.getMethod("stop", long.class);
258
+ stopMethod.invoke(null, playerPtr);
259
+ Log.d(TAG, "Playback stopped");
260
+ } catch (NoSuchMethodException e) {
261
+ // Try pause() instead
262
+ try {
263
+ Method pauseMethod = appPlayerClass.getMethod("pause", long.class);
264
+ pauseMethod.invoke(null, playerPtr);
265
+ Log.d(TAG, "Playback paused");
266
+ } catch (NoSuchMethodException e2) {
267
+ Log.w(TAG, "No stop/pause method found");
268
+ }
269
+ }
270
+
271
+ isStreaming = false;
272
+ statusView.setVisibility(VISIBLE);
273
+ statusView.setText("Stream stopped");
274
+
275
+ } catch (Exception e) {
276
+ Log.e(TAG, "Failed to stop stream", e);
277
+ }
148
278
  }
149
-
150
- // TextureView.SurfaceTextureListener implementation
151
-
279
+
280
+ private void releasePlayer() {
281
+ if (playerPtr == 0) return;
282
+
283
+ try {
284
+ stopStream();
285
+
286
+ try {
287
+ Method releaseMethod = appPlayerClass.getMethod("release", long.class);
288
+ releaseMethod.invoke(null, playerPtr);
289
+ Log.d(TAG, "Player released");
290
+ } catch (NoSuchMethodException e) {
291
+ // Try destroy() instead
292
+ try {
293
+ Method destroyMethod = appPlayerClass.getMethod("destroy", long.class);
294
+ destroyMethod.invoke(null, playerPtr);
295
+ Log.d(TAG, "Player destroyed");
296
+ } catch (NoSuchMethodException e2) {
297
+ Log.w(TAG, "No release/destroy method found");
298
+ }
299
+ }
300
+
301
+ playerPtr = 0;
302
+
303
+ } catch (Exception e) {
304
+ Log.e(TAG, "Failed to release player", e);
305
+ }
306
+ }
307
+
308
+ // TextureView.SurfaceTextureListener
309
+
152
310
  @Override
153
- public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
311
+ public void onSurfaceTextureAvailable(
312
+ SurfaceTexture surfaceTexture, int width, int height) {
154
313
  Log.d(TAG, "Surface available: " + width + "x" + height);
155
- // Initialize native player with surface when available
156
- if (playerLibLoaded && clientPtr != 0) {
157
- initializePlayer(surface, width, height);
314
+ this.surface = new Surface(surfaceTexture);
315
+
316
+ // If already supposed to be streaming, try to update surface
317
+ if (isStreaming && playerPtr != 0 && appPlayerClass != null) {
318
+ try {
319
+ Method setSurfaceMethod = appPlayerClass.getMethod(
320
+ "setSurface", long.class, Surface.class);
321
+ setSurfaceMethod.invoke(null, playerPtr, surface);
322
+ Log.d(TAG, "Surface updated on existing player");
323
+ } catch (Exception e) {
324
+ Log.e(TAG, "Failed to update surface", e);
325
+ }
158
326
  }
159
327
  }
160
-
328
+
161
329
  @Override
162
- public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
330
+ public void onSurfaceTextureSizeChanged(
331
+ SurfaceTexture surface, int width, int height) {
163
332
  Log.d(TAG, "Surface size changed: " + width + "x" + height);
164
333
  }
165
-
334
+
166
335
  @Override
167
336
  public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
168
337
  Log.d(TAG, "Surface destroyed");
169
338
  stopStream();
170
- releasePlayer();
339
+ if (this.surface != null) {
340
+ this.surface.release();
341
+ this.surface = null;
342
+ }
171
343
  return true;
172
344
  }
173
-
345
+
174
346
  @Override
175
347
  public void onSurfaceTextureUpdated(SurfaceTexture surface) {
176
- // Called when texture is updated with new frame
177
- }
178
-
179
- private void initializePlayer(SurfaceTexture surface, int width, int height) {
180
- // Native player initialization will be implemented based on SDK API
181
- Log.d(TAG, "Initializing player for surface");
348
+ // Frame rendered - nothing to do
182
349
  }
183
-
184
- private void releasePlayer() {
185
- if (playerPtr != 0) {
186
- // Release native player resources
187
- playerPtr = 0;
188
- }
189
- }
190
-
350
+
191
351
  @Override
192
352
  protected void onDetachedFromWindow() {
193
353
  super.onDetachedFromWindow();
194
- stopStream();
195
354
  releasePlayer();
196
355
  }
197
356
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bits-innovate/react-native-vstarcam",
3
- "version": "1.0.18",
3
+ "version": "1.0.20",
4
4
  "description": "React Native bridge for VStarCam P2P SDK",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",